Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by Captain_Dando · Apr 18, 2013 at 02:56 PM · listfunctionsmethods

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.

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image TonyLi · Apr 18, 2013 at 03:16 PM 3
Share

Why not use Send$$anonymous$$essage()? 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.Send$$anonymous$$essage.html

3 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by whydoidoit · Apr 18, 2013 at 04:00 PM

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
    }
Comment
Add comment · Show 21 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image whydoidoit · Apr 18, 2013 at 04:17 PM 1
Share

Let's presume that you have the list of strings and you want to have two functions for accessing the skill - perform it(with a target) and check if you can perform it.

    using System.Linq;

    ...


    public class SkillFunctions
    {
          public string name;
          public Action<GameObject> use;
          public Func<GameObject, bool> canUse;
   }

   public $$anonymous$$onoBehaviour targetBehaviourForFunctions;


   public Dictionary<string, SkillFunctions> skillLookup;
   public List<SkillFunctions> skills;

   public List<string> yourListOfNames;

   void Awake()
   {
        if(!targetBehaviourForFunctions) targetBehaviourForFunctions = this;
        skillLookup = yourListOfNames.Select(n=>{
                var miUse = targetBehaviourForFunctions.GetType().Get$$anonymous$$ethod(n, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                var miCanUse = targetBehaviourForFunctions.GetType().Get$$anonymous$$ethod("IsAbleTo" + n, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                 return new SkillFunctions { name = n, use = mi.CreateDelegate(typeof(Actions<GameObject>), targetBehaviourForFunctions) as Action<GameObject>,
                        canUse = miCanUse != null ? miCanUse.CreateDelegate(typeof(Func<GameObject, bool>), targetBehaviourForFunctions) as Func<GameObject, bool> : (o)=>true
                    };
             }).ToDictionary(c=>c.name);
         skills = skillLookup.Values.ToList();
   }

Now you can call that liek this:

   someObject.GetComponent<WhateverThisScriptIsCalled>().skillLookup[someSkill].use();
avatar image whydoidoit · Apr 18, 2013 at 04:18 PM 1
Share

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.

avatar image whydoidoit · Apr 19, 2013 at 10:30 AM 1
Share

It would just allow you to specify the $$anonymous$$onoBehaviour (any script you wrote) as the thing which has the functions on it.

If you are missing $$anonymous$$ethodInfo (using $$anonymous$$onoDevelop right click, and use the resolve menu) add a

   using System.Runtime.Reflection;
avatar image whydoidoit · Apr 19, 2013 at 11:23 AM 1
Share

Oh I'm sorry - just working on another .NET project and that's a 4.5 call :S

You care after

        Delegate.CreateDelegate(typeof(Action<GameObject>), skillsObject, methodInfo);
avatar image whydoidoit · Apr 19, 2013 at 11:35 AM 1
Share

So being able to create a delegate directly from a $$anonymous$$ethodInfo is a 4.5 function. In Unity's .NET you have to use Delegate.CreateDelegate(typeof(Action), objectInstance, methodInfoYouFound) as Action;

Show more comments
avatar image
1

Answer by flaviusxvii · Apr 18, 2013 at 03:14 PM

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

http://stackoverflow.com/questions/540066/calling-a-function-from-a-string-in-c-sharp

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Captain_Dando · Apr 18, 2013 at 03:18 PM 0
Share

Thanks, I didn't know about this method, but now I do

avatar image Captain_Dando · Apr 18, 2013 at 03:21 PM 0
Share

will this work for ienumerators?

avatar image Captain_Dando · Apr 18, 2013 at 03:24 PM 0
Share

hmm, I get the error " Type Skills' does not contain a definition for Get$$anonymous$$ethod' and no extension method Get$$anonymous$$ethod' of type Skills' could be found"

avatar image
1

Answer by Dracorat · Apr 18, 2013 at 09:02 PM

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.)

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

15 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

A node in a childnode? 1 Answer

Optional parameter, editor raises error "Unexpected symbol `=' " 0 Answers

Calling arbritary functions with arguments in Unity 2 Answers

Get Object, Trigger Attached Method,Trigger method on collider script 1 Answer

How can you list all classes inside a namespace (such as UnityEngine) and every message method that class has? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges