2

Tinkering in Unity, I have a part of my GUI that will render information (e.g. 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 (e.g. 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 (i.e. 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.

Grant Winney
  • 65,241
  • 13
  • 115
  • 165
mag
  • 23
  • 2

2 Answers2

2

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();
        }
    }
}
metacubed
  • 7,031
  • 6
  • 36
  • 65
  • Thanks for the suggestion - interfaces in C# are new to me. I was going to ask if the interface bit is inheritable from a separate C# script in Unity, but after some testing it appears they are. – mag Aug 09 '14 at 05:21
1

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.

Austin Mullins
  • 7,307
  • 2
  • 33
  • 48
  • Thanks for the information. Would that I could set more than one answer as accepted. – mag Aug 09 '14 at 05:22