Is it possible to create a List filled with methods?

Hi everyone, I have created a mob named Stan. Stan derives from the class DefaultCharacter, which looks a little like the example below.

public Class DefaultCharacter:MonoBehaviour{
    public List<string> Abilities = new List<string>();
}

In the inspector, you can set his abilities by filling them with the names of abilities I’ve kept in another class named Skills. The abilities I’ve kept in skills are all functions, that you can call in game (think final fantasy’s abilites). I set them as functions rather than creating a class each skill can derive from as the skills will be so different from one another that it would be pointless to have them all come from one place.

This has let to certain complications, however, as I would like to be able to set Stan’s four abilities in the inspector, and then have my AI be able to run them according to their index, for example, if it was the enemies’ turn, I would (for example) have it choose a number from one to four, (one for each ability) and then use the skill at that index in the list.

The problem is I can’t convert the string’s name to a function call. Is there a way to create a list of functions? I’ve used List but obviously that doesn’t work.

You can use your strings to “look up” functions in your Skills class. Something like Skills.GetMethod(“someFunctionName”).

Your reflection approach would be:

  var mi = skillsObject.GetType().GetMethod(functionName) as MethodInfo;

Now you need to create a delegate for that which uses some standard signature. If it’s a void UseAbility() type method then you would do:

   Action useSkill = (Action)mi.CreateDelegate(typeof(Action), skillsObject);

And call it using:

  useSkill();

You’d want to cache that or it will be just as slow as SendMessage

If you want it to return a value and take an object your would define your delegate signature like this:

    Func<GameObject, bool> canIUseSkillOnThisObject = mi.CreateDelegate(typeof(Func<GameObject, bool>), skillsObject) as Func<GameObject, bool>;

And use it like this:

   if(canIUseSkillOnThisObject(someObject))
   {
          //Do something
   }

Why not just edit the Skills class to have something like this:

public void PerformSkill(string skillName){
    switch(skillName.ToLower()) {
        case "super punch":
            SuperPunch();
            break;
        case "upper cut":
            UpperCut();
            break;
        default:
            Debug.Log(string.Format("Urp. {0} doesn't exist.", skillName));
    }
}

There are more admittedly “advanced” ways to do this, but this is easy, maps well and executes fast. Also doesn’t require reflection or keeping delegate dictionaries (which isn’t bad for the program but wrapping your head around them can be something like slamming a brick through the nearest available hole and hoping all goes well.)