One Release 3 feature completed this week: the Title Screen! It will likely completely change after I bring an artist onboard, but it gets the job done.
Finished Actor Refactoring
I dug myself into a deep hole last week by refactoring actors. Every unit test failed and there were a couple hundred compiler issues to fix. I’ve mostly climbed my way out of the hole since, and I think the actor architecture is solid enough now to get to the finish line. I now have:
- The main actor class is a plain C# class for all actors. It contains all actor state and is therefore the only class involved in actor saving and loading.
- Actor Types
- A GameObject prefab is defined for each Actor Type. These prefabs are loaded into memory when the game starts. They use composition in a limited manner, typically having only Transform, SpriteRenderer, and Animator components. When a new actor is created, the corresponding Actor Type GameObject is instantiated and associated with the actor.
- A ScriptableObject prefab is defined for each actor type’s definition data. Composition is employed here as well, though it is not supported “out of the box” by Unity, at least not in the way I’m using it. The technique is to add a field to the ScriptableObject that is a parent class or interface, and create custom editors to enable an inherited class (or implementing class in the case of interfaces) to be selected from a dropdown. Reflection is used to get all of the subclasses and populate the dropdown. When an actor is created in the game, Activator.CreateInstance is used to instantiate the class. This allows me to define an actor’s AI and abilities, for example, in the editor instead of in code.
This isn’t an elegant solution, but it addresses the things that were bothering me about the previous architecture, namely redundant type data in each actor instance, having to use MonoBehaviours or ScriptableObjects for composition but not being able to easily save/load component state data, inadequate information hiding, circular dependencies, and unclear division of responsibilities between the different classes comprising actors. The drawbacks of this solution are having to maintain two prefabs for each actor type and not doing composition the “Unity way” with MonoBehaviours.
All Unit Tests Passing, More Unit Tests Added
I’m repeating myself from previous posts, but the unit tests have been well worth the investment in time.
Next week, the plan is to finish the class selection and load game screens. There are still some things that are broken from refactoring and I need to fix those too.