Simple FSM Framework Part 1: The Making

I remember a project which I lead that heavily used Playmaker for its systems. This was the time when Playmaker was still in its first couple of months and I got pretty excited when I tried it. For those of you who are not familiar, Playmaker is a Unity asset that helps you create FSM graphs and add functionality without code. It got so popular that it has become the leading “visual scripting” asset of Unity.

Short version of the story: that project became a disgusting pile of mess. The messiness of FSM wiring is way worse than spaghetti code. At least code could be refactored. It was so bad that I vow not to primarily use visual scripting to run the complex systems of a game ever again.

A part of Defender unit FSM. Looks like spaghetti, yum!
This is not part of that project but you get the idea.

However, I didn’t hate Playmaker. It showed a good data model on how a finite state machine works that can be applied to games. So I made my own bare bones FSM framework based from it so that I can still make FSM graphs through code. Used wisely, FSMs can be a great way to organize simple behavior. I’ve been using this framework ever since. I’m still using Playmaker but only as a visual reference. All of my FSMs are now in code.

I’m going to show you how I did it in this post. There will be no github repository for this because honestly, I’m too lazy to extract it from my library. My intent is to have you read code so you can make your own FSM framework and hopefully improve it on your own.

High Level Design

My design is based on Playmaker’s model. These are the main concepts:

  • FsmAction – Represents an action that is executed/executing on a single state
  • Events – It is that thing that causes state change. This can be easily represented as strings.
  • FsmState – Represents a state in the FSM. It has a collection of actions and transitions.
  • Transitions – Represents the link to another state. This can be easily represented as a pair of event (string) and FsmState.
  • Fsm – Contains a certain set of FsmState instances that comprises a single FSM graph. Provides methods to send events and thus changes the current state.

FsmAction Code

An FsmAction is just a base class for concrete actions to implement. The way the framework is used is that there will be a collection of predefined action classes that can be used such as Move, Rotate, TimedWait, etc. At the same time, custom actions could also be implemented. Obvious examples are actions that are specific to a game.

public abstract class FsmAction {

    private readonly FsmState owner;

    public FsmAction(FsmState owner) {
        this.owner = owner;
    }

    public FsmState GetOwner() {
        return owner;
    }

    public virtual void OnEnter() {
        // may or may not be implemented by deriving class
    }

    public virtual void OnUpdate() {
        // may or may not be implemented by deriving class
    }

    public virtual void OnExit() {
        // may or may not be implemented by deriving class
    }

}

This is pretty straightforward. The most important here are the three methods. OnEnter() is invoked when a state has been entered. OnUpdate() is called repeatedly every frame while on a certain state. OnExit() is invoked when the current state will be changed to a new one. The member FsmState is needed so that actions can send events to it (change the current state).

Why is it not an interface? The intent is that actions should be small modular classes deriving from FsmAction. An existing big class, say some kind of big manager, can’t just implement an interface and use that big class as an FsmAction. This also prevents usage of MonoBehaviour classes as FsmAction instances.

FsmState Code

FsmState is just a collection of actions and transitions to other states. It provides the methods appropriate to setup states.

public class FsmState {

    private readonly string name;
    private readonly Fsm owner;

    // Transitions are just pairs of event and FsmState
    // Events are just strings
    private readonly Dictionary<string, FsmState> transitionMap = new Dictionary<string, FsmState>();

    private readonly List<FsmAction> actionList = new List<FsmAction>();

    public FsmState(string name, Fsm owner) {
        this.name = name;
        this.owner = owner;
    }

    public string Name {
        get {
            return name;
        }
    }

    public void AddTransition(string eventId, FsmState destinationState) {
        // can't have two transitions for the same event
        Assertion.Assert(!transitionMap.ContainsKey(eventId), string.Format("The state {0} already contains a transition for event {1}.", this.name, eventId));
        transitionMap[eventId] = destinationState;
    }

    public FsmState GetTransition(string eventId) {
        // May return null if there's no such transition
        return transitionMap.Find(eventId);
    }

    public void AddAction(FsmAction action) {
        Assertion.Assert(!actionList.Contains(action), "The state already contains the specified action.");
        Assertion.Assert(action.GetOwner() == this, "The owner of the action should be this state.");
        actionList.Add(action);
    }

    public IEnumerable<FsmAction> GetActions() {
        return actionList;
    }

    public void SendEvent(string eventId) {
        // Just delegate to the owner Fsm
        this.owner.SendEvent(eventId);
    }

}

Fsm Code

Fsm is like the central hub of the framework. You make an instance of this class then it provides methods to create FsmState instances. Those FsmState instances can then be setup to your liking (actions and transitions).

public class Fsm {

    private readonly string name;

    private FsmState currentState;

    // Collection of all states using the state name as key
    private readonly Dictionary<string, FsmState> stateMap = new Dictionary<string, FsmState>();

    public Fsm(string name) {
        this.name = name;
        currentState = null;
    }

    public string Name {
        get {
            return name;
        }
    }

    public FsmState AddState(string name) {
        // state names should be unique
        Assertion.Assert(!stateMap.ContainsKey(name), "The FSM already contains a state with the specified name: " + name);

        FsmState newState = new FsmState(name, this);
        stateMap[name] = newState;
        return newState;
    }

    private delegate void StateActionProcessor(FsmAction action);

    private void ProcessStateActions(FsmState state, StateActionProcessor actionProcessor) {
        FsmState stateOnInvoke = this.currentState;

        IEnumerable<FsmAction> actions = state.GetActions();
        foreach(FsmAction action in actions) {
            actionProcessor(action);

            if(this.currentState != stateOnInvoke) {
                // this means that the action processing caused a state change
                // we don't continue with the rest of the actions
                break;
            }
        }
    }

    public void Start(string stateName) {
        FsmState state = stateMap.Find(stateName);
        Assertion.AssertNotNull(state);
        ChangeToState(state);
    }

    private void ChangeToState(FsmState state) {
        if(this.currentState != null) {
            // if there's an active current state, we exit that first
            ExitState(this.currentState);
        }

        this.currentState = state;
        EnterState(this.currentState);
    }

    private void EnterState(FsmState state) {
        ProcessStateActions(state, delegate(FsmAction action) {
            action.OnEnter();
        });
    }

    private void ExitState(FsmState state) {
        FsmState currentStateOnInvoke = this.currentState;

        ProcessStateActions(state, delegate(FsmAction action) {
            action.OnExit();
            if(this.currentState != currentStateOnInvoke) {
                // this means that the action's OnExit() causes the FSM to change state
                // note that states should not change state on exit
	        throw new Exception("State cannot be changed on exit of the specified state.");
            }
        });
    }

    public void Update() {
        if(this.currentState == null) {
            return;
        }

        ProcessStateActions(this.currentState, delegate(FsmAction action) {
            action.OnUpdate();
        });
    }

    public FsmState GetCurrentState() {
        return this.currentState;
    }

    public void SendEvent(string eventId) {
        if(currentState == null) {
            Debug.LogWarning(string.Format("Fsm {0} does not have a current state. Check if it was started.", this.name));
            return;
        }

        FsmState transitionState = this.currentState.GetTransition(eventId);
        if(transitionState == null) {
            #if UNITY_EDITOR
            // log only in Unity Editor since it lags the game even if done in build
            Debug.LogWarning(string.Format("The current state {0} has no transtion for event {1}.", this.currentState.GetName(), eventId));
            #endif
        } else {
            ChangeToState(transitionState);
        }
    }

}

The only thing special here is ProcessStateActions(). It is the common algorithm for traversing state actions. I made it this way so I don’t have to repeat this pattern whenever I traverse state actions. As you can see here, it is invoked in EnterState(), ExitState(), and Update().

This is pretty much it. The FSM framework is done.

How to use?

Let’s just say we’re making a runner game and we are developing the main runner character. Let’s say the following would be its FSM behavior graph:

RunnerFsm

This is self explanatory. That starting state would be the character running. When Jump event triggers, like the player presses the jump button, it goes to jumping state. From jumping, if it hits the ground, it goes back to running state. If it hits an obstacle, then it dies.

Their are many ways to use the framework. The most common one is to use it in a MonoBehaviour. This is how it is then set up:

public class RunnerCharacter : MonoBehaviour {

    [SerializeField]
    private float moveSpeed;

    private Fsm fsm = new Fsm("RunnerCharacter");

    private void Awake() {
        PrepareFsm();
    }

    // Only keeping constant of the starting state since it will be needed for starting the FSM
    private const string RUNNING = "Running";

    // Events
    private const string JUMP = "Jump";
    private const string HIT_GROUND = "HitGround";
    private const string HIT_OBSTACLE = "HitObstacle";

    private void PrepareFsm() {
        // States
        FsmState running = fsm.AddState(RUNNING);
        FsmState jumping = fsm.AddState("Jumping");
        FsmState die = fsm.AddState("Die");

        // Actions

        // Running
        {
            MoveConstantly move = new MoveConstantly(running);
            move.Init(this.transform, this.moveSpeed);
            running.AddAction(move);

            TriggerAnimator animationTrigger = new TriggerAnimator(running, "Run");
            running.AddAction(animationTrigger);
        }

        // Jumping
        {
            JumpAction jump = new JumpAction(jumping);
            jumping.AddAction(jump);

            TriggerAnimator animationTrigger = new TriggerAnimator(running, "Jump");
            running.AddAction(animationTrigger);
        }

        // Die
        {
            TriggerAnimator animationTrigger = new TriggerAnimator(running, "Die");
            running.AddAction(animationTrigger);
        }

        // Transitions
        running.AddTransition(JUMP, jumping);
        running.AddTransition(HIT_OBSTACLE, die);

        jumping.AddTransition(HIT_GROUND, running);

        // Auto start the FSM (sometimes it may be started else where)
        // Start() can be invoked anywhere like respawning a character
        this.fsm.Start(RUNNING);
    }

    private void Update() {
        // Process input
        if(Input.GetKeyDown(KeyCode.Space)) {
            this.fsm.SendEvent(JUMP);
        }

        // Don't forget to update
        this.fsm.Update();
    }

    private void OnCollisionEnter(Collision collision) {
        if(...) {
            // Collided with ground
            this.fsm.SendEvent(HIT_GROUND);
        }

        if(...) {
            // Collided with obstacle
            this.fsm.SendEvent(HIT_OBSTACLE);
        }
    }

}

I usually make a method for preparing the FSM. I usually name it PrepareFsm() and invoked on Awake(). In PrepareFsm(), I perform 3 preparations which are the states, actions, and transitions. I make the states first because those instances are needed when adding transitions. The classes MoveConstantly, JumpAction, and TriggerAnimator are defined FsmAction classes.

Events are natural candidates to become constants. They can be made as public if you want to expose the sending of events from other parts of the program. However, I don’t recommend that.

Every time you want to change the state, you just have to call Fsm.SendEvent() as can be seen here in Update() and OnCollisionEnter().

A common use case is to determine what the current state is. This can be done by caching the added state in a member variable instead of a local one. The cached state can then be compared with the state returned with Fsm.GetCurrentState().

private FsmState running;

private void PrepareFsm() {
    // States
    this.running = fsm.AddState(RUNNING); // Cache in member variable
    FsmState jumping = fsm.AddState("Jumping");
    FsmState die = fsm.AddState("Die");

    ...
}

private void Update() {
    // Process input
    if (Input.GetKeyDown(KeyCode.Space)) {
        if (this.fsm.GetCurrentState() == this.running) {
            // Jump only when on running state
            this.fsm.SendEvent(JUMP);
        }
    }

    this.fsm.Update();
}

This looks more tedious than Playmaker.

It is but it’s more useful for me. The reason I made the framework is so that I don’t have to use Playmaker if I ever do need FSMs. It forces me to ground my work using code. I’m afraid that if I start using Playmaker, it will creep out of control and will eventually become unmanageable. With FSMs done in code, I can apply a lot of tricks to make them manageable. Or if the FSM itself is messy, I could opt to refactor the whole thing without dealing with a Playmaker graph.

Some Utility Code

Every now and then, I’d like to share some of my small utility classes that I’ve made a long time ago but are still being used until now. The following are what I call some of my mini utilities. They can be used in your own Unity projects.

(Note that I’ve removed method description comments so that the code part looks more compact.)

Comment Component

A lot of times have come up where I have an object or prefab that contains a lot of components. Sometimes, I want to be able to note about the values I’ve entered for some component or state why the component is there. Sadly, Unity doesn’t have a feature where you can comment on components (let me know if you know one). However, it’s quite easy enough to roll your own “comment” component.

public class Comment : MonoBehaviour {

    [SerializeField]
    private string text;

    void Awake() {
        DestroyImmediate(this); // auto destroy to save memory
    }

    public string Text {
        get {
	    return text;
	}

        set {
	    this.text = value;
        }
    }

}

// This is the editor script. Place it under an Editor folder.
[CustomEditor(typeof(Comment))]
public class CommentEditor : Editor {

    private Comment targetComponent;

    void OnEnable() {
        this.targetComponent = (Comment)this.target;
    }

    public override void OnInspectorGUI() {
        if(targetComponent.Text == null) {
            // use an empty string so that it won't throw null pointer exception
            targetComponent.Text = "";
        }

        targetComponent.Text = GUILayout.TextArea(targetComponent.Text, GUILayout.Height(100), GUILayout.MinWidth(200));
    }

}

To use, just add the Comment component and type your comment text in the textbox.

CommentComponent

UI Image Sprite Animation

I tried to use the animation timeline for animating sprites in a UI Image. But it didn’t work or maybe I was using it wrong. I got impatient, so I turned to code.

public class ImageAnimation : MonoBehaviour {

    [SerializeField]
    private Image image;

    [SerializeField]
    private float framesPerSecond = 15;

    [SerializeField]
    private Sprite[] sprites; // The sequence of sprites comprising the animation

    private float polledTime;

    private int currentFrameIndex;

    private void Awake() {
        Assertion.AssertNotNull(this.image);
        Assertion.Assert(this.framesPerSecond > 0);

        this.polledTime = 0;

        // Reset
        this.currentFrameIndex = 0;
        SetSprite(this.currentFrameIndex);
    }

    private void Update() {
        this.polledTime += UnityEngine.Time.deltaTime;

        // We didn't cache this so we can see the effect of framesPerSecond on the fly like tweaking it in editor
        float timePerFrame = 1.0f / this.framesPerSecond;

        while(this.polledTime > timePerFrame) {
            this.polledTime -= timePerFrame;

            // Show next frame
            this.currentFrameIndex = (this.currentFrameIndex + 1) % this.sprites.Length;
            SetSprite(this.currentFrameIndex);
        }
    }

    private void SetSprite(int index) {
        this.image.sprite = this.sprites[index];
    }

}

This is very straightforward to use. Just specify an Image target, a frame rate, and the sequence of sprites to show. That’s it. It will play on loop. Nothing fancy. I’ve use this on the game over screen of Academia.

GameOver

SelectionSequence

Political Animals had a common UI where you select an item from a finite set of items using next and previous buttons. I’ve noticed that I’m repeating the same code spread across different UI screens. So I made a generic class for this.

public class SelectionSequence<T> {

    private readonly List<T> items = new List<T>();

    private int currentIndex = 0;

    public SelectionSequence(T[] array) {
        this.items.AddRange(array);
        Reset();
    }

    public void Reset() {
        this.currentIndex = 0;
    }

    public void MoveToNext() {
        this.currentIndex = (currentIndex + 1) % this.items.Count;
    }

    public void MoveToPrevious() {
        int decremented = this.currentIndex - 1;
        this.currentIndex = decremented < 0 ? this.items.Count - 1 : decremented;
    }

    public T Current {
        get {
            return this.items[this.currentIndex];
        }
    }

    public void Select(int index) {
        this.currentIndex = index;
    }

    public void Select(T item) {
        for(int i = 0; i < this.items.Count; ++i) {
            if(this.items[i].Equals(item)) {
                Select(i);
                return;
            }
        }

        throw new Exception("Can't find the item to select: " + item.ToString());
    }

    public int Count {
        get {
            return this.items.Count;
        }
    }

    public T GetAt(int index) {
        return this.items[index];
    }

}

// Usage
// Say you have an array of LanguageOption
LanguageOption[] languages = ...;
SelectionSequence<LanguageOption> langSequence = new SelectionSequence<LanguageOption>(languages);

// When next button is clicked
langSequence.MoveToNext();

// When previous button is clicked
langSequence.MoveToPrevious();

// Do something with current selection
ChangeLanguage(langSequence.Current);

This kind of selection have come up in Academia, too.

SelectionExample

These are just some of my cute little classes. They’re small but they have been very useful. Here’s some programming tip, think of making classes like making a new invention or a device. That way, you will think in terms of narrowing functionality as much as possible and expose only appropriate public methods. This will also make your classes more modular. Over time, you will develop a library of robust and reusable code.

Reflection Series – Part 3: Attributes are Magic

Attributes in C# are those things wrapped in “[]” that are sprinkled on classes, properties, or variables. In Unity, I usually use [SerializeField] so that a variable becomes editable in the editor but still remains private or protected in code if I wanted to. There are other attributes, too, like Range, ExecuteInEditMode, HideInInspector, DisallowMultipleComponent, etc. Somewhere in Unity’s processes access these attributes through reflection and executes code that the attribute dictates. The coolest part is you can make your own attributes. The following is a very simple attribute:

[AttributeUsage(AttributeTargets.Property)]
public class PropertyGroup : Attribute {

    private readonly string name;

    public PropertyGroup(string name) {
        this.name = name;
    }

    public string Name {
        get {
            return name;
        }
    }

}

It’s an attribute that can be attached to properties (AttributeTargets.Property). It requires a string name. This is how it can be used:

        ...

        [PropertyGroup("Settings")]
        public string Gender {
            get {
                return gender;
            }

            set {
                this.gender = value;
            }
        }

        [PropertyGroup("Settings")]
        public string Type {
            get {
                return type;
            }

            set {
                this.type = value;
            }
        }

        [PropertyGroup("OrientationIds")]
        public string DownSpriteId {
            get {
                return downSpriteId;
            }

            set {
                this.downSpriteId = value;
            }
        }

        [PropertyGroup("OrientationIds")]
        public string RightSpriteId {
            get {
                return rightSpriteId;
            }

            set {
                this.rightSpriteId = value;
            }
        }

        ...

We use PropertyGroup attribute as a grouping mechanism for our generic editor. What we do is in our editor code, we look for this attribute and collect such properties in their own container before rendering them. There are many ways to access an attribute through reflection. The following is one way:

public static T GetCustomAttribute<T>(PropertyInfo property) where T : Attribute {
    Attribute attribute = Attribute.GetCustomAttribute(property, typeof(T));
    return attribute as T;
}

// Usage
PropertyGroup group = GetCustomAttribute<PropertyGroup>(propertyInfo);

// Do something with the attribute like access its name
List<PropertyInfo> propertyList = GetPropertyList(group.Name);

With this, we can change the look of our editor by just adding attributes to our classes.

GroupedProperties

Other Uses

Persistence

In Part 2 of this series, I discussed an XML writer/reader by reading properties of classes. Aside from this, we also have a property attribute named Persist to selectively write/read properties with such attribute. The attribute also allows specification of a default value. We heavily use this attribute in our persistence system. This is useful for properties that are not present in old save files and you want a default value for them.

    [AttributeUsage(AttributeTargets.Property)]
    public class Persist : Attribute {

        private object defaultValue;

        public Persist() {
        }

        public Persist(object defaultValue) {
            this.defaultValue = defaultValue;
        }

        public object DefaultValue {
            get {
                return defaultValue;
            }
        }

    }

    // Sample usage
    [Persist]
    public float PolledTime {
        get {
            return polledTime;
        }

        set {
            this.polledTime = value;
        }
    }

    [Persist(1)]
    public int Day {
        get {
            return day;
        }

        set {
            this.day = value;
        }
    }

    [Persist(1)]
    public int Year {
        get {
            return year;
        }

        set {
            this.year = value;
        }
    }

    ...

Class Browser

In Part 1, I wrote about loading classes using their class names. As such, we have a lot of different editors where a user can select from a selection of different classes that derive from a single base class. The amount of classes written for these editors can get out of hand so we made a class level property to group classes into their respective domains.

    [AttributeUsage(AttributeTargets.Class)]
    public class Group : Attribute {

        private readonly string name;

        public Group(string name) {
            this.name = name;
        }

        public string Name {
            get {
                return name;
            }
        }

    }

    // Usage
    [Group("Game.CharacterNeeds")]
    public class AddNeedAmount : ComponentAction<CharacterNeeds> {
        ...
    }

    [Group("Game.Task")]
    class GetCurrentTaskEffortPerTile : ComponentAction<TaskDoer> {
    }

With this attribute, we can make our class browsers to look like this:

ClassBrowser

Conclusion

Reflection is a worthy tool to add to your gamedev toolbox. It’s powerful and useful. What I did in this series is probably just the tip of an iceberg. I’ve read about modders who opened up, ripped, and replaced game parts of C# games using reflection. Yikes!

I’m going to end the series for now. I may add to it later. I hope I have convinced you that reflection is a cool toy to learn.

Reflection Series – Part 2: Harnessing Properties

One of my favorite features in reflection is the ability to know about the properties of a certain instance at runtime. This has helped a lot in making tools to aid game development.

Basics

The following code is the simplest way to iterate through the properties of an instance:

// Let's say there's some instance named myInstance
Type type = typeof(myInstance);

// Get the properties that are public and not static
PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);

foreach(PropertyInfo property in properties) {
    // Do something with property...
}

PropertyInfo contains the information about a property. You can get its getter and setter methods. You can invoke them. You can get its return type. You can query the attributes attached to the property. You will know a lot (just head over to its API reference).

Example Usage

One utility class that I’ve made is a generic XML writer and loader that can accept any instance and write the instance’s public properties to an XML. This way, I don’t have to make a custom XML writer code for each type of data. I can just use this class and tell it to write the instance.

I don’t write all public properties. I only select those with public getter and setter. The following is a utility method if such property is meant to be written:

public static bool IsVariableProperty(PropertyInfo property) {
    // should be writable and readable
    if(!(property.CanRead && property.CanWrite)) {
        return false;
    }

    // methods should be public
    MethodInfo getMethod = property.GetGetMethod(false);
    if(getMethod == null) {
        return false;
    }

    MethodInfo setMethod = property.GetSetMethod(false);
    if(setMethod == null) {
        return false;
    }

    return true;
}

This is how I built the writer class (showing only the important parts):

class InstanceWriter {

    private readonly Type type;
    private PropertyInfo[] properties;

    // A common delegate for writing a property of each type
    private delegate void PropertyWriter(XmlWriter writer, PropertyInfo property, object instance);
    private Dictionary<Type, PropertyWriter> attributeWriterMap = new Dictionary<Type, PropertyWriter>();

    // Constructor
    public InstanceWriter(Type type) {
        this.type = type;
        this.properties = this.type.GetProperties(BindingFlags.Public | BindingFlags.Instance); // Cached

        // Populate map of writers
        this.attributeWriterMap[typeof(string)] = WriteAsAttribute;
        this.attributeWriterMap[typeof(int)] = WriteAsAttribute;
        this.attributeWriterMap[typeof(float)] = WriteAsAttribute;
        this.attributeWriterMap[typeof(bool)] = WriteAsAttribute;
        // ... More types can be added here if needed
    }

    // Writes the specified instance to the writer
    public void Write(XmlWriter writer, object instance) {
        writer.WriteStartElement(this.type.Name);

        // Traverse properties
        foreach (PropertyInfo property in this.properties) {
            if (!TypeUtils.IsVariableProperty(property)) {
                // Not a candidate to be written
                continue;
            }

            // Must have a writer
            PropertyWriter propWriter = null;
            if (this.attributeWriterMap.TryGetValue(property.PropertyType, out propWriter)) {
                // Invokes the property writer
                propWriter(writer, property, instance);
            }
        }

        writer.WriteEndElement();
    }

    // Writer methods. There are more of these to support the types you need to support.
    private static void WriteAsAttribute(XmlWriter writer, PropertyInfo property, object instance) {
        // Invoking the getter using reflection
        object value = property.GetGetMethod().Invoke(instance, null);
        if (value != null) {
            writer.WriteAttributeString(property.Name, value.ToString());
        }
    }

}

This class just maintains a dictionary of writer methods mapped by Type. During traversal of properties, it checks if a property needs to be written and that it has a mapped writer method. PropertyInfo.PropertyType was used to get the type of the property. It then proceeds to invoke that writer method which writes the value to the XmlWriter.

The actual class is more elaborate than this. There’s a separate map for property writers that needs child elements. For example, Vector3 needs a child element and its xyz values are stored as attributes. We also took it further by checking if the property implements a custom interface of ours named IXmlSerializable and invokes the writer method of that property.

This is then how it is used:

InstanceWriter writer = new InstanceWriter(typeof(MyClass));
writer.Write(xmlWriter, myClassInstance); // Writes a whole element representing MyClass

My XmlLoader was made using the same concept only that the mapped methods now invoke the setter of the property. This is one of the loader methods:

private static void LoadString(SimpleXmlNode node, PropertyInfo property, object instance) {
    if(!node.HasAttribute(property.Name)) {
        // No value from XML. Set a default value.
        SetDefault(property, instance);
        return;
    }

    string value = node.GetAttribute(property.Name);
    property.GetSetMethod().Invoke(instance, new object[] { value });
}

Other Uses

I’ve made a generic data Unity editor that can support any type of data class as long as they expose the editable variables in the form of properties. As you can see in my other posts, most of our data editors have the same look. That’s because we are using the same base code for the editor and provide the custom rendering when necessary.

CharacterSpritesEditor
One of our generic data editors

In part 1 of this series where I talked about loading instances from mere string, we are also using properties manipulation to expose the variables of such instances in the editor. The following is a screenshot from our GOAP data editor.

GoapVariables

All of these are possible because of reflection.

Reflection Series – Part 1: From Class Name to Instance

I’m starting a series on how I’ve used reflection for my projects. I saw that I’ve actually made a lot of stuff out of it and I just can’t put them all in one long post. I’ll start with a brief introduction to what reflection is and discuss a simple usage that has huge potential.

Reflection refers to the set of APIs that “makes it possible to inspect classes, interfaces, fields and methods at runtime, without knowing the names of the classes, methods etc. at compile time. It is also possible to instantiate new objects, invoke methods and get/set field values using such API.” Basically, you can do things like traversing all the properties of a class instance and invoke them or assign value to them. You can list the class names that derive from a certain class. You can determine the attributes attached to a property or class. You can do a lot. The limit is your imagination.

Luckily, Unity’s C# environment have access to such API. The namespace is aptly called System.Reflection.

Loading a class name (string) into an actual class instance

Say you have the following class:

namespace Game {
    class Shoot : Command {
        public Shoot() {
            // Default constructor
        }

        public void Execute() {
            ... // Detailed shooting routines
        }
    }
}

By using reflection, we can load a Shoot instance by its full class name. First thing to do is to determine the Type that a class name points to. There’s a method for this named Type.GetType() but this is insufficient. Sometimes, it returns null even when the class exists. I’ve made a utility method for this which I found somewhere on the internet years ago:

public static Type GetType(string typeName) {
    // Try Type.GetType() first. This will work with types defined
    // by the Mono runtime, in the same assembly as the caller, etc.
    Type type = Type.GetType(typeName);

    // If it worked, then we're done here
    if(type != null) {
        return type;
    }

    // Attempt to search for type on the loaded assemblies
    Assembly[] currentAssemblies = AppDomain.CurrentDomain.GetAssemblies();
    foreach(Assembly assembly in currentAssemblies) {
        type = assembly.GetType(typeName);
        if(type != null) {
            return type;
        }
    }

    // If we still haven't found the proper type, we can enumerate all of the
    // loaded assemblies and see if any of them define the type
    var currentAssembly = Assembly.GetExecutingAssembly();
    var referencedAssemblies = currentAssembly.GetReferencedAssemblies();
    foreach(var assemblyName in referencedAssemblies) {
        // Load the referenced assembly
        var assembly = Assembly.Load(assemblyName);
        if(assembly != null) {
            // See if that assembly defines the named type
            type = assembly.GetType(typeName);
            if(type != null) {
                return type;
            }
        }
    }

    // The type just couldn't be found...
    return null;
}

We also need the following utility code to get the constructor with no parameters.

public static ConstructorInfo ResolveEmptyConstructor(Type type) {
   ConstructorInfo[] constructors = type.GetConstructors();
   foreach(ConstructorInfo constructor in constructors) {
       // we only need the default constructor
       if(constructor.GetParameters().Length == 0) {
           return constructor;
       }
   }

   // Can't resolve appropriate constructor. Client code should check for this.
   return null;
}

Then we use the following sequence of code to load the instance.

Type type = TypeUtils.GetType("Game.Shoot"); // Full class name (include the namespaces)
ConstructorInfo constructor = TypeUtils.ResolveEmptyConstructor(type);
object[] EMPTY_PARAMETERS = new object[0]; // This can be made into a static variable

// Invoke the constructor
// Can also be cast to Shoot but I'd like to point out a possible usage
Command command = (Command)constructor.Invoke(EMPTY_PARAMETERS);

// Use the instance
command.Execute();

That wasn’t so hard, was it? But how can this used? We just made an instance from a mere string. Imagine if that string was from an XML file, or JSON, or Unity editor, or whatever. We could build an editor that collects these class names then in the game, we load those classes and use them. I’ve used this a lot in our editors. Just this week, I was working on our Grants editor. In Academia, grants act as resource boost and also guide the player on what to do next. Each grant has a set of requirements. Each requirement is implemented as a class that derives from a base class. The grant data then has a list of requirement class names. I made an editor where the designer can input the values for each grant data and also define its requirements. In the game, I then load these requirement instances and use them.

GrantEditor

The following code can be used to get the types that are deriving from a parent type. This can be used to make something like a class selection browser.

Type[] types = Assembly.GetAssembly(parentType).GetTypes();
foreach (Type type in types) {
    if (type.IsSubclassOf(parentType) && !type.IsAbstract) {
        // Add to some container
        subclassList.Add(type);
    }
}

Hopefully, you have found this example usage of reflection useful. I plan to show more on the next part. But by then, you may have probably thought of more uses for it.

Render Two Sprites in One Shader

Most of the character faces in Academia are generated in a procedural way. Each character has its own combination of face and head. Heads can either be hair or construction hat if they are workers. Both faces and heads are contained in a single texture so Unity may apply batching.

FaceHair
Part of the faces and heads texture

To generate a character, you simply render a face and render its head on top of it.

Characters

This can be done with two sprites. However, there are disadvantages. First, more draw calls. Second, it looks weird when the characters are overlapping because of z fighting. I needed a way to render both the face and head in only one sprite. This reduces draw calls and prevents weird z fighting. Fortunately, this is easy enough to do using a custom shader.

While working on our custom quad mesh where the characters would be displayed on, I realized that vertices can have more than one UV. This means that I can use the first UV for the face and use a second UV to draw the head. These two renders can be done within a single shader.

Shader "Common/TwoUvsLayeredTexture"
{
	Properties
	{
		_Texture("Main Texture", 2D) = "white" {}
	}

	SubShader
	{
		Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
		ZWrite Off Lighting Off Cull Off Fog{ Mode Off } Blend SrcAlpha OneMinusSrcAlpha
		LOD 110

		Pass
		{
			CGPROGRAM
			#pragma vertex vert_vct
			#pragma fragment frag_mult 
			#pragma fragmentoption ARB_precision_hint_fastest
			#include "UnityCG.cginc"

			sampler2D _Texture;

			struct vin_vct
			{
				float4 vertex : POSITION;
				float4 color : COLOR;
				float2 texcoord0 : TEXCOORD0;
				float2 texcoord1 : TEXCOORD1;
			};

			struct v2f_vct
			{
				float4 vertex : SV_POSITION;
				fixed4 color : COLOR;
				float2 texcoord0 : TEXCOORD0;
				float2 texcoord1 : TEXCOORD1;
			};

			v2f_vct vert_vct(vin_vct v)
			{
				v2f_vct o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.color = v.color;
				o.texcoord0 = v.texcoord0;
				o.texcoord1 = v.texcoord1;
				return o;
			}

			fixed4 frag_mult(v2f_vct i) : SV_Target
			{
				fixed4 col1 = tex2D(_Texture, i.texcoord0) * i.color;
				fixed4 col2 = tex2D(_Texture, i.texcoord1) * i.color;

				fixed4 output;
				output.rgb = (col1.rgb * (1.0f - col2.a)) + (col2.rgb * col2.a);
				output.a = min(col1.a + col2.a, 1.0f);
				return output;
			}

			ENDCG
		}
	}
}

The magic is in frag_mult(v2f_vct i). Actually, I’m not too sure if that’s the proper way to blend two images. I’m not very good with shaders. I arrived with that using trial and error. Let me know if there’s a better way.

[Edit] Some people pointed out that it’s generally not ok to have conditionals in shader code. Thus, I’ve updated the code with a better one. This is why I blog.

A Better A* Interface

I have made my own A* framework around 2012. I still use the same code until now. It has been improved a lot of times already but one thing that didn’t change much is the interface. What I mean by ‘interface’ here is the collection of public classes, methods, and interfaces to access the framework. In this post, I’m showing how I did it. First, I’ll show you the method that executes the A* search:

public void ResolvePath(AStarPath<T> path, NodeHandle<T> start, NodeHandle<T> goal, HeuristicCostCalculator<T> calculator, Reachability<T> reachability = null) {
    ...
}

I’m no longer showing the code on how A* works. There are better resources about that else where. What I’m focusing here is the interface and why I did it that way.

First thing you’ll notice is I’m using a generic type variable. This is important because each game or problem domain has its own way of representing their positions be it tiles or waypoints. It also implies that the algorithm should work for any type of position.

Let’s discuss the parameters:

AStarPath<T> path – This is simply a custom class that contains the sequence of T items. It also stores whether the path is reachable or not. The method stores the A* search result in this object. It was done this way to prevent instantiating this class whenever an A* search is needed. The client code is required to maintain an instance of this class. The caller would then also use this class to traverse the path.

NodeHandle<T> start – The start node (self explanatory). NodeHandle has methods related to adding neighbors or connected nodes. Underneath, it is implemented as a graph node.

NodeHandle<T> goal – The goal node (self explanatory).

HeuristicCostCalculator<T> calculator – This is the cost calculator to use during algorithm execution. Will explain the details later. I provided this interface because different problem domains have different implementations of such calculation.

Reachability<T> reachability – Reachability is an interface that tells whether or not a tile is reachable or not. Will explain the details later. I provided such interface because there are instances where reachability differs in case to case basis. Reachability is optional because it may not be needed at all times. Most use cases for A* is really just shortest path.

HeuristicCostCalculator

HeuristicCostCalculator is implemented as an interface. It looks like this:

public interface HeuristicCostCalculator<T> {
    // Computes the heuristic cost from the specified starting position and the goal.
    float ComputeCost(T start, T goal);
}

Basically, it just computes the heuristic cost given two arbitrary positions. As you know, the heuristic cost is important to the algorithm. Without it, it’s no longer A*.

Reachability

Reachability is also implemented as an interface:

public interface Reachability<T> {
    // A reachability check on a single position
    // This is used to check if a goal is reachable at all
    // If not, the search ends abruptly
    // This is to avoid useless search when the position can't be reached at all
    bool IsReachable(T position);

    // Returns whether or not the specified movement of these two nodes is reachable. 
    bool IsReachable(T from, T to);
}

There are two methods. The first one with only one position parameter is used as a quick check to see if the position is reachable at all. For example, in a tile based game, if the tile has a blocker and thus unreachable, A* can be dropped. Or in another case, a tile is free but all its neighbors are blocked. If the position is not reachable, A* search may no longer be needed.

The second one with two parameters is used while the algorithm is being executed. The parameters are not necessarily the starting and goal nodes. The parameters passed here are nodes that are considered during the A* search. There are times where reachability changes for a certain pair of nodes.

For example, in our game Academia, when a tile is blocked, an agent can’t move diagonally along the tile’s diagonal neighbors like moving from bottom neighbor to right neighbor. The agent has to go through the right neighbor of the bottom tile first then move up to the right neighbor of the newly blocked tile. The bottom neighbor and the right neighbor are reachable by their graph node setup (we allow diagonal movement). By using the reachability interface, we can override this rule and mark the pair as unreachable because of the presence of such blocked tile.

Reachability
Moving from chair to water fountain is not allowed because of the wall. Agent has to go from chair to trash can then to water fountain.

Different games may also have game rules that override the graph node setup. A simple example I can think of is say land tile that is connected to a water tile. Only amphibian units can pass from land to water but not land only units. The Reachability interface can be used to express these rules.

Usage

This is how our A* class is then used:

// Say Tile is our "position" class
AStar<Tile> astar = new AStar();

// Prepare node handles
foreach(Tile tile in tileMap) {
    tile.NodeHandle = astar.Add(tile);
}

// Prepare neighbors
foreach(Tile tile in tileMap) {
    foreach(Tile neighbor in tile.Neighbors) {
        // TileLink here stores the weight for moving from the tile to the neighbor
        tile.NodeHandle.AddPath(neighbor.Handle, new TileLink(tile, neighbor));
    }
}

// To use A* search
AStarPath<Tile> path = new AStarPath<Tile>();
Tile start = ResolveStartTile(); // Let's just say this is how we resolve the starting tile
Tile goal = ResolveGoalTile();

// Say MyHeuristicCalculator and MyReachability are implemented as singletons
astart.ResolvePath(path, start.NodeHandle, goal.NodeHandle, MyHeuristicCalculator.Instance, MyReachability.Instance);

// Use the path of reachable or do something else if not
if(path.Reachable) {
    foreach(Tile tile in path) {
        MoveToTile(tile); // It's not really like this in an actual game but you get the idea
    }
}