If you are new to game development, then it’s most logical to start by creating a simple game. She will teach you how to implement simple mechanics and how objects interact with each other.
In this part of the tutorial, we will create a first-person game that lasts forever. You will learn the following:
- Infinitely move a player forward.
- Generate obstacles that the player must avoid
- Randomize obstacles for creating variations
- Create a restart button that is displayed when a player encounters an obstacle
As a result, we will have this game:
')
Please note that in this part we will use Blueprints and UMG. If you need to refresh your knowledge, then read the parts on
Blueprints and
UI .
Note: This article is one of the eight parts of the Unreal Engine tutorial:
Getting Started
Download the
project blank and unpack it. Navigate to the project folder and open
InfiniteMatrix.uproject .
Note: if a window opens indicating that the project was created in an earlier version of the Unreal editor, then everything is fine (the engine is often updated). You can either choose the option to create a copy, or the option to convert the project itself.
Click on
Play to check the motion control.
Moving the mouse , you can move vertically and horizontally.
The first thing we need to do is make the player move constantly.
Player forward movement
Go to the
Blueprints folder and open the
BP_Player .
To move a player forward, you need to add an offset to the player’s location in each frame.
First, we need to create a variable that sets the player’s forward speed. Create a
Float variable called
ForwardSpeed and set the default value to
2000 .
Now go to the Event Graph and find the
Event Tick node. Create the following schema:
Multiplying
ForwardSpeed by
Delta Seconds , we get a result
independent of the frame rate .
Note: if you don’t understand what frame rate independence is, then read the part of the
Blueprints tutorial. We analyze it in the section
Frame rate independence .
Now we need to use this result to move the player along the same axis.
Movement along one axis
To move a player, create an
AddActorWorldOffset node. Change the
Sweep value to
true by clicking the
checkbox .
If you try to connect the
Float result to the
Delta Location input, Unreal will automatically convert it to
Vector .
However, in this way the Float value will be written to the X, Y, and Z components of the vector. For our game, forward movement should be performed only along the
X axis. Fortunately, the Vector can be divided into three
Float components.
Ensure that the
Delta Location contact
AddActorWorldOffset is not connected to anything.
Right-click the
Delta Location contact and select
Split Struct Pin .
Finally, connect everything as follows:
Summarize:
- In each frame, the game will multiply ForwardSpeed and Delta Seconds to get a frame rate-independent result.
- AddActorWorldOffset will use this result to move the player along the X axis.
- Since the Sweep is turned on, the player will interrupt forward movement when something is blocking it.
Click on
Compile and return to the main editor. If you click
Play , then you begin to move through the tunnel.
Instead of arranging the tunnels manually, we can create a blueprint that automatically spawns the tunnels.
Creating a system of spawn tunnels
Go to the Content Browser and go to the
Blueprints folder. Create a new
Blueprint Class with the parent class
Actor . Call it
BP_TunnelSpawner and open it.
The game will create tunnels all the time, so it would be nice to create a
function for spawn. Go to the My Blueprint panel and create a new
SpawnTunnel function. The function task will be the tunnel spawn at the specified location.
To pass a location to a function, the function needs an
input parameter . They will be displayed when the function is called as input contacts.
They will also be displayed as output contacts of the node
Entry function.
Let's create an input parameter. Go to the
SpawnTunnel function
graph . Select the
Entry node and go to the Details panel. Click the
+ icon next to the
Inputs section.
Rename the input parameter to
SpawnLocation and change its type to
Vector .
To create a tunnel, add the node
Spawn Actor From Class . Click on the
drop-down list to the right of the
Class contact and select
BP_Tunnel .
To set the location of the spawn,
right-click on the
Spawn Transform contact and select
Split Struct Pin . Then connect the
Spawn Actor From Class node to the
Entry node:
Now when the
SpawnTunnel function is
called, it will spool an instance of
BP_Tunnel at the location passed to it.
Let's check how it works!
Checking the system of spawn tunnels
Switch to the Event Graph and find the
Event BeginPlay node. Add a
SpawnTunnel node and connect it to the
Event BeginPlay node .
In the SpawnTunnel
node, set the
Spawn Location value
(2000, 0, 500) .
Now when you start the game, he will spawn a tunnel on top and in front of the player. Click on
Compile and return to the main editor.
First remove the
BP_Tunnel from the level. To do this,
click on the
BP_Tunnel in the World Outliner. Then press the
Delete key to remove it from the level.
Then go to the Content Browser.
Drag BP_TunnelSpawner with the left mouse button into Viewport. Due to this, its copy will appear on the level.
If you click on
Play , the game will spawn a tunnel on top and in front of the player.
When finished checking, go back to
BP_TunnelSpawner . Reset the
Spawn Location values of the
SpawnTunnel node to
(0, 0, 0) .
After that, click on
Compile and return to the main editor.
In the next section, we will configure
BP_Tunnel to work.
Tunnel Blueprint Setup
BP_Tunnel will perform two tasks. First, it will determine when the game should create a new tunnel. To do this, we will create a trigger zone. After the trigger triggers,
BP_Tunnel will tell
BP_TunnelSpawner to create a new tunnel. Thanks to this, you can create the illusion of an endless tunnel.
Secondly, it will set the spawn point. After this,
BP_TunnelSpawner will use this point as the next spawn location.
Let's start by creating a trigger zone.
Creating a trigger zone
Open
BP_Tunnel and go to the Components panel. Add the
Box Collision component and name it
TriggerZone .
So far, the collision area is rather small. Go to the Details panel and find the
Shape section. Set the
Box Extent property to
(32, 500, 500) .
Now set the
Location property to
(2532, 0, 0) . This will place the
TriggerZone directly at the end of the tunnel mesh. This means that a new tunnel will only have to be created when the player reaches the
end of the tunnel.
Now it’s time to create a spawn point.
Creating a spawn point
To set the location of the spawn point, you can use the
Scene component. These components are ideal for setting locations, because they only have a Transform. They are also visible in Viewport, so you can see where the spawn point is.
Go to the Components panel and make sure nothing is selected. Add the
Scene component and rename it to
SpawnPoint .
Mesh tunnel has a length of
2500 units along the
X axis, so this is where there should be an attachment point. Go to the Details panel and set the
Location property to values
(2500, 0, 0) .
The next thing you need to do is create a function that spawns a tunnel in
SpawnPoint .
Creating tunnels at the point of spawn
Click on
Compile and switch to
BP_TunnelSpawner .
The next
BP_Tunnel should spawn in the
SpawnPoint of the farthest tunnel. Because of this, the tunnel will always continue.
Since the farthest tunnel will always be the last one created, it is easy for us to get a link to it.
Open the
SpawnTunnel graph.
Right-click on the
Return Value contact of the
Spawn Actor From Class node. Select
Promote to Variable and rename the variable to
NewestTunnel .
Now we will always have a link to the farthest tunnel.
Next, create a new function and name it
SpawnTunnelAtSpawnPoint . Create the following graph:
This scheme will receive the newest tunnel and the location of its
SpawnPoint component, then spawn a new tunnel at this location.
In order for
BP_Tunnel to communicate with
BP_TunnelSpawner , it needs a link. Without data transfer,
BP_TunnelSpawner will not know where to spawn the next tunnel.
Creating a link to the tunnel spuner
Click on
Compile and close the
SpawnTunnelAtSpawnPoint graph. Switch to
BP_Tunnel .
Add a new variable and name it
TunnelSpawner . For the
Variable Type, select the
BP_TunnelSpawner \ Object Reference .
Click on
Compile and switch to
BP_TunnelSpawner .
Open the
SpawnTunnel graph and add the indicated nodes:
Now each tunnel will have a link to
BP_TunnelSpawner .
Next you need to tell
BP_TunnelSpawner about the need to spawn the next tunnel when a player enters
TriggerZone .
Trigger zone scripting
Click on
Compile and switch to
BP_Tunnel .
Go to the Components panel and
right-click on
TriggerZone . Select
Add Event \ Add OnComponentBeginOverlap . This will add the following node to the Event Graph:
This node will be executed when the other
Actor touches
TriggerZone .
First we need to check whether
Actor , concerning
TriggerZone , is a player.
Drag the Other Actor contact. Release the
left mouse button in the empty space and select
Cast to BP_Player from the menu.
Note: the tunnel will spawn at the
end of the other tunnel, so it will trigger the
TriggerZone trigger of this tunnel.
Cast to BP_Player prevents all further nodes from being executed if the
Other Actor is a tunnel.
Now add the indicated nodes after the
Cast to BP_Player node :
Let's see what happens step by step here:
- When Actor touches TriggerZone , the On Component Begin Overlap (TriggerZone) node is executed.
- Cast to BP_Player nod checks if the actor is a player
- If this is a player, then BP_TunnelSpawner will create a new tunnel. Its location will be located in the SpawnPoint component of the last tunnel created.
- Since the old tunnel is no longer needed, the game deletes it with the DestroyActor node .
Click on
Compile , return to the main editor and click
Play . When you reach the end of the tunnel, the game will create a new one.
Although the game creates tunnels endlessly, they do not
look endless. You can fix this by making several tunnels visible. Later, when we connect them with obstacles, the player will not be able to see how tunnels are created.
Creating multiple tunnels
The first thing to do is create a function that creates a certain number of tunnels.
Open
BP_TunnelSpawner and create a new function called
SpawnInitialTunnels .
To spool a certain number of tunnels, you can use the
ForLoop node. This node will perform the nodes connected to it the specified number of times. Add a
ForLoop node and connect it to the
Entry node.
For the
ForLoop node to run
n times, the
Last Index must be set to
n - 1 .
In this tutorial we will spawn
three tunnels. To perform three cycles, set the
Last Index value to
2 .
Note: if you do not specify the
First Index or
Last Index fields, then by default they will be equal to
0 .
When the game starts, the player must always be in the tunnel. To do this, you can create the first tunnel at the location of the player.
Creation of the first tunnel
To determine if the first tunnel was created, we can check if
NewestTunnel is set. If not, this means that the first tunnel has not yet been created, because the
NewestTunnel is set only
after the game creates a tunnel.
To perform this check, add an
IsValid node (on which there is a question mark) after the
ForLoop node.
Then we get a link to
NewestTunnel and connect it with the
Input Object contact of the
IsValid node.
If
NewestTunnel is not specified, the
Is Not Valid node will be executed, and vice versa.
Add the following and connect the nodes to the
Is Not Valid contact of the
IsValid node:
This scheme will create a tunnel at the player's Pawn location.
Then we need to create the following tunnels.
Creating the following tunnels
Add a
SpawnTunnelAtAttachPoint node and connect it to the
Is Valid contact of the
IsValid node.
Here is the finished graph:
Summarize:
- The ForLoop node is executed three times.
- In the first cycle, he spunits the tunnel at the player’s location.
- In subsequent cycles, he spunits the tunnel at the SpawnPoint point of the newest tunnel.
Now go to the Event Graph and delete the
SpawnTunnel node. Add the
SpawnInitialTunnels node after the
Event BeginPlay .
Click on
Compile , go back to the main editor and click on
Play . Now the tunnel is much longer!
The game is not very difficult yet, so let's add some obstacles.
Creating obstacles
Here are the meshes that we will use as obstacles:
Open
BP_Tunnel and go to the Components panel. Add the
Static Mesh component and name it
WallMesh .
Go to the Details panel and change its
Static Mesh property to
SM_Hole_01 .
Then set its
Location property value
(2470, 0, 0) , thus placing it at the end of the tunnel.
To make the game more interesting, the walls must also rotate. Add a new variable
Float and name it
RotateSpeed . Set the
Default Value to
30 .
Switch to Event Graph and find the
Event Tick node. Create the following schema:
This will cause
WallMesh to rotate each frame by a specified amount.
Click on
Compile and return to the main editor. Click on
Play to see the walls turn.
Let's make the game more interesting by adding variability to the walls.
Creating wall variations
Instead of creating a new Blueprint for each variation, we can just randomize
WallMesh .
Open
BP_Tunnel and create a new function called
RandomizeWall . Then create the following graph:
As the name implies, the
Set Static Mesh node will set the transmitted mesh to
WallMesh .
To create a list of static meshes, you can use the
Select node.
Drag the contact
New Mesh . Release the
left mouse button on the empty space and add the
Select node.
Select node allows you to specify a list of options. The
Index entry determines which option the
Select node will display.
We have four mesh walls, so we need to create two more
Option contacts. This can be done by
right-clicking on the
Select node by choosing
Add Option Pin . Repeat this operation until you have
four Option pins.
Now give each option the following values:
- Option 0: SM_Hole_01
- Option 1: SM_Hole_02
- Option 2: SM_Hole_03
- Option 3: SM_Hole_04
Now we will make it so that a random option is chosen.
Wall randomization
To obtain a random number, you can use the node
Random Integer in Range . This node returns the value
> = Min and <= Max .
Add a
Random Integer in Range node and connect it to the
Index contact of the
Select node.
Set
Max to
3 . This will give us four possible numbers: 0, 1, 2 and 3.
To add randomness, let's give
WallMesh a random twist. Add the following after the
Set Static Mesh node:
This will add a random rotation to
WallMesh from
0 to
360 degrees.
Here is the finished graph:
Summarize:
- Select node passes the list of meshes.
- A random mesh is selected using the Random Integer in Range node.
- The Set Static Mesh node sets the WallMesh mesh to be selected.
- The AddLocalRotation node adds an offset to the random rotation of WallMesh
Click on
Compile and close the
RandomizeWall graph.
Switch to
BP_TunnelSpawner and open the
SpawnTunnel graph. Add selected node:
Now, when the tunnel goes down, it will have a random wall mesh.
Close the
SpawnTunnel graph and click on
Compile . Return to the main editor and click on
Play to see the wall variations!
If you run into a wall. then stop moving forward. However, if you continue to move and go through the hole, then you will start moving forward again.
The next step is to turn off the movement forward after the player collides with the wall.
Handling collisions with walls
To enable and disable forward motion, you can use the
Boolean variable. It has only two states:
true and
false .
Open the
BP_Player and create a new
Boolean variable called
IsDead .
Go to the
Event Tick node and create a
Branch node.
Now get a link to
IsDead and connect it to the
Condition contact of the
Branch node.
Connect the
Event Tick node to the
Branch node. Then connect the
False pin of the
Branch node to the AddActorWorldOffset
node .
Now when
IsDead is
true , the player will stop.
Now we need to set the
IsDead variable when the player collides with the wall.
Setting the IsDead variable
Click on
Compile and switch to
BP_Tunnel . In the Components panel,
right-click on
WallMesh and select
Add Event \ Add OnComponentHit . This add the following node to the Event Graph:
This node will be executed when another
Actor collides with
WallMesh .
First, we need to check if
Actor is a player facing
WallMesh .
Drag the Other Actor contact. Release the
left mouse button on the empty space and select
Cast to BP_Player from the menu.
Drag a BP_Player contact
to the Cast to BP_Player node . Release the
left key on the empty space and add the
Set Is Dead node.
Set
IsDead to
true by
checking the box .
Click on
Compile and return to the main editor. Click on
Play and try to face the wall. If you move to the hole, you will not move further through it.
In the next section, we will learn how to display the restart button when a player hits a wall.
Display restart button
The widget we will display is called
WBP_Restart . It can be found in the
UI folder. Here is what it looks like:
To display or hide a widget, we need a link to it. Open
BP_Player and create a new
RestartWidget variable. Change the
Variable Type to the
WBP_Restart \ Object Reference .
Then go to the Event Graph and find the
Event BeginPlay node.
Add a
Create Widget node and set the
Class to
WBP_Restart .
Now add the
Set Restart Widget node and connect everything as follows:
Now, when the player spawns, we will create an instance of
WBP_Restart . The next step is to create a function that displays this instance.
Creating a mapping function
Create a new function and name it
DisplayRestart . Having done this, create the following graph:
Summarize:
- Add to Viewport displays RestartWidget on the screen.
- Set Input Mode UI Only allows the player to interact only with the UI. We make it so that the player cannot move while he is dead.
- As the name implies, Set Show Mouse Cursor simply displays the mouse cursor.
To display the restart button, we just need to call
DisplayRestart after a player collides with a wall.
Call display function
Close the
DisplayRestart graph and click on
Compile .
Switch to
BP_Tunnel and locate the
On Component Hit node
(WallMesh) .
Add a
DisplayRestart node to the end of the node chain.
Click on
Compile and close
BP_Tunnel . Return to the main editor and click on
Play . When a player hits a wall, a restart button is displayed.
The final step is to restart the game when you click on the button.
Restart game
When restarting, the game must perform two actions:
- Reset the player status. This includes hiding the restart button from the screen.
- Re-create tunnels. Thus, the player starts from the beginning of the tunnel.
Let's start by resetting the player.
Player reset
Open
BP_Player and create a new function
RestartGame . Create the following graph:
Summarize:
- Set Is Dead sets IsDead to false . This again includes the possibility of moving forward.
- Remove From Parent removes RestartWidget from the screen
- Set Input Mode Game Only again includes the ability to control the game so that the player can move
- Set Show Mouse Cursor hides the mouse cursor.
Now we need to create the tunnels again.
Re-creating tunnels
Click on
Compile and close the
BP_Player .
Open
BP_TunnelSpawner and go to the
SpawnInitialTunnels graph.
First, before creating new tunnels, we need to delete the existing ones.
Add a
Sequence node after the
Entry node. Connect the
Then 1 pin to the
ForLoop node.
Note: Sequence node executes its outputs in sequential order. This is a great way to arrange the graph vertically, especially when the node chains are very long.
Then create the following nodes:
This scheme will receive all existing tunnels and remove them from the game.
Finally, connect the
Then 0 contact of the
Sequence node to the
Get All Actors of Class node.
Thanks to this, the tunnels are deleted before the creation process.Here is the final graph:The last thing to do is to process the click of a button.Processing button presses
Click on Compile and close BP_TunnelSpawner .Go to the Content Browser and locate the UI folder . Double click on WBP_Restart to open it.Select RestartButton and go to the Details panel. Go to the Events section and click on the button next to OnClicked .This will create an On Clicked node (RestartButton) . This node is executed when the player clicks on the RestartButton .Recreate the following pattern:Summarize:
- Get Owning Player Pawn returns the pawn that the player currently controls.
- Cast to BP_Player checks if Pawn belongs to the class BP_Player
- If so, it calls the RestartGame function . This function resets the player and hides the restart button.
- Get All Actors of Class and Get returns BP_TunnelSpawner and calls SpawnInitialTunnels . This function removes all existing tunnels and spunits new ones.
Note: You may be wondering why I did not use the reference variable for BP_TunnelSpawner . The main reason is that BP_Tunnel is not associated with WBP_Restart . For our simple game, it is easier to implement this method than to figure out where to store the reference variable.Click on Compile and close the Blueprint editor. Click on Play to test the restart button!Where to go next?
Download the finished project
here .
Now that we have a simple game, we can start creating something else based on it. Try adding a point counter, increasing when the player avoids hitting the wall.Try also to implement simple classic games like Pong and Tetris . The mechanics of these games are simple, but they can be difficult to implement.If you want to continue exploring, read the next post in the series , which will show you how to animate game characters using Blueprints.