简体   繁体   中英

Calling a method that is unspecified at compile time

Tinkering in Unity, I have a part of my GUI that will render information (eg enemy stats) from one of several different class types representing different things in the game. All of the different classes have a method for creating an information object that contains the desired information (eg enemyInfoObject), which have a DrawInfo() method that draws the info depending on the gameObject.

In my information-rendering script I would like to be able to assign any one of the different information objects to a single variable (ie the currently selected enemy, NPC, etc.) and be able to call the DrawInfo() method. Is there a clean, simple, and/or better way to do this?

I can elaborate if needed.

This is a well-known design pattern called the "Strategy Pattern" . It extends the idea of "programming to an interface".

The strategy pattern is intended to provide a means to define a family of algorithms, encapsulate each one as an object, and make them interchangeable. The strategy pattern lets the algorithms vary independently from clients that use them.

First, define an interface containing DrawInfo ,say ISprite . All your sprites will be classes that implement this interface. Now the game can store a reference to the selected ISprite and call the method on it.

For example:

public interface ISprite
{
    void Draw();
}

public class BossMonster : ISprite
{
    public override void Draw()
    {
        // Draw scary stuff
    }
}

public class NPC : ISprite
{
    public override void Draw()
    {
        // Draw stuff
    }
}

public class Game
{
    private ISprite currentSprite = ...
    private List<ISprite> otherSprites = ...

    public void Render()
    {
        currentSprite.Draw();

        foreach (ISprite sprite in otherSprites)
        {
            sprite.Draw();
        }
    }
}

The best way I can think of is to make all of the objects in your game that you'd like to call DrawInfo() on implement an interface like IDrawableInfo :

IDrawableInfo.cs

public interface IDrawableInfo
{
    void DrawInfo();
}

EnemyInfoObject.cs

public class EnemyInfoObject : IDrawableInfo
{
    public void DrawInfo()
    {
        // Do drawing stuff here
    }
}

YourScript.cs

if(objectIdLikeToDrawInfoFor is IDrawableInfo)
{
    objectIdLikeToDrawInfoFor.DrawInfo();
}

You can avoid runtime errors by wrapping your DrawInfo() calls in an if statement like this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM