Now the question is "what else can I add to my NPC?" It really depends on what you want to do. Say you have a roaming NPC, and that you want your NPC to chase your player character after it "sees" it. We can do it using the method below.
First, to make things more understandable, let’s give "eyes" to our NPC. One reason to do this is to make it easier for us to know which part of our NPC capsule is actually the front. However, in some cases we can use this "eyes" object to use it as a reference for view angles and such.
The first thing you need to know is how an NPC would "see" a player. The NPC must have a direct line of sight from its "eyes" object to the player, but also it has to be within a specific vie angle. Humans have a roughly 170 degree view of the frontal part of the head, but if you don’t need your NPC to have that angle of vision; it can be lower to make it "miss" the player at some points. In this case, I’ve used a 120 degree view (60 degrees to each side).
First, create this FSM (the "Float Compare with Bools" action was downloaded from the PlayMaker Ecosystem Browser. Remember to use that feature, since you can find a lot of additional actions there):
This action works as follows: First it automatically searches for your player by tag name (you did tag your player character, didn’t you?). Then, it gets the NPC’s forward direction (this will be used in a bit), and then it gets the NPCs eyes position and (in world coordinates) so it can use a subtraction to create a vector that would go from the NPC’s eyes to the player (PlayerDirection). Then it uses the PlayerDirection vector to create a raycast from the NPC to the player. This raycast stores the hit object (the object being hit by the ray), and then it will compare it to the player to check if the hit object is the player or not (basically what this does is check if the NPC has an "omnidirectional direct line of sight" between itself and the player). If both objects match, the "isPlayer" bool is set to true. Another thing this FSM does is use a Vector3 operation to calculate the angle between the NPCs forward vector and the PlayerDirection vector, to see if it’s lower than the desired visibility angle (maxAngle). If it is, then the IsInAngle bool is activated. All these calculations are done per frame, and when both bools (IsInAngle and isPlayer) are true, the Bool Operator action sets the isInView variable to true.
Now that we have this part solved, let’s move on to make the NPC go from "roaming" to "chasing." Right now, we had created two different PlayMaker FSMs for the previous examples: one for roaming and another one for chasing. It doesn’t matter if they were created on the same object, or in separate objects. What we are going to do now is create one single FSM that combines both (we use the same goal objects we used before, when we created the "roaming" scenario).
What this FSM does is this: it sets the NPC into roaming state, but it is constantly checking the isInView bool variable from the other FSM (by using the Get FSM Bool action and then using that variable to run a Bool Test). When the isInView variable is true, it automatically launches the Chase state, setting the Agent’s destination as the Player.
If you press Play to run the game, the NPC should roam across your level until it has a direct view to the player, and, when this happens, the NPC should run directly to the player. If you make your player run around, the NPC will continue chasing the player.
We will continue exploring other things you can do with your NPCs on the next part.