Get ability by string reference

Cheo

Active member
Hello, allow me to share a convenient addition when dealing with multiple Abilities of the same type : we have the option to add an index int to GetAbility method, but that requires knowing where exactly in the array the ability is, and may require an update if the order is changed. Instead, it is more pratical to make these changes and get an ability by a string reference !
First, we need to add this string to Ability :

C#:
         [SerializeField] protected string m_AbilityName;
        public string AbilityName { get { return m_AbilityName; } set { m_AbilityName = value; } }

It should by default be added beneath Ability Index Parameter.
Next, let's add these to UltimateCharacterLocomotion :


C#:
        public T GetAbility<T>(string abilityName) where T : Ability
        {
            return GetAbility(typeof(T), abilityName) as T;
        }


C#:
        public Ability GetAbility(System.Type type, string abilityName)
        {
            var allAbilities = (typeof(ItemAbility).IsAssignableFrom(type) ? m_ItemAbilities : m_Abilities);
            if (allAbilities != null)
            {
                for (int i = 0; i < allAbilities.Length; ++i)
                {
                    if (type.IsInstanceOfType(allAbilities[i]) && (abilityName != "" || abilityName == allAbilities[i].AbilityName))
                    {
                        return allAbilities[i];
                    }
                }
            }
            return null;
        }


And you now have what you need to call an ability by name ! For example, let's say you have multiple instances of Speed Change in your ability array - a slow one and a fast one let's say - just write Fast and Slow for each, and you'll be able to get the fast one specifically for example by using "GetAbility<SpeedChange>("Fast");".

Another idea that came to my mind was to use an ID but these are apparently associated with an object, it should be possible as well but perhaps a bit less straightforward to write ?
In any case let me know what you think !
 
I am struggling to see why you would want two of the same ability like this, especially concurrent ones. With the example you give, you could have one speed ability that switches between fast and slow states using the state system and presets.
 
I'm currently using a combination of Speed Changes for manually slowing down the player while he is inside some specific zones but still allowing him to accelerate using an input - the speed modifications can stack this way. But yeah it might be possible to reach the same effect with states, I should try that. In any case, I maintain that using an int to get an ability by index is not convenient compared to using a string, so I thought this would be a nice addition for devs who for some reason or another have multiple instances of the same ability. One specific scenario being using an ability like Crawl which inherits from Height Change - if you use GetAbility<HeightChange> hoping to get the default crouch ability you actually take the risk of getting the Crawl abilty instead !
 
Some correction...

if (type.IsInstanceOfType(allAbilities) && (abilityName == allAbilities.AbilityName))
 
Top