Unreal Engine 4.17
Coding & Scripting Languages:
C++ & Blueprints
This project is intended to create a game mechanic which allows a developer or player to “play by proxy”. What this means in practice is a user will be able to place waypoints and create a custom path that an AI controlled pawn will take. A user can add and remove waypoints at will. Additionally, they can order the character to begin the set path or stop and reset their position. This is intended as the basis of a turn based full game, details included below.
The application is fully controlled by the mouse. To avoid confusion there are no keyboard controls and the camera is fixed. A user can click on an area a spawn a waypoint. If this area is not located on a navmesh area that is accessible by the waypoint AI it will do nothing and a message will appear to inform the user. If, however, it is in a correct location a new waypoint will spawn.
All other input revolves around the four buttons on the UI located on the right side of the screen.
Undo will remove the waypoint that was placed last (if any).
Play will make the waypoint AI start following the created path.
Reset will stop the waypoints AI movement and reset it to the original location.
Exit will stop the application.
Requirements and Specifications
The initial idea was quite broader in scope initially, encompassing the whole gameplay referenced above. During planning, when time considerations we’re looked at it was reduced to support the basis of the waypoint system, a simple AI that would follow the path and a rudimentary UI via which a user could control the project. A video can be found here: that showcases the base functionality.
Goal 1: Create a usable waypoint system.
Conclude that the system is error-free.
Allow access via the UI.
Goal 2: Create UI so a user can control the application.
Conclude that the UI is error-free.
Flexible yet simple.
Risk 1: Unwanted Feature Growth.
Scope contained to the basic feature needed by all others.
Refer to planning documentation often.
Not implementing anything outside of what is described in this document.
Risk 2: Lack of Unreal C++ Resources
Located Unreal Documentation.
Located appropriate forums.
The challenge in this project was for the developer to grasp the basics on how the engine worked. It’s approach to visual scripting, building & compiling and other features took a while to digest. Apart from this the technical side was quite simple and straightforward. A short description follows of what the various classes do.
The WaypointAI has several functions that are made available to be called via blueprint. This is because it’s this script’s functions that will be commanded via the UI. By far the most important data this script holds is the array of all the waypoints in the game. This gets refreshed every tick as it’s integral to the system that it’s up to date.When a waypoint is destroyed the script will remove it from the queue and shrink it so it’s ready to receive a new entry. The waypoint AI also holds a FVector of the position it was in when the game began. This is used to teleport back to it when reset is called. Additionally, there is a bool called moving which determines if the move to waypoint function will carry out or not. The main function of the script is Move to Waypoints which goes through all waypoints, finds the one that matches the AI’s current waypoint target and commands the AI to move to it while updating it to target the next waypoint.
The waypoint itself is quite simple. The blueprint version simply holds a mesh and a decal to stand out and is based on the script which simply holds a integer called WaypointOrder. This determines where in the path queue the waypoint will sit.
The waypoint AI controller inherits from the standard AIcontroller and overrides the OnMoveCompleted function. It simply tells the Way point AI to move to the next waypoint whenever it reaches its current destination. No other logic was included there.
Finally, the Waypoint Generator takes in an instance of the waypoint AI and the waypoint blueprint. It uses the later to spawn a new instance of the waypoint where a user has clicked (although the click itself is handled on the blueprint side, see diagram below). It uses the WaypointAI to create a test navigation attempt from it to the new waypoint. If it is unsuccessful it will not spawn a new waypoint. This ensures that any waypoint that is placed will work.
That covers all the C++ functionality in the project. Looking at the blueprint side we have the level blueprint which sets up the UI to be activated, the UI itself which calls C++ functions depending which buttons where called and the blueprint functionality of the Waypoint Generator. This includes keeping the generator at mouse location (as that location is used to spawn the new waypoints) and detecting a user’s mouse input.
This project first underwent a significant planning phase. During it, may things changed about the project but what emerged proved to be a solid guideline for development. In order to meet the spirit of the assignment all the functionality was made using blueprints. After this was achieved core systems were converted to C++ and any UI/Designer facing functionalities were left as blueprints as they were not considered core elements. Most C++ scripts had blueprints that inherited from them and acted as instances of that class. They could then be placed within the game world which in turn simplified a lot of the interactions. What follows is a visual representation on how the blueprint part of the project interacted with the C++ part of the project.
As you can see the only major blueprint functionalities lie within the user Interface and the WaypointGenerator’s control of mouse input. One element not included here is the LevelBlueprint which sets up the UI widget.
The ideal continuation of the project would be to expand the commands available to a player so they could “play by proxy”. An example follows:
The player inputs commands in a 2D console located in their spaceship. This in turn will control the movement and actions of the vehicle the player is located in. Actions the player could input are:
Basic Movement (Moves Ship).
Evasion (Attempts to dodge enemy fire).
Flanking Maneuverer (Attempts to move behind enemy ship)
Fire Torpedoes (Slow moving projectile that does a large amount of damage).
Fire Laser (Fast moving projectile that does a small amount of damage).
This, coupled with a turn based system could be the basis for an interesting game.
Essentially, the player must set up a series of actions while trying to figure out what the enemies will do. When all actions are inputted the game “plays out” what the user inputted without needing any further input. Once this is complete the player receives feedback on the situation and can proceed to inputting orders unless they have lost. Each action can be configured via the Unreal Editor. New modes can easily be added by using the mode template.
The application, while functional, fell short from the initial goal. This was due to the assumption that since the functionality had already been implemented using blueprints the conversion to C++ code would be quick. Unfortunately, locating C++ documentation was slow going as most relevant links concerned blueprint functionality and this coupled with the developers lack of knowledge using Unreal Engine meant that the process was slower than expected.
However, the initial result showed that the initial planning was sound, the waypoint system worked as described and has been set up to be easily expanded.
Overall, I’d say the project went well and was a learning experience.
Unreal Engine Programming Guide
Available from: https://docs.unrealengine.com/en-us/Programming
Peter L. Newton, Jie Feng. (2016). Unreal Engine 4 AI Programming Essentials