Implementing the Plan


So what changed from the plan to the execution?

Time Flow

The first part is the time flow change. What I had in place was that each entity with a rigidbody would also have a method on its controller componenet with a listener for the timescale change event, and would change the speed of the rigidbody to match the new timescale. This turned out to be a bit silly, because it meant the same repeated method on every entity with a rigidbody (namely the player, enemies, and projectiles). It got worse when I came across an issue with the projectiles that, when destroyed, were still somehow listening for the event and raising an exception.

I tried to simplify this, and instead placed a method in the TimeController that looped through every rigidbody and updated its velocities. The problem with this is it undermined my initial premise of keeping some entities from feeling the time flow changes.

So the final solution I came up with was to attach a custom TimeFlow component on the player and enemies. This allowed me to turn this TimeFlow sensitivity on and off per entity, and I could keep the TimeController looping through every TimeFlow rather than every Rigidbody. Just to be clear this loop through every instance of the TimeFlow class is not being done every frame, only whenever the timeScale changes (which would be the action of an enemy or the player), so should not be a performance killer.

So a fair bit to learn from this experiment. I need to read up more on custom events and listeners in Unity so that I know when and how to use them in the future, since this turned out to be a poor example. I'll be experimenting more with events based on player/enemies dying so I will have to do this soon.

Enemies

Right now almost all of the enemy functionality is in their AIBehaviours, so the value of the interface implenetation isn't really apparent. When I start adding animation control and sound effects on actions I think this implementation will really shine.

Otherwise I'm very happy with it. Something I didn't consider when planning is that the code for the enemies shooting and the player shooting are actually almost identical. Additionally, the actual code to fire weapons is in their input/AI component, which should definitely have been abstracted out to a seperate firing component. This would have allowed me to just attach this component to each of the entities, rather than copy and pasting the methods. So, something to remember for the future is to try and identify common actions, and to try to abstract those actions outside of the member classes. This also ties into the single-use principle, that I should be more dilligent about.

I implemented a simple enemy spawner that continually spawns enemies at discrete intervals, that I can modify to ramp up over time in the future.

Next Steps

So I have a working prototype, right now I would like to get some art in, since I can't really stand looking at coloured squares. Once I have some simple sprites for the player and enemies I can work on adding some more feeling to the game, impactful bullet impacts and enemy deaths.

Comments

Log in with itch.io to leave a comment.

I ended up refactoring the code for the firing of the player and enemies into a seperate "Gun" component that could be attached to each of them, much cleaner!