-
Notifications
You must be signed in to change notification settings - Fork 0
Technical Design
Author: Mitchel Vonk,
Created on: 27-02-2025,
Last edited on: 27-02-2025,
Last edited by: Mitchel Vonk
For our game, we wanted the enemy to be controlled by AI. In the Unity game engine, there's two out of the box ways of doing this: ML-Agents package and the Behavior package. We had decided for using the ML-Agents as it offered a great way of training and using machine learning models.
Training is a necessary step in creating a model for our AI. Luckily, Unity has a nice tool for this using Python with PyTorch. From the command-line, I can use the mlagents-learn to as such:
> mlagents-learn --run-id idto start with training my ai with the given run-id. At the end of the training, this will create a model that can then be imported into the engine.
Unity_lO2DxgUg7c.mp4
Above an example of training a model to get to the ball (its goal)

The above image is an example of how the ML-model is used in the engine. It's a combination of a "Behavior Parameters" component and an "Agent" component. The "Vector Observation > Space Size" describes the size of the input layer and the "Vector Observation > Stacked Vectors" describes how many previous inputs are used for determining its next action.
Under "Actions", we are only using 1 "Descrete Branch" that has 4 possible outcomes: 0, 1, 2 and 3 (upperlimit-exclusive). We use this value to decide its preference cardinal direction in which it will go at the next intersection.
The behavior component is used for configuring the ML-model and the agent passes info to the observation (input layer) and receives the action (output layer) given by the model.

Author: Mitchel Vonk,
Created on: 26-02-2025,
Last edited on: 26-02-2025,
Last edited by: Mitchel Vonk
For our game, we want to be able to navigate through the playing-field. This playing field is primarily made up of: corners, T-junctions and intersections. Going from intersection to intersection is done by going on a straight path. So we don’t want to go through walls:

A possible solution could be placing nodes at each intersection that hold the data of allowed directions at the intersection:

This node could be accompanied by a traverser which abides the rules of the intersection. That creates a system where the traverser depends on the intersection-node.
The traverser obviously needs a way to communicate with the intersection-node. This is done by asking the intersection-node the best-corresponding direction with the passed preference direction. The correspondence-value is also returned to the traverser so they can decide if the returned direction is to its liking. By having all this information, the traverser can properly navigate through: corners, T-junctions and intersections:


Author: Mitchel Vonk,
Created on: 12-03-2025,
Last edited on: 12-03-2025,
Last edited by: Mitchel Vonk
In our game, it is possible for the player to control four different characters in the level. So we need a system that can handle this. One of the possible solutions to this problem is a system that handles switching between the characters.
As a solution, I wrote a system that makes use of Unity's input-actions. When the required key is pressed, a function that cycles to the next character in the list is called:

This prepares the next character by disabling the last controlled character and enabling the specified next character.
The system that now controls which character the player controls needs to globally communicate which character is being controlled upon switching. This so other systems can be notified, for example: UI elements, or the communication of a character getting hit by the enemy.
Unity_NtxaSXxXrI.mp4

Author: Daan Dijkstra,
Created on: 13-03-2025,
Last edited on: 13-03-2025,
Last edited by: Daan Dijkstra
For our game we want the playable characters to be move on their own when not controlled by a player. To achieve this we need a system to do that. One of a possible solution for this is to use the Unity behaviour graph.
As a solution I wrote a system that makes use of the Unity behaviour graph. When the ghost is not controlled by a player the behaviour agent (which uses the behaviour graph) activates, and moves the player when it's on an intersection.
(Self is a reference to something on the player often being a monobehaviour class)

This system has to:
- Move the ghost when not controlled by the player.
- Turn off when being controlled by the player.
- Base the momement diraction off where the enemy is.
- Move into a random diraction from time to time.
- Change behaviour based on whether the enemy can attack the ghost or not.

Author: Mikey Clarke,
Created on: 13-03-2025,
Last edited on: 13-03-2025,
Last edited by: Mikey Clarke
When Diva picks up a power pellet, they enter a state where they are able to "eliminate" the player. This elimination will stop the player from moving, and send them to their starting position.
- Move the player object beneath the map and move them to the centre.
- Handle the "Death" as a sprite animation.
- Animate the player body to go under the map and move the player object separately.
- Move the player on a linear line towards the centre when they die.
Animating the player body separate from the player object is the most sound solution. Makes implementing a future death animation easy, and is the fastest solution to set up with a dedicated state for when controls need to be disabled.

Requirements
- Player control body and player sprite mesh body need to be separate.
- Timing needs to be right. This will be done with the use of a Enumerator.
- Animator needs to have a death, dead and idle animation.
- A home position must be defined.