This is my first project in Unreal Engine 5. Here I created a 3rd person controller in blueprints which replicates some mechanics from the Stack o Bot project from Unreal. Also added a few new things.
Table of Contents:
This class holds the logic behind our AI Bot companion. Whenever the player spawns an Orb, our AI Bot will come and collect it.
Function returns the Orb actor if it exists. (Click to see Blueprint)
Executes 'Move' event every 3 seconds. Event checks if Orb is successfully discovered and once discovered, it moves the AI Bot to it's location.
(Click to see Blueprint)
I created a kill zone volume for the project that will respawn the player to it's last safe location on the map if the player falls from it.
Here I made a custom event 'SaveSafeLocation' to save a safe location for the player to respawn to after falling. This event checks if the player Is Walking or is standing on a surface. If the condition is True, the variable 'Safe Location' is set as the current player location and executes Delay to call the event every 2 seconds. If the condition is False, the variable assignment is skipped and execution continues from Delay.
'Respawn Player' is an function from Interface class BP_FXInterface which whenever called teleports the Bot(player) to the last 'Safe Location'.
(Click to see Blueprint)
but why interface? -> next section
Interface classes are a collection of function headers(name, parameters) which can be added to other blueprints. This allows us to declare one function and define different functionalities in blueprints which implements the interface. In simple terms, a single function call is able to perform different tasks when interacting with different blueprints.
General Benefits: Modularity, Abstraction, Scalable etc.
A major overlooked use of Interface is to communicate between blueprints without creating a hard reference to that particular asset.
Hard references: When asset A is depended upon asset B, a hard reference of asset B is created. This means when asset A will be loaded in memory, asset B alongside with it's hard references(eg: meshes, materials) will also be loaded in the memory.
Casting is a very widely used technique to access functions, variables and components of other Blueprint Actors while creating hard references and intertwined dependencies across the project.
This snippet below is from the Kill zone volume blueprint - BP_KillZZone. This contains a Box Collider which when gets overlapped by the Bot, casts to it and teleports it to a safer location (which it gets from BP_Bot event 'SaveSafeLocation').
The Size Map above on the right side displays that the Memory Size of BP_KillZZone is 157.5 MB. It also displays that BP_KillZZone (Grey Layer) contains dependency to BP_Bot (Red Layer) whose Memory Size is also 157.5 MB.
Since the chances of the player actually falling from the map are very rare, the extra 157 MB constant occupied memory is very costly. (even if the functionality was more frequent, there is no need for BP_Bot to be kept loaded in the memory). a better solution below .
In order to optimize memory performance, I created a Blueprint Interface - BP_FXInterface (originally made to trigger jetpack fx) and declared a function 'Respawn Player'. I implemented the interface in BP_Bot and defined the functionality of 'Respawn Player'. (see implementation in previous section - Save location logic) This function can now be called from anywhere
Doing this removes the hard reference for BP_Bot and frees up a lot of memory. The Size Map above displays that the memory space occupied by BP_KillZZone is reduced to just 13.4 KB compared to 157.5 MB previously.
Memory Size: a) Interface - 13.4 KB b) Casting - 157.5 MB (157500 KB)
References: a) Only to Interface b) to BP_Bot + references in it
I created a pressure based Door Mechanism with cool effects.
For this mechanism I made an Interaction component and used Event Dispatchers. This is another normally used method to avoid casting and improve memory performance. Start interaction event passes a True bool value and Stop interaction event passes a False bool value. These bool values will accordingly call events to Close and Open door in BP_Door
(Click to see Blueprint)
On object overlap with pressure plate, it calls the events of Interaction component to change Door behavior. Starts a Timeline animation to Move the plate down smoothly. Also changes the color of light on plate depending if it's pressed or not. Before closing doors and moving plate upwards, it checks if any object is currently colliding other than previous one. The Door will remain open whenever something is on the plate
(Click to see Blueprint)
(Click the Image to Zoom - Hold right mouse button to navigate)
Gets BP_InteractionComponent by class and then binds the OnInteract Custom event to event dispatcher OnInteract. Depending on the bool Value from dispatcher, it calls custom events - Open Door, Close Door.
(Click to see Blueprint)
Plays Timeline animation according to the events that moves the left and right gates. Also animates the color of the Light in door depending if its open or close.
This class contains the Player Movement logic with the Enhanced Input System
(this is not included inside BP_Bot[player])
Gets Yaw and takes the Forward Vector from it's rotator as movement direction.
(Click to see Blueprint)
Gets Yaw and takes the Forward Vector from it's rotator as movement direction.
(Click to see Blueprint)
Adds Yaw and Pitch Input to the Pawn
(Click to see Blueprint)
Spawns Orb (for AI Bot to collect) at the player's location only if the player is walking and not flying or jumping.
(Click to see Blueprint)
My player controller was incomplete without a dedicated walk toggle button.
(I love walking in games).
(See implementation below)
Implementation:
Each button press toggles to play or reverse play the Timeline 'SpeedTrans'. Timeline is a time based animation node. SpeedTrans increases/decreases float value Speed overtime. That value serves as the Aplha for our lerp function which linearly interpolates between 2 values based on the Aplha.
I created an Animation Blendspace which blends between walking and running animations according to speed. This saved a lot of time because I just had to change the speed and it would blend automatically between animations.
(Walk toggle is only for keyboard as Controller joysticks have dead zones and scale to control player speed).
Event Graph
Toggle JetPack(function)
Update JetPack(function)
(Click to see Blueprint)
Event Graph (Click to see Blueprint)
Based on the movement mode, the player does a Jump when walking and when in air, Jetpack can be activated. Jetpack resets when player lands.
Toggle JetPack (Click to see Blueprint)
This Blueprint Toggles the Jetpack functionality on or off. It Resets the Jetpack when the player lands setting back the Thruster Time (how long the player can fly) to it's default value - 2. It gives more Air Control to the player while the Jetpack is active. Based on the Air Control values, Interface functions are called.
Interfaces used to avoid casting and reduce memory cost.
(Click the Image to Zoom - Hold right mouse button to navigate)
Interface in BP_Bot - to activate or deactivate FX and SFX for Jetpack
AnimBP - Updates for state machine transitions
Cached Ground Locomotion for further use. (Click to see Blueprint)
Sets necesaary values to variables for State Machines. (Click to see Blueprint)
Used Blendspace for Walk - Run - Lean Left - Lean Right. Speed and Clean is calculated. (Click to see Blueprint)
Used Blendspace for Walk - Run - Lean Left - Lean Right. Speed and Clean is calculated. (Click to see Blueprint)