As a part of my masters for one of our first submissions we were tasked with building a small serious game in unity over the course of a couple of weeks. As a part of that we were given the option to create a project based on the research of one of the attending scientists at the Ocean Sciences Meetings 2026 in Glasgow.
For this we chose to base our work on the research by Danny Ionescu and Mina Bizic. Their research centres on the study of macro bacteria, Bacteria that can reach up to 7cm in size as single celled organisms. We were fortunate enough to be able to get in contact with Danny and Mina and organise a meeting with Danny and later a quick in person meeting at the event with Mina. They were both incredibly informative and really enthusiastic about our ideas, and we were really thankful for them taking time out their schedules to speak and work with us on this project.
One of the properties of the organisms discussed at the meeting is that unlike other single celled organisms these creatures do not clone themselves in a binary format. Instead they split into different versions of themselves, by dividing up their proteins and chromosomes in an unequal fashion. Resulting in cells with completely different proteins and chromosomes. We decided to take this idea and expand it into our game.
The idea for our game was first-person collectathon platformer where the player would take the role of a person shrunk down to the size of the bacteria(The bacteria is still relatively small to us) and make use of a unique scientific device to hook onto them and reel them in. With the main goal of the game to catch every bacterium within each area. With the main gameplay loop taking inspiration from games such as the Ape Escape franchise where the collectables act as individual creatures that need to be captured in order to move from one area to the next. Along with Slime rancher taking inspiration from the vacuum catching mechanic for the main game.
With the project also making use of a more non-traditional 3D art style. Using 2D sprites in a 3D space that are set to always rotate towards the player. The inspiration for this was from the upcoming game Mouse P.I. for Hire and the Original Doom from 1993. We decided to pursue this in order to achieve a unique aesthetic for our project to help us stand out and help draw players towards the game.
For my contribution to the project, I would develop the billboarding graphics necessary for the games unique 2D in a 3D space look. Aswell as the Game manager to keep track of what should be spawned, how much of it should be spawned and what bacteria the player has captured. Can the player travel from scene to scene and if so to what scene etc. When writing all my scripts I stuck to a strict naming scheme. Using pascal case for file, asset and script names, snake case for all public/global functions and variables and camel case for all private functions and variables. Aswell as the SOLID design principles when developing the functionality of the scripts.
The Sprite Billboarding was a simple task. With many different resources online and walkthroughs from the unity community to achieve this unique look. With information on setups and thorough explanations of the logic along with how to properly implement it. By taking the rotation in the y-axis of the sprite and setting it equal to the player cameras y-axis. This allows the sprite to always be facing towards the player. We can then change the sprite or animation of the bacteria based of the angle that the player camera is facing towards them. We can calculate this by getting the angle between the forward-facing vectors of both the player and bacteria. We can then use a simple set of if statements to determine which sprite or animation to be used for the bacteria based off the size of the angle.
Diagram demonstrating changing the Bacteria animation based of the angle between the two forward vectors
To allow for the Bacteria to roam around the scene I made use of Unitys navigation mesh, adding a navigation mesh agent to the prefab of the bacteria. I also added a script to the same prefab named BacteriaController. This small script features an enumerator to distinguish the different types of Bacteria. Aswell as a couple functions to destroy the instance of itself in scene and a function to invoke the delegate in order to pass its type to the script that is managing the inventory which will then add it to the bacteria currently being held by the player.
With this now completed and functioning as intended I would then move on to work on the Game manager. Keeping to the SOLID principles I decided to split the game manager into multiple objects to better adhere to the principle of single responsibility.
These objects would consist of the Inventory manager (responsible for managing the Inventory of the Player), area manager (to keep track of what bacteria should be spawned in an area and how many should be spawned) and the door manager (to keep track of what doors have been opened and which ones are closed to the player moving between scenes).
These would all be child objects of the game manager which would handle the responsibility of their setup and destruction once the game was over. An early diagram featuring some elements that were never implemented demonstrates the levels of responsibility for the implemented objects to help aid in the development
Early Responsibility Hierarchy Diagram
To allow for consistent data between scenes the game manager would use a singleton design pattern and the DontDestroyOnLoad Function. This would ensure that when the scene changes the game manager will not be destroyed during the changeover and the use of the singleton pattern would ensure only a single instance of the game manager is active at any time during the game.
To obtain low coupling between objects within the game management system and outside of it (such as the bacteria) while keeping the high cohesion of the game manager and its children. I decided to make use of delegates to reference and invoke functions throughout the scene without needing one object to access the other. Which I made use of for the sending of the bacteria’s data from itself to the inventory manager and the game manager to update the door manager which allows movement between rooms to allow the player to progress
Delegate established and called within the Bacteria Controller
Function called once the delegate has been invoked in the Inventory Manager Script.
I also decided to make use of a script I had made use of for a previous project. The script would allow for Dictionaries to be accessed from the unity editor, as this feature is not currently supported by engine. I decided to use dictionaries instead of lists to be able to more easily map the data being held from one thing to another, for example the name of the scene and the bacteria type spawned in it. These functioned as a set of public classes that acted as the Dictionary and the items within the dictionary. So, the item would feature the variables being held and the dictionary would hold that data in a dynamic array. This data could also be translated into a dictionary by simply taking every item within the dictionary class and passing all the values within into a dictionary and returning that newly created data holder.
This ended up being a success as it allowed for the area manager to hold what kind of bacteria would need to be spawned in which scene and how many would need to be spawned once that scene has been loaded. Which could be changed and edited within the editor. Thid allowed for easier changes to be made during development and testing. An example of the code that held the scene name and spawn locations which allowed for it to be accessed from within Unity’s editor.
Code to create a dictionary that could be accessed from within the unity editor
However, my scripts and work could be developed further with more time put towards the project. For example, the use of a dictionary to hold the Scene name and the bacteria to be spawned in that scene uses an instance of a dictionary using a key pair of a serializable dictionary and an integer. The serializable dictionary being used to hold the scene name and type could have been a simple key value pair as by the end of the project no more than one item was inserted into that dictionary.
I would have liked to create a system that would allow for the current positions of the bacteria to be saved when changing scenes along with which bacteria are active. This would have allowed for greater freedom in the gameplay and would have given the player a reason to go back and forth between multiple areas. Which could have also opened the possibility of having multiple types of bacteria occupy a single scene. I would have liked to also dedicate more time to the player UI as it could be more efficient and better designed. Finally, the variable used to determine how many bacteria enemies are spawned within the scene could have been removed and instead the area manager could have simply collected the total count of spawners within a current scene and used that to determine how many should be spawned in.
However, despite these issues I am pleased with the work my team and I have managed to achieve in the project. With the game demonstrating the ideas and facts of Danny Ionescus and Mina Bizic’s research while also maintaining a fun and engaging gameplay loop.