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 also invoke the delegate directly (SLOW - not recommended) if((bool)mi.Invoke(skillsObject, parameter1, parameter2, parameter3)) //Any number of parameters { } CreateDelegateInvoke
You would be forced to define a function with the name of the skill and optionally have an function called IsAbleToXXXX (where XXXX is the skill). If you didn't define the latter, it would presume it was always able to work.
There are lots of cool ways to go further using Attributes so you could just write things like: [Skill] void Cast(GameObject target) { ... } [Skill] void Smash(GameObject target) { } And have the system automatically find all of these to avoid you needing to add them to the list of strings - just attach behaviours to a game object and it would get additional skills automatically.
Thanks for everything, I'm going to give this a try when I'm next able to edit my project. for var mi = skillsObject.GetType().GetMethod(functionName) as MethodInfo;, can I use var in C#? or must I declare it as a MethodInfo at the beginning? also, does using System.Linq enable the use of Action() and Func()? Thank you for offering to provide notes, though I admit my code is quite simplistic and I have to learn a bit about the methods you've provided me with first before venturing any deeper. Thanks for your help again!
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.)
Why not use SendMessage()? Since you won't be calling it every single frame, there shouldn't be any concern about efficiency. http://docs.unity3d.com/Documentation/ScriptReference/GameObject.SendMessage.html
– TonyLi