Role: | Lead-Programmer | |
Project Team: | 8 Students | |
Version: | Unreal Engine 4.23.1 | |
| ||
Tasks: | - Task packages created for other programmers | |
- Git setup and configuration (LFS) | ||
- Prototyping and developming the secret text | ||
- Prototyping and developing AI behavior | ||
- Developing and importing AI animations | ||
- Main character movement | ||
- Ambience sound | ||
- Developing of the jumpscare |
Police detective Zachariah Stigandr is searching for his missing niece. He has worked on cases involving missing children before. Children who disappeared in the woods, but now it hits his family and he is willing to do anything to find out the secret of his niece.
This project was a challenge in many ways. On the one hand, it was the first time I was a code leader, on the other hand, it was the first time I worked with the Unreal Engine. On top of that, I had to animate the enemies via motion capture.
Besides the organizational work, where I created work packages for the programmers and the repository, my core activity was to implement the functions of the NPC (non-playable character).
The enemies function as an instance that works with an NPC controller, similar to the first-person character. Parallel to this is the Behavior Tree, which contains the logic of the NPC in loud tasks, but more about that later (figure 1).
In the beginning, the Behavior Tree is loaded in the Blueprint class so that each NPC knows exactly which logic to follow (Figure 2).
Each NPC is programmed with two AIPerceptions, one for sight and one for hearing. Since the behavior tree works with blackboard conditions, the variables are set accordingly when the NPC sees or hears the player (Figure 3).
The interesting thing is that the NPC should continue to react when he has seen the player even if he steps out of his sight radius. In Pentum, the sight radius was set to 45 degrees and a sight range of 1500 units. Since the player is faster and can run out of the NPC's field of view relatively early, a so-called raycast is sent to the player to check if there is an object between the player and the NPC.
If the raycast hits an object for three seconds, the player is hidden from the NPC and the NPC goes back to its initial state of walking around or roaming (Figure 4).
The status change of the NPC always happens via a Boolean variable, which is controlled via the Behavior Tree. There are the following Boolean variables:
Variable | Meaning | |
---|---|---|
canSeePlayer | NPC can see player | |
canHearPlayer | The player is heard | |
canNotHearPlayer | The player is not heard | |
canNotSeePlayer | The player is not seen |
As already mentioned, the Behavior Tree is the logic behind each NPC. If one of the Boolean variables mentioned above is set, the Behavior Tree decides which task to run. Each branch is divided into several tasks, which are processed from left to right (Figure 5).
Let`s take a closer look at the "can`t hear branch". The branch "Can`thear Player", shows the tasks that the NPC performs when it can`t hear the player anymore (Figure 6).
The task "PlayIndividual_LostHearing" is structured like any other Blueprint in Unreal, except that it is processed as a task in the Behavior Tree. If you take a closer look at the task, every task is structured in the same way (Figure 7).
Each task starts with an "Execute Node" and is finished with a "Finish Execute" Node (outlined in red). In between is the actual task in which the program runs (yellow bordered). This task is cast directly after the Execute Node to the NPC Blueprint, which makes it possible to execute a function in it. In this case "Set Chasing". Casting to other blueprints is needed in Unreal to generally have access to functions or variables of the blueprints. Next, casting also checks which enum has been stored for the NPC so that the character-specific sound can be played (the NPC has lost the player sound). Finally, the Finish Execute Node is called which successfully finishes the task.
Next, the task "AI Clear Focus" is called. Again, you can see the Execute and Finish Node (outlined in red, Figure 8).
Then cast to the NPC controller to execute the "ClearFocus" function. This will stop the NPC from turning toward the player.
The next task is responsible for the animation of the NPC. The task named "WalkAnimation" changes the animation of the NPC to a "WalkAnimation" (Figure 9). In the following, I will not go into the Execute and Finish Node.
Here we cast again to the NPC to execute three functions, namely "Set Running", "Set Searching" and "Set Walking". The interesting thing about this task is that the NPC cast calls another cast to the Animation Blueprint, which is stored in the variable "M Animation Cast" (outlined in green). Only the Animation Blueprint has access to the three called functions.
The task "Get Random Location" is used more often in the Behavior Tree. This is because you can use the same task under different branches (Figure 10).
In this task the location of the NPC is taken and a point in a radius of 1500 units is searched. This point is stored as a vector in the variable "TargetLocation". Furthermore, the Boolean variable "canNotSeePlayer" is set to "true" and the variable "canNotHearPlayer" is set to "false". This defines the next branch in the Behavior Tree for the NPC to address.
The "Move To" task is a standard Unreal task that has been predefined. You only have to specify a vector to which the NPC should move. Here, the vector created in the previous task is specified, namely "TargetLocation" (circled in yellow, Figure 11).
The last task in the branch is the "Wait" task, this makes the NPC wait for a certain time. In this case one second (Figure 12).
The Animation Blueprint determines when which animation is executed. The special thing about Pentum was that there were three different NPC with different characteristic properties. The following characters exist:
Character | Property | |
---|---|---|
Britain | NPC with a British accent in his gait and search style. | |
Military | NPC with a strict and stiff gait. | |
Fanatic | NPC with a crazy character. |
Depending on which character was configured for the NPC, a separate state machine was executed. The state machine defines under which conditions, for example, a character moves or searches (Figure 13).
Each state machine is configured in the same way but performs its animations for each character.
In the example of the Britain State Machine, you can see the states (outlined in red), which are connected with state transitions (circled in yellow). The state transitions are Boolean variables that are controlled by the tasks in the Behavior Tree and thus the different animations are played, for example in WalkAnimation.
AI Roaming | Motion Capture | Secret Text | ||
---|---|---|---|---|
|
Link to Subversion: https://christian-brueckl.de:8443/svn/Pentum/
_________________________
Username: showcase
Password: showcase