📜 ⬆️ ⬇️

Tutorial on the Unreal Engine. Part 5: How to create a simple game

image

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:


As a result, we will have this game:
')
Spoiler header

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.

Spoiler header

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:

  1. In each frame, the game will multiply ForwardSpeed and Delta Seconds to get a frame rate-independent result.
  2. AddActorWorldOffset will use this result to move the player along the X axis.
  3. 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.

Spoiler header

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.

Spoiler header

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.

Spoiler header

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:

  1. When Actor touches TriggerZone , the On Component Begin Overlap (TriggerZone) node is executed.
  2. Cast to BP_Player nod checks if the actor is a player
  3. 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.
  4. 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.

Spoiler header

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:

  1. The ForLoop node is executed three times.
  2. In the first cycle, he spunits the tunnel at the player’s location.
  3. 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!

Spoiler header


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.

Spoiler header

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:



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:

  1. Select node passes the list of meshes.
  2. A random mesh is selected using the Random Integer in Range node.
  3. The Set Static Mesh node sets the WallMesh mesh to be selected.
  4. 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!

Spoiler header

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.

Spoiler header

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:

  1. Add to Viewport displays RestartWidget on the screen.
  2. 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.
  3. 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.

Spoiler header

The final step is to restart the game when you click on the button.

Restart game


When restarting, the game must perform two actions:

  1. Reset the player status. This includes hiding the restart button from the screen.
  2. 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:

  1. Set Is Dead sets IsDead to false . This again includes the possibility of moving forward.
  2. Remove From Parent removes RestartWidget from the screen
  3. Set Input Mode Game Only again includes the ability to control the game so that the player can move
  4. 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:

  1. Get Owning Player Pawn returns the pawn that the player currently controls.
  2. Cast to BP_Player checks if Pawn belongs to the class BP_Player
  3. If so, it calls the RestartGame function . This function resets the player and hides the restart button.
  4. 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!

Spoiler header

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.

Source: https://habr.com/ru/post/344690/


All Articles