Calling a string equivalent method

Asked

Viewed 887 times

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 enter the commented code:

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

Here I would execute the method, but I don’t know how to do.

  • What is this Enemy.transform.name?

  • Enemy.transform.name returns a string with the name of the game object.

  • Ta with all the face that should have an interface in place of this concrete implementation of object.

2 answers

3


I advise doing this with delegated methods and not using string to set the method call. It looks like you are using an event to trigger events, only the wrong way.

But I’ll give you an answer because I 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);

Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.

An optimization would be:

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

I don’t know if this totally solves what you need but it’s what came out without a bigger context.

Obviously if the string contain a name that cannot generate a valid method, will give exception.

  • How would it be with delegated methods? Could I give an example? Thank you.

  • Get out of the question and you could only see a larger context of the application. But you might not be able to change the application to solve this.

  • So wouldn’t it be good practice to use strings? I know it’s out of the question, but it was just an idea and I ended up asking how to do it without knowing if I should.

  • 1

    For this, no, as far as possible.

  • The idea is cool, but I don’t think it’s a good choice for AP (and I don’t even know if it would give other problems in Unity, since she does a control of the invocations because of framerate). And another thing, (although he doesn’t make it clear) he doesn’t want to perform this method on this (which is the class AnimationManager), and yes in the instance Enemy (an instance of a class that he does not mention, but which is manipulated through the basic class GameObject).

  • 1

    I answered what I could to answer with the information I had and on top of what he asked. I did not do this for sure. I saw that the whole design is bad. This method does not make much sense.

  • I realized that it was a bad idea and I’m using another solution. However, as your answer solves the question, I marked it as right. Thank you for your time!

  • I explained what I want here: http://answall.com/questions/83690/howto organize.

Show 3 more comments

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 disadvantages in performance (because it needs to reflect in a sense similar to what @Maniero has described to you), but it works for what you want. So you can do it this way:

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

  2. Execute the method as follows: Enemy.GetComponent(Enemy.transform.name).Animation();. Note that this can cause errors while running your game if the script with the name Enemy.transform.name not exist!

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

  • 1

    @Filipemoraes Surely this is the best way is the one that consumes the least when running. Letting the enemy’s Prefab(and class) take care of the animations is what is most consistent with how to develop in Unity. I recommend that instead of calling a method, use the functions of Unity itself and determine parameters for each animation you want, this way you can determine each of them by changing a boleano or by firing a Trigger. https://www.youtube.com/watch?v=fotMn6x7aoU

  • @Nils and Luiz, for each enemy I have the normal animation generated through the sprites (Unity frame by frame) and then I have another type of animation that is the displacement of the enemy, for example, move up and down, this I do with code because of boxcollider2d, to be able to move it as well, but this action of going up and down is not enemy specific and wanted to reuse it in others, so I centralized it in a single file. I realize this was a bad idea. :)

  • 1

    I will create a more specific question and demonstrate what I really want and include images, it is easier to understand! Thank you for your time.

  • I explained what I want here: http://answall.com/questions/83690/howto organize.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.