Explore an abandoned Asian-style village, with all that remains being lost memories or "Ghosts" from the past. Dispel ghosts by increasing your brightness, if it's too dark you will become but another memory.
Press X to light the way,
Shine enough the ghosts become your prey.
However, if the light goes dim.
Your life looks very grim.
Villagers Memory is a prototype and the first game I've made in Unreal Engine. The purpose of this prototype was to help me learn Unreal 5 whilst also developing my Technical Design skills for Virtual Reality. I found that Unreal Engine is much more different to Unity than I had first imagined and that jumping straight into a Virtual Reality prototype proved more challenging than I had initially expected.
My Initial Goals For This Project
My initial goal for this project was to learn Unreal Engine 5 sufficiently to produce a simple VR prototype and develop my skills in gameplay and systems design.
I planned to achieve this by watching multiple tutorials before jumping into making a game and then learning based on my experience. I felt this was the best approach as otherwise, I would likely forget useful information that I'd use consistently throughout development and instead remember information that I would only use in rare circumstances.
Going into this project I didn't have a plan for a game mechanic that I wanted to prototype, rather I felt I'd watch basic unreal 5 tutorials first and then after playing around with it, decide on a concept that felt within my scope whilst also providing opportunities to expand
Learning Unreal Engine
I began by following an Unreal Engine 5 tutorial on Youtube by Smart Poly. This tutorial gave me a basic idea of the layout and how to navigate the engine. While it went into some details about blueprints and how to set up a project, most of the video was about building a world and was very art orientated. By the end of the tutorial, I had a basic 3rd person character that would run around an island and if it went through an invisible collider, it would lose 10 health and if it reached 0 health it would die.
While this was a good start, I felt I lacked an understanding of how the game functioned and as I wanted to build a prototype of a mechanic, I needed to understand how the blueprint system within Unreal functioned. This led me to my second Youtube tutorial which was about the blueprint system within Unreal Engine. Blueprints are a Visual scripting tool which allows you to program despite not knowing C++.
This tutorial by Virtus Learning Hub I found extremely helpful as he explained each component carefully and showed examples of how to get basic functionality working within your game. After completing this tutorial, I had a basic door that opened when you got near and a flashlight that would turn on when you push F. I felt much more confident in developing within Unreal after this and felt the only major component I was missing before I could start was a basic tutorial on Virtual Reality.
When I found out that Virtus Learning Hub had a tutorial on Virtual Reality in Unreal 5 I knew that I had to follow it. After the previous video was so helpful, I was excited to learn how Virtual Reality worked in Unreal Engine. This excitement ended, however, once I realised that VR had changed significantly in Unreal between versions 5.0 and 5.1. This meant I had to find another tutorial which was once again by Smart Poly.
This tutorial taught me everything I needed to know about VR in Unreal and throughout the development process, I repeatedly returned to this video to remind myself of certain components.
By this point, I was now confident I had the basic knowledge to begin attempting to make a game prototype. During the previous tutorial, I downloaded a really nice Asian-style village map which I felt set a nice atmosphere despite there being no people. It was then that I had the idea that you go around an Asian village holding a lantern and dispelling ghosts. I suggested this idea to my girlfriend who then suggested that you have to spam a button to make the lantern brighter. Now I had an idea of what I was going to make, and I felt like I had the ability to make it work.
Building the Setting
To begin I wanted to create an eerie atmosphere, to achieve this I added volumetric fog and turned it into an eerie purple colour. This fog added a lot to the world; however, the map was still as bright as daylight. So, I removed the current directional light as well as the sky sphere. I downloaded a free sky asset from the marketplace which had features like storms which I used to create lightning within the game. By this point, the world looked dark and spooky which felt like what I was aiming for.
Implementing the Mechanics
Now that I had a nice setting, I felt I should begin trying to implement the mechanics of the game. I began by creating a new blueprint class for a lantern which also had a light and grab component attached. This allowed you to pick up the lantern and it would cast a light.
Next, I wanted to make the lantern brighten by clicking X on the controller. I quickly realised, however, that I didn't know how to get the input from a touch controller.
I began searching for how to add this functionality and I found the official Unreal Engine documentation on how to add custom Input events. However, when I tried to follow the documentation, I realised it was outdated and the old input system was deprecated. I then spent hours trying to search for the new system. I had heard that Unity had better documentation than Unreal in the past, but this was my first experience realising just how much better Unity's documentation is.
After hours of searching, I finally found a video showing how to use the new system. This video was thanks to Matt Aspland who single-handedly saved this project from not working. After following this tutorial, I attempted to get the brightness of the lamp to change when the player pressed X.
For some reason, however, this wouldn't function when on the lamp blueprint. I assumed this was because I set the blueprint class to an actor (default) however when I set it as something else it also wouldn't receive any input from the player. However, on the VRPawn blueprint (Player blueprint) it would receive these inputs.
After spending a long while trying to get it to either work on the lamp or on the VRPawn and talk to the lamp, I decided to move the light source onto the hand of the player. This meant that there was no longer a lamp, but the brightness now changed when the player pushed the X button on their controller.
Despite this being a seemingly simple mechanic, it took me a lot longer than I expected and I was incredibly relieved to see it working. Next, I wanted to add enemies for the player to destroy.
To begin with, I found a ghost model online and imported it into the project. I then made a character class blueprint called Enemy_Ghost. I gave the ghost a point light with a limited range as well as a large box collider. The box collider I set to only collide with the player pawn as I wanted it to detect when it touched the player.
It was then that I reached my next massive hurdle. In order to determine if the ghost or the player should die, I needed the Enemy_Ghost blueprint to know the current light intensity which was stored on the VRPawn. Once again, I found a massive lack of documentation. There was talk of casting from the VRPawn but for some reason, I couldn't get this to work so instead I found the component "Get Actor Of Class". To my surprise, after hours of nothing it suddenly worked.
I set it up so that if the light intensity was below 1, the player would die and if above 1 the ghost would die. This worked surprisingly well except that currently if you pressed X the light would remain high. In order to fix this, on the VRPawn I added a loop that every second would decrease the brightness by 1. At the same time, I added an additional light which was bright yellow. This light was a lot more intense than the main one, but the range was extremely small. The purpose of this light was to indicate to the player when their brightness was high enough to kill ghosts as it was difficult to tell before.
At this point I had an enemy that either killed the player or could be killed by the player, however, it was extremely static as it did not move. I didn't know how to go about adding AI to the ghosts, so I went back to youtube to follow a tutorial once again.
I found a really good tutorial by Gorka Games about how to make a super simple enemy AI in Unreal. After following this tutorial, I had ghosts that chased the player in no time. By this point, I was pretty happy with the ghosts and simply added a death sequence, so they flew away as they died. I experimented with trying to get the ghosts to run away when the brightness was below 1, however, this didn't seem to work.
Now in order to make this mechanic feel more like a game, I decided to add a points system to it. Whenever the player killed a ghost, they gained a point. This was super simple to add as a float variable which during development I could print as text onto the screen.
Setting up the UI
By this point, the prototype I wanted to make was effectively done so I decided that I needed some UI elements to display the points as well as allow the player to play and exit the game.
Again, I began by watching a tutorial on how to make UI's in Unreal Engine. This video was once again by Virtus Learning Hub and showed me how to implement a UI into a normal 3D Game. However, it also taught me how the UI widgets worked within Unreal. This helped out when watching the next video which was by the same person about how to implement UI for VR games in UE5.
After watching these tutorials, I created two new maps which were the Main Menu and Game Over. I then added world UI to both of these levels and hooked them up to function correctly. In the game over menu, I also added a score so the player can see what score they got in the game. I then customised them to make them look more thematic for the prototype as the default assets I used from the tutorial didn't match the eeriness of the game.
Sound and Music
Now that the game was becoming more complete, it was time to add sound to the game. I used the YouTube audio library of royalty-free songs in order to find music that fitted the game. I then searched for ghost sound effects and after lots of searching, I found some which felt perfect.
I didn't know how to implement audio but instead of following a tutorial, I thought I'd try figuring it out myself. I placed a meta sound source within the world and tried to add my sounds to it, however, I discovered that Unreal only seems to accept WAV sounds and mine were in MP3. So, I converted all the sounds to WAV and then it automatically created a sound cue.
I figured out that a sound cue is essentially a blueprint for sounds and allows you to have random sounds, loops etc. I decided to play certain songs in the main menu and game over scenes, however, in the main game the songs would be randomised meaning that you couldn't predict what was going to play next.
I then added a ghost cue to the ghosts and added the ghost sound effects I had downloaded. By this point it was ready, however, I found the gameplay somewhat boring to play.
In order to make the game more interesting, I decided to add another ghost type that would only spawn after the player had a certain number of points and required much more brightness to kill.
I decided they needed 5x the amount of brightness and therefore rewarded 5 points rather than 1. The basic AI and blueprints were identical to the first ghost type except for a few different numbers. I also changed their material to a more light blue material to signal a difference in their type.
In order for the player to know if they have enough brightness in order to kill this new ghost, I added a third point light which was bright blue and only turned on if the default intensity was above 5.
I also gave this ghost type a different sound effect than the default ghost. Their speed and vision were increased greatly too as I wanted them to be much more challenging to defeat.
The main purpose of this project was for me to learn Unreal Engine 5 and to work on my skills as a VR systems designer. I found that Unreal Engine 5 is much different to Unity than I had originally expected. The blueprints and very simple templates make it a lot easier to get going straight away.
However, during this process, I have also discovered that there is a massive lack of documentation meaning that if you want to try and do something specific, it can be gruelling to get it working as well as overall stability.
Throughout this project, I have experienced an incredible number of crashes and issues all of which are different and due to the lack of documentation I couldn't determine their cause. Some of these include GPU crashes even in the main menu scene, Memory leaks which it says the cause is my Epic Games login and OpenXR error which doesn't explain anything. The main issue is that there's no reference to what could be causing these errors and it causes the entire editor to crash, removing any unsaved work.
If I were to do this again, I wouldn't go with VR straight away. I would begin by doing a 3D game as I found VR is incredibly unstable, especially when you don't know what you're doing. I found it incredibly annoying when I am looking for a component which I know in Unity but had a different name and location within Unreal and I think this could have been mitigated if I spent more time following tutorials before going and making my own game.
Something I would do again, however, was experimenting with different features or nodes which I didn't know what they did as they often taught me a lot about the engine and what it was capable of.
Overall, I am happy with the outcome as it's a functioning VR prototype using a game engine which I had no experience with before beginning this project. I now feel much more confident using blueprints and look forward to developing future content within the engine.