Call a method equivalent to a string

5

Consider the following class:

public class AnimationManager : MonoBehaviour {
    public GameObject[] Enemies;

    void OnTriggerEnter2D (Collider2D o) {
        if (o.tag == "Player")
            foreach(GameObject Enemy in Enemies)
                //Eval(Enemy.transform.name + "Animation();");
    }

    void MacacoAnimation(){
        //...
    }
}

What I want is when the object collides with the player, the script executes a method equivalent to the name of the object concatenated with the string "Animation".

See where to insert the commented code:

Eval(Enemy.transform.name + "Animation();");

Here I would execute the method, but I do not know how to do it.

    
asked by anonymous 31.08.2015 / 21:30

2 answers

3

I recommend doing this with delegate methods and not using string to define the method call. It looks like you're using an event to trigger events, just the wrong way.

But I'll give you an answer because you might not be able to do it this way:

var nomeMetodo = Enemy.transform.name + "Animation";
var Metodo = this.GetType().GetMethod(nomeMetodo);
Metodo.Invoke(this, null);

See working on dotNetFiddle .

An optimization would be:

var Metodo = typeof(AnimationManager).GetMethod(nomeMetodo);

I do not know if this completely solves what you need but it is what you gave without a larger context.

Obviously, if the string contains a name that can not generate a valid method, it will give exception.

    
31.08.2015 / 22:07
3

In Unity, the way to execute a method from another script is as follows:

Objeto.GetComponent<NomeDaClasseDoScript>().NomeDoMetodo();

Or

Objeto.GetComponent("NomeDaClasseDoScript").NomeDoMetodo();

The second form has performance disadvantages (because you need to do the reflection in a sense similar to what @bigown has described to you), but it works for what you want. So, you can do it as follows:

  • Create different scripts instead of different methods in a single script. Each script will have the name you are defining (in transform.name ). And all of them will have the same method animation (of course, each doing what it has to do differently).

  • Run the method as follows: Enemy.GetComponent(Enemy.transform.name).Animation(); . Note that this may generate errors during the execution of your game if the script with the name Enemy.transform.name does not exist!

  • That said, I would like to mention that I understood what you want to do but did not understand exactly why you want to do this. You are centralizing the control of the animation in a class called AnimationManager , when you could have left it to the class of each enemy (the enemy can also detect the collision and alone execute its animation). From the point of view of object orientation this is a very bad choice, as it creates an unnecessary coupling and will certainly hinder its future maintenance.

        
    01.09.2015 / 02:46