Categories
Uncategorised

Developer Journal : Prototype Gameplay

Developer Journal

I’ll be going over the gameplay of my prototype, and how each level in my Unreal Game is designed to help teach players the mechanics of the game.

Good level design is crucial for the prototype as it is a good way to introduce the the mechanics as straightforward as possible through player experience.

“Level design incorporates player capabilities, game mechanics, obstacles, and discoverable elements that create a positive user experience.”

Master Class, 2021

When making my prototype, I considered the best way to incorporate my mechanics would be to let the player discover them at their own pace once first introduced.

Many of the early levels have a fairly linear path which makes them easy to navigate, so the mechanics laid out are more obvious. In the first level the player starts directly in front of a locked door in a single room, and must find a way to a key.

The red key is accessed by a sliding block in a one-way gap that can be only pushed into one direction, the player will be lured to the left side by the glowing key and find the dark area.

After getting the key, the player should head towards the red door to get the blue key which opens the locked gate at the entrance – the idea this should convey is that each coloured key opens their counterpart doors (Figure 1).

Figure 1

After being taught the mechanics of the sliding blocks and keys, the next level further focuses on the sliding blocks and also introduces a new mechanic.

The player starts off in a one-way gap in front of a sliding block, being their only path they have no choice but to push this block. Afterwards they’ll then learn that they are able to push blocks downwards – players may also be lured to the exit and make another bridge with this new knowledge in mind (Figure 2).

Figure 2

However, once they try to form the second bridge, the block pushed off the platform reveals a pressure plate that requires a block to be pushed onto it for the door at the exit to keep open.

This means the player has failed the level, as it is impossible to get the block back up, their only option is to self-detonate as hinted under the level name (Figure 3).

Figure 3

On their second retry, the player would try to form the bridge on the lower path of the level instead to get more blocks. There’s enough blocks to form both bridges and also leave one to weight down the pressure plate (Figure 4).

Figure 4

The next level combines most of the mechanics learned from previous levels, these are formed into a much bigger scale level to further test the player’s knowledge on what they’ve learned.

This level requires the player to collect keys, slide blocks and to make use of the pressure plates to unlock their assigned doors (Figure 5).

Figure 5

The fourth level takes place in complete darkness, and requires the player to make paths around it using the sliding blocks much like the second level but much harder.

The main challenge here is to explore the level’s layout whilst making use out of the player’s passive ability: the light (Figure 6).

Figure 6

The final level of the prototype introduces the first enemy, who starts off in a square room. This is a basic representation of the enemy’s path and direction, as they move straight forward and turn 90 degrees left once they hit a wall.

If the player rushes, then they may come into contact with the enemy and initiate a chase sequence. If the player makes it to unlocking the door, there still will be a delay before it fully opens so there’s a high chance of the enemy catching up to the player by then.

The level teaches you to stay out of the enemy’s sight, and to be patient (Figure 7).

Figure 7

The game has also gone through playtesting, and much of the praise has gone towards how the levels are structured – albeit a couple of bugs as seen in Figure 8.

Figure 8

I’m glad to know that the levels I’ve designed were a success at teaching the game’s core mechanics in an engaging, and fun manner.

To improve upon this, I’d polish the current levels to iron out some bugs and also add in some new ones, though due to time constraints I can’t add more mechanics and further explore current ones as I would’ve liked to of done.

Next time, I may try to get some more play testers so that many more will be likely to uncover oversights like bugs.

Bibliography

Master Class. (2021) How to Become a Video Game Level Designer. [online] Available at: https://www.masterclass.com/articles/how-to-become-a-video-game-level-designer [Accessed 19 May 2021].

Categories
Uncategorised

Developer Journal : Unreal & Blender

Developer Journal

As I’ve mentioned creating 3D Models in some other blog posts, I’ll be going over my process in using Blender to create models and importing them over to Unreal.

For my project, I chose to use Blender as it is a free and open source program. This is mostly intended to benefit independent artists and small teams.

“We build a free and open source complete 3D creation pipeline for artists and small teams, by publicly managed projects on blender.org.”

blender.org, 2021

Because of this, I consider learning and using Blender is good opportunity to show that we can go the extra mile for our Indie Dev project and detail it more.

For my game, I want a low-poly and pixelated style. To avoid any inconsistences for when I get to texture the model, I use a grid snap function to make sure the model’s shape stays accurate to each square on the grid (See Figure 1).

Figure 1

Next up after the model is done would be setting up a UV map for unwrapping and texturing the model, a UV map is a flat representation of the model and is primarily used to wrap textures.

“A UV map is the flat representation of the surface of a 3D model used to easily wrap textures. The process of creating a UV map is called UV unwrapping.”

Thomas Denham, 2021

As you can see, the UV in Figure 2 is unwrapped into 2D shapes on the left representing each face of the model. These 2D shapes can be drawn on to form the textures for the model as shown on the right.

Figure 2

Once a model is done, I export it as an FBX and set the smoothing to “Face” – this is a type of smoothing Unreal supports when importing models and prevents errors from occurring (See Figure 3).

Figure 3

Finally, the model and texture both get imported into Unreal as an asset. To get the model to display the texture I simply open up the asset and set it a new material with the texture on it (Figure 4).

Figure 4

To make the assets stand out much better during gameplay, I edit the materials to have an Emissive Colour attached and then wire it through a multiplier. They also have their Roughness set to 0 as to give them a very glossy look to further capture the attention of the player (Figure 5).

Figure 5

In-game, this makes the objects stand out much better in the dark by using a subtle glow. The reason as to why I’ve done this for my game is to help with the readability of important objects the player will be interacting with (See Figure 6).

Figure 6

I’ve also made plenty of models for my project for detail, this goes for most of the items and environmental objects you can see.

Figure 7 shows a key I modelled to go with the doors, this is a collectable picked up by the player.

Figure 7

Figure 8 shows the sliding blocks, these are given bevelled edges to help distinguish them from the walls.

Figure 8

Figure 9 shows a cell wall, this is essentially just for detail and serves no purpose within the game.

Figure 9

Figure 10 shows a character model I created for the player, however I have not managed to import and animate this into the game due to time constraints.

Figure 10

Overall, I feel as if Blender and Unreal are great tools to work with.

I think it is important to learn different skills with different programs to better improve the versatility of my skills, as in Indie Development working individually or in a small team may require some extra legwork for things such as details – but that is not problem if you have learn how to do perform those skills independently.

I think in the future to improve upon these skills I could try and learn to animate within Blender and to import those into Unreal.

Bibliography

Blender Foundation. (2021) About — blender.org. [online] blender.org. Available at: https://www.blender.org/about/#:~:text=Blender%20is%20the%20free%20and,video%20editing%20and%20game%20creation. [Accessed 18 May 2021].

Denham, T. (2021) What is UV Mapping & Unwrapping?. [online] Concept Art Empire. Available at: https://conceptartempire.com/uv-mapping-unwrapping/#:~:text=A%20UV%20map%20is%20the,used%20in%20the%203D%20space. [Accessed 18 May 2021].

Categories
Uncategorised

Developer Journal : Enemy AI

Developer Journal

As of the 10th of May, I’ve made some more progress on my prototype. This time I’ve made made an enemy AI for the game, this was done with the use of Blackboards and Behaviour trees.

Figure 1 shows the enemy AI in-game with a patrol behaviour, this state is initiated on the start of the level and is reactivated when the enemy loses sight of the player.

Using line traces, the AI is able to find any wall it can collide with and sets a position to move to. Once it reaches it, the AI will simple turn 90 degrees left and repeat.

Figure 1

In Figure 2, Another behaviour is when the AI starts to chase the player, this initializes once the player comes into contact with the AI’s sight radius. Once they’ve reached the player, they’ll explode and result in a game over screen.

Figure 2

To start creating the AI, I needed to create special blueprint known as an AI Controller. This works similarly to the Player Controller, but is more focused on receiving inputs from the environment and game world.

Figure 3

“The job of the AIController is to observe the world around it and make decisions and react accordingly without explicit input from a human player.”

unrealengine.com, 2021

Using this, we are able to get the base for our AI. However we are able to make this AI a lot more intelligent with the use of a Behaviour Tree.

Creating an Advanced Asset, we are able to get our Behaviour Tree. With this, we are able to give our AI Controller some logic to follow.

Figure 4

“While the Behavior Tree asset is used to execute branches containing logic, to determine which branches should be executed”

unrealengine.com, 2021

Finally, we’ll need a Blackboard. This’ll contain certain variables we need to refer to in our Behaviour Tree.

Figure 5

Anything we want our AI to know about will have a Blackboard Key that we can reference.

unrealengine.com, 2021

Now that we have all we need, I now need to go into the AI_Enemy character I created and to set its AI Controller Class to the one I’ve just created (See Figure 6).

Figure 6

Inside the AI Controller, it runs our behaviour tree once the game starts (See Figure 7).

It also has an event linked to AIPerception, which is used to create a sight for our enemy that’s casted to our player.

If successfully sensed then a boolean will be activated in our Blackboard to activate a chase sequence – I’ll be able to explain this later.

Figure 7

Next up is the Behaviour Tree itself, as you can see there are two different branches from the selector; Patrol and Chase.

If the boolean used to detect the player mentioned earlier was false, then the left part of the tree will play. If the boolean was true then the right part of the tree will activate instead.

Each will lead to a sequence that will play certain tasks, starting from the left side, this is where the player gets given actions to do in a specific order that’s numbered (See Figure 8).

Figure 8

Inside both sequences, you can see that they both take the SeePlayer boolean from our Blackboard (See Figure 9).

Figure 9

Our first task in the left sequence starts with the enemy finding a wall, this is done using a LineTraceByChannel which starts at the enemy’s position and heads forwards in front of them by 1000 units.

Once the line hits a wall, it’ll take the vector of the hit location and use it as the enemy’s next location to move to (See Figure 10)

Figure 10

After the execution is finished, the next task in the sequence is played which will be a Move To. This is assigned to a vector variable from the Blackboard known as TargetLocation, this is where the location for where line hits is stored (See Figure 11).

Figure 11

After the enemy has moved to its location, the next and final task is to rotate 90 degrees to the left. Using a SetActorRotation, I am able to change the rotation of the enemy with a value.

The value gets the actor’s current rotation on the Z axis and divides it by 90, it then rounds it to the nearest integer and times it by 90 – this is done so we can get a perfect snap for the rotation as to avoid any inaccurate rotations.

90 is then simply taken away from the player’s z axis and thus turns them a perfect 90 degrees left once we put the value into the new rotation (See Figure 12).

Figure 12

Once this task is finished, the whole sequence is then repeated from the first task again until the PlayerSee boolean activates.

In our next sequence for when the PlayerSee boolean is activated, a chase sequence is initiated. The first task of this sequence is to simply get the player character’s location using our AI’s perception from earlier (See Figure 13).

Figure 13

Next up in the chase sequence would be a task that made the AI move to this location (See Figure 14).

Figure 14

This sequence will keep going until the enemy loses sight of our player, thus making the SeePlayer boolean false again.

As this was my first time trying to make AI within Unreal, I feel as if the task was a success and I was able to comprehend how to use the Blackboard and Behaviour Trees.

Although the AI is quite simple, it still may need some improving such as having to go back to it’s original location after chasing the player – this may have to be left for any extra polish I can fit into the game.

Bibliography

Docs.unrealengine.com. (2021) AIController. [online] Available at: https://docs.unrealengine.com/en-US/InteractiveExperiences/Framework/Controller/AIController/index.html [Accessed 16 May 2021].

Docs.unrealengine.com. (2021) Behavior Tree Quick Start Guide. [online] Available at: https://docs.unrealengine.com/en-US/InteractiveExperiences/ArtificialIntelligence/BehaviorTrees/BehaviorTreeQuickStart/index.html [Accessed 16 May 2021].

Docs.unrealengine.com. (2021) Behavior Trees. [online] Available at: https://docs.unrealengine.com/en-US/InteractiveExperiences/ArtificialIntelligence/BehaviorTrees/index.html [Accessed 16 May 2021].

Categories
Uncategorised

Developer Journal : Unreal Keys and Doors

Developer Journal

As of the 3rd of April, I’ve learned how to use Structs within Unreal to create a proper colour-coded key system with doors.

I’ll be using structs as a more accessible way to edit multiple types of data for an actor in my project.

“A struct is a collection of different types of data that are related and held together for easy access.”

unrealengine.com, 2021

This is important as the collectable keys have more than one variable – A single key will contain; an image, text and colour.

How it works in the game is that I’ve currently got a key system where certain colour-coded keys open doors with matching colours, I’ve also made models for each of these actors as seen in Figure 1.

Figure 1

Each key also has a unique material and light assigned to it from the struct.

Not only that, but I’ve also got a widget list that keeps track of all the current keys the player has collected throughout the level on the top right of the screen in Figure 2.

Figure 2

So how was I able to do this? I created a structure blueprint for the data I wanted to store within the keys and doors, this contained variables for a 2D Texture, a text variable and a linear colour (Figure 3).

Figure 3

For the keys and doors, a variable of this data structure is stored in both of them.

This will be used to help detect whether the variable of the key the player is using on the door matches the exact key data variable the door contains. Figure 4 shows a struct variable in one of the actors of Key Data containing the values we’d entered earlier.

Figure 4

The keys will have to be collected by the player, so the Player has an array type of the Key Data variable (Figure 5).

Figure 5

Back to the key actor, there is a component overlap that casts to the Player and calls a custom event for storing the key in the array. Here, we get the key variable from our current key that is being collected to insert into the player’s inventory (Figure 6).

Figure 6

Using a custom event, we can now use the New Key to add it to the player’s inventory array. Included is also a casting towards our game mode blueprint – this will come in later once get to the widgets (Figure 7)

Figure 7

Now for our door actor, we have a begin overlap event that casts to the player’s inventory and checks to see if it contains a matching key – this is a structure whose variables completely match our collected key’s.

If the player does contain a matching key, then the door will be opened (Figure 8).

Figure 8

To also help differentiate different keys and doors between each other, an event BeginPlay will check to see a key or door’s Key Data variable and change their material based on if the text matches the Literal Text.

For example, if the struct contains a text variable called “Red Key”, then that exactly equals to the Literal Text named “Red Key” as well. If this is true then set the material of the key or door to red.

If it’s false then move onto another section where it will be compared to a different text, if the text doesn’t match any then it will turn the door into a Neutral colour (Figure 9).

Figure 9

Keys will also set the colour of their light to the colour variable in the struct as well, Figure 10 shows what the doors and keys look like in-game.

Figure 10

As for the Widgets, I want the keys to display on the player’s interface so that they know what current key they’re holding – this can be useful to help the player keep track of all the keys they’ve stored.

I created an object blueprint that would store variables from Key Data to then be used later to display on the Widget (Figure 11).

Figure 11

I’d made a ListView widget containing where these collectables will be stored, using a custom function called Add Key.

There you can see that there is an input for New Data, this is adds the data received to the list (Figure 12).

Figure 12

Although before we start adding to our list, we need a separate Widget which will be how we want each individual line to display on our list.

In Figure 13, I’ve binded the text, color and image of an object to this particular line I want to enter.

Figure 13

To make this compatible with the ListView widget, I implemented a UserObjectListEntry interface.

This helps get our object supplied by the Add Item method earlier, this is then casted to the KeyInfoData and is stored as a variable (Figure 14).

Figure 14

Now all we do is just bind our list’s widget entry class to widget we’d just created and it will display the entries on the list like so (Figure 15).

Figure 15

In our game mode blueprint, we create the list when the game starts, we also promote the return value of the widget into a variable to be referenced later (Figure 16).

Figure 16

Using a custom function within our game mode blueprint, we can add any entry widget to the list by taking the Key Data and using it as the function’s input.

Also included is a Key Array within the game mode to add the following keys to the array (Figure 17).

Figure 17

As from earlier, our cast to the game mode from picked up keys enable them to be displayed in the list like this.

As some of their functions are binded to the data struct’s variables they display the images and colours correctly to the picked up key’s (See Figure 18).

Figure 18

This was one of the more challenging tasks of working on my game, but I am glad I managed to learn and figure out how to get Data Structures working within Unreal.

This was important to the game as to make it more readable to the player by displaying the data of their collectables to the User Interface, although not completely necessary I still feel as if it can go a long way to help make the game more accessible.

However, I think some parts can be improved a bit better such as how changing the object’s material could use a simpler and more efficient function rather than using a lot of branches.

Bibliography

Docs.unrealengine.com. (2021) Struct Variables in Blueprints. [online] Available at: https://docs.unrealengine.com/en-US/ProgrammingAndScripting/Blueprints/UserGuide/Variables/Structs/index.html [Accessed 9 May 2021].

Categories
Uncategorised

Developer Journal : Widgets and Transitions

Developer Journal

As of the 26th of April, I’ve made more progress on my game by adding elements to the User Interface known as Widgets as well as some Level Transitions.

For my game, I’ve considered adding multiple levels as well as a simple UI to help transition the players to the next level by giving them a button to press once the current level had been beaten.

As seen in Figure 1 of the video below, this shows the results of my implementation of these features working within the game.

Figure 1

The Widget used at the end of each level simply accomplishes the player once they’ve beaten the current level and are given an option to continue onto the next.

In the designer section of the widget, I kept the UI relatively minimal looking with a short message and a working button.

Figure 2

Not only does Unreal allow us to design just a UI with the widget system, but we can also assign something to happen if the UI is interacted with. Using the button, we can make it so that once clicked the Player’s input can trigger a certain function within the game.

“The Widget Blueprint uses Blueprint Visual Scripting to design the layout as well as script functionality for UI elements such as what happens when a button is clicked or if a value changes.”

unrealengine.com, 2021

When the button is clicked on our widget, we want to activate a function that easily transitions the player to the next level or restarts the level if they’ve failed.

Figure 3 shows the blueprint for when the button on the UI is clicked, it also uses a branch to determine a different result whether the player is dead or not.

The game simply uses Names to help give it the level name it wants to open. If the player has failed then it’ll get the current level’s name and reopen it, or if they’ve succeeded then they will fetch a Name variable from the exit which contains the next level’s name.

Figure 3

The exits within the game have their own editable instance which allows me to set their value to the name of a level they’d transition the player to once touched, Figure 4 shows the function of the exit giving their name value to the widget to use later on.

Figure 4

I feel as if I’ve gotten a good idea of how inserting widgets into Unreal works as this task remained to be successful, however the current UI I’ve made for the project seems to look very rough and may need some better looking visuals – this won’t be a top priority however as I need to get a playable build of the game out first.

Bibliography

Docs.unrealengine.com. 2021. Creating and Displaying UI. [online] Available at: https://docs.unrealengine.com/en-US/InteractiveExperiences/UMG/HowTo/CreatingWidgets/index.html [Accessed 4 May 2021].