The gameplay in our heads and in practice are very different things. What we find interesting will be a complete horror for others. In addition, the project often have controversial points – management, rules of the game, game dynamics and so on. Therefore, before you break into the development and implement the plan, you must first make a prototype – a raw and fast product that will try the basic mechanics and get an idea of the gameplay.
In the finished prototype will be:
The character is running forward, on the buttons “A,” “D” change the lock on the axis “X.”
The level we’re moving on is Tile Map. As the character moves, the past tile moves forward.
The coins we will collect and the counting of points.
A simple UI (Game Over, Score, Restart) and the end of the game when faced with an obstacle.
I have prepared the assets in advance and will be loaded from the finished project. I’ll write logic from scratch.
Creating a project and setting up a character
Let’s create a project based on Third Person, in which we will have a character and a level by default.
I remove excess geometry from the level and adjust the character’s control. Initially, when you click on “W”, the MoveForward event is raised and the character moves forward. We will call the logic of moving forward not by pressing a button, but on an Event Tick, that is, for each frame in the game, so that the character runs forward all the time.
Then we adjust the character’s movement to the “A”, “D” buttons – we change the location along the X axis .
We create an array of float variables in which we will store the location values along the X axis of each of the three “tracks” along which the character runs.
Next, we check on which lane we are running – 0, 1 or 2, then by pressing the “A”, “D” buttons we add or subtract the lane index if it does not exceed the minimum and maximum values.
After that, depending on the index of the lane, set the coordinates on the X axis for our character.
Let’s start by preparing assets for level generation. We will need:
- Cars that we will arrange by level.
- Coins that we will collect.
- Tile is a blueprint actor with level filling. From the tiles we will generate a “corridor” of our level.
Now let’s make cars that will spawn on the level. To diversify the game, we will generate a random car from an array of possible options. Create a new blueprint actor, add the Static Mesh component to it. We create an array with geometry options for our machines. Next, we write the logic that, when creating the machine, it will generate a random (within the array) number – the index, and using it to set our ector geometry from the array.
Each individual tile on each lane of the road in a random place along the Y axis spoils the machine, and a random group of coins spawns.
So that the geometry of coins and cars does not intersect, we will spawn the coins above so that they fall on the map. In a collision with a typewriter or road, we turn off the physics for them. Thus, the coins will be at the same height above the asphalt and above the cars, in those places where they are. Here I have them at an unequal distance from each other, but for that he is also a prototype in order to quickly convey the principle without a long study.
We create a blueprint actor, add a geometry component and a collision to it, which will be responsible for disabling physics in a collision with a surface.
By default, we make our actor a physical object to enable gravity. To do this, check the box physics enabled. Next, add the physics shutdown logic when we no longer need it.
Make the coin spin all the time.
We create a tile from which a level will be generated at which the character will run. I create a new Blueprint actor, add the components we need:
- StaticMesh – Building geometry and surroundings.
- Box Collision “SpawnPoint Box” is a collision that will work out the event when the character runs this tile. This is necessary so that we can invoke the logic of destroying this tile and the new spawn ahead.
- Spawn point – the coordinate point at which we will spawn the new tile.
Next, we write the functions of generating machines. The logic here is this – we get the local tile and in a random place from the given range along the Y axis spawn BP_Car.
The same is for coins, just add a cycle to generate several pieces at once.
At the beginning of the game, we call the functions of the machine spawn, one for each lane, and spawn coins on a random lane.
Now in GameMode we will write the level generation logic. The GameMode class is responsible for setting the rules of the game. Rules may include any behavior related to the game. For example, the conditions for winning or, as in our case, the generation of a tile map. The tile spawn function will look like this:
We spawn the first tile in zero coordinates, which are recorded in the NextSpawnPoint variable. After that we pull out the location at his Spawn Point. We get the coordinates of this point and write them into the NextSpawnPoint variable – these coordinates will be used for the next tile. We call the function again to spawn the next tile. In Game Mode on Event Begin Play, create a loop that will trigger spawn tiles for the number of times we need.
The beginning of the game starts the cycle. It runs from zero to five. That is, the Spawn Tile function is called six times. Accordingly, at the beginning of the game six tiles are spawned.
If we start the game now, our tile map will be generated, but we can run it from beginning to end. Let’s write the logic for real time tile generation when moving around the level. In BP_Tile, add the On Component Begin Overlap event to the SpawnPoint Box. It will be triggered when the component box intersects with another object in the game world that has a collision. The event checks that it encountered a SpawnPointBox. If this is the character that we control, then we call the function of the spawn of the new tile from Game Mode and after the delay we delete the passed tile.
Create a Widget Blueprint and call it WBP_Point.
Add the following text widgets to our widget:
- Your score
- Total score
Let’s make our text widgets variables to set values for them.
Visibility of all widget elements except Score, set Hiden and add the Restart button, by clicking on which our level will reopen.
In general, our widget should look something like this:
Let’s go to Graph and create an “Score” variable of type integer – an integer. For Score and Total Score texts, we will attach the created int variable as a value. Now we will set the value from the variable to the text, and the variable, in turn, will be changed in the character.
Now add our widget to the viewport. To do this, create a WBP_Points widget in ThirdPersonCharacter on Event Begin Play, add it to the viewport and save the link to it in the “Widget Score” variable.
Now we have almost everything in order to collect coins. Create a PickupPoints event in ThirdPersonCharacter. When the event is called, we get the value of the Score variable from the link to the Widget Score widget, add 5 points to it and write it back to the Score variable.
PickupPoints will be called from BP_Coin. Add the On Component Begin Overlap event for the static mesh, in which we check what the coin intersects with. If this is ThirdPersonCharacter, call PickupPoints on it and destroy the coin.
Now, when the character intersects with the coin, the number of points will increase by 5, which will immediately appear in the widget, and the coin will disappear / pick up.
Next, we will create the logic of the end of the game, which will be called to the collision of the character with the machine. To do this, create a Game Over function in WBP_Points, in which we will change the visibility of the text widgets Game Over, Total Score, Restart button.
Add a separate Box Collision component to ThirdPersonCharacter.
We will assign an event to a collision with this box, in which we check: if ThirdPersonCharacter collides with BP_Car, then we call the Game Over function from WBP_Points, which will draw the interface we need. Next, turn off the character’s movements and turn on the display of the mouse cursor to be able to click Restart.
Now, if you crash into a typewriter, we get the following result: