This is the last part of this tutorial series that explains how to create a simple rhythm game. Here we can see the implementation details of the game actor and their components.
We have 3 blueprint actors. The first one (BP_Game) is the actor that will be added to the Level. This blueprint contain the user interface and an instance of other actor blueprint (BP_Game_dealer), this actor will control the spawn of the beat spheres (BP_Game_dealer_beat)
The BP_Game_dealer is added as a Child Actor component of BP_Game. To be able to call the functions of our dealer class we need to obtain the Child Actor and do a cast to BP_Game_Dealer
Here we have a list with the functions and variables of our game actor. We can see in detail some of the more interesting of variables.
Player and Tracker are only references to the objects contained in the Game Instance, only to avoid the casting on each access to this variables. UI_Game is the user interface created in the previous tutorial, we can construct and show it on this event.
We can initialize both players here too, and the beat tracking analyzer. We want to do only a beat tracking of the 0-100Hz frequency band, so we need to create a 2D array with this bounds as input of that node.
The basic idea is to generate the beat sphere few seconds ahead it sound by the speakers, so the player can see how the sphere travel across the screen until they reach the center and the song of the speaker reach the beat in the song in that exact moment.
So we have 2 important variables, the delay between the tracker and the player playback and the distance between the spawn point and the player button. Both variables determines the velocity of the movement of the beat spheres.
When the game start and the countdown reach zero we need to call both Play nodes with a Delay of 2 seconds.
We are going to use Event Tick cascade, instead of using a different event tick in each of the 3 actor class and synchronize all using more variables. Using this method we only need to pause the BP_Game and all the child actor will stop too.
The Delta time must be shared with all the actor components, it is very important to obtain a synchronized the movement.
The Game Tick event of the BP_Game_dealer must call to the Game Tick of all their beat spheres BP_Game_dealer_beat.
The Game Tick of BP_Game_dealer_beat actors is only used to move the sphere
With that call the event tick call chain is completed. The other part of the Event Tick of BP_Game is used to calculate the spawn of the beat actors. We have added a variable to remove the first seconds of the analysis, on a real-time analysis we can obtain false positives in this first seconds.
We only want to spawn on beat on-set, so we need to add a variable to do this. When this variable is false and the beat analyzer returns a true we need to spawn a new sphere in their actor dealer.
We need to add a cooldown time in the dealer actor to avoid to generate too much spheres in a short time and overlap beat spheres. We need to calculate and pass the modify parameters to the sphere, like the movement speed and the scale speed. We need to pass too the distance to the button zone. If the beat sphere overtake that position and the player doesn’t catch the beat we need to subtract some score and mark the beat to their destruction.
Tip: To check if the beat is inside the dealer button we need to add a threshold around the center point to allow some margin to the player capacity.
The player button is only a displaced cylinder in the BP_Game_dealer actor. The beat spheres will spawn in the origin point of the dealer actor and moved in the cylinder direction.
To capture the player mouse event we need to assign the input of the Player 0 to the actor using the Input property Auto Receive Input
In the Project Settings we need to enable the option Mouse Properties > Use Mouse for Touch, this option it is very useful if we want to develop a game for a desktop and a mobile environment.
Now we can link the event to our function to check the beat
This function iterates over all their beat actors using their IsInside function to check if the beat is in the player button position.
If the beat is inside the cylinder then the player has captured a beat and we will increase their score. We will remove and destroy this actor from the beat list of the dealer.
Now we have a very basic rhythm game working, we can do a more complex game from here adding more dealers and effects, a song selector, highscores panel…
Support this blog!
For the past year I've been dedicating more of my time to the creation of tutorials, mainly about game development. If you think these posts have either helped or inspired you, please consider supporting this blog. Thank you so much for your contribution!