# The Projection System

***

Unreal Engines built in prediction system works great when it comes to predicting the location of an actor in the near future, based on its current velocity, direction and a set time for the prediction calculations. The only problem with it is that it does not consider changes in the environment like different height levels, which might result in the predicted location being in unreasonable spots like underneath the map.

Here the projection system comes in handy, doing some extra calculations to get the perfect location for the AI to move to. Below you will find a explanation how the most important processes of the projection system work.

<details>

<summary>First Projection</summary>

As soon as the prediction system, predicted the players location, the projection system starts the first projection. The first projection basically shoots a ray down to the ground from above the predicted location. This process is designed, so that the predicted player location is always at the ray’s center. For example, if the ray starts 25.000 units above the location, it will end 25.000 units below the predicted location.

In the first projection, the ray returns the first hit it registers on its way down. The impact point of this hit is considered as the first projection impact point. When hitting something, the first projection also needs to find out if there is the need for the second projection. In most cases, a second projection is needed if there might be more valid height levels below the first projection impact point.

To get this information, the system first checks if the hit actor is a landscape. If that’s the case, there will be no second projection since landscapes are always seen as the end of a map. If the actor is not of type landscape, the system will check if the actor possesses the “Hitable” component and if the “Ground Zero” setting is set to “true”. If the actor is not marked as ground zero, there will be a second projection. If the second projection is not needed, the system ends here, and the first impact point will be returned.

</details>

<details>

<summary>Second Projection</summary>

The second projection takes place if the hit actor of the first projection is not a landscape and is not marked as ground zero. This usually means that there are multiple height levels in this area and there is something below the first hit location.

Now in the second projection, the system is again shooting a ray down to the predicted player location, using the same principle of the first projection, making sure that the predicted player location is in the middle of the ray. The only difference is that this time the ray does not return one single hit but is returning all the hit events it encounters on its way down, as an array.

</details>

<details>

<summary>Select Projection Location</summary>

In this step, the system takes all the hits returned by the second projection and selects the best suited impact location for the AI to move to.

To find the best suited impact location the system first, gets the players ground location by firing down a ray down from the players location, returning the first impact. Now it loops trough all hits in the array and gets their impact points z value and the z value of the players ground location. By getting the difference between those values and checking if the distance is in a certain toleration zone (by default 500), the system sorts out all hit points that are too high or too low to the player’s position. This for example would make bridges above the player an invalid move location for the AI, so it would follow the player underneath the bridge and not trying to run on the bridge, while still getting a precise location projected on the ground.

After all invalid hits are filtered out, the system will run through all leftover hits again, filtering out the hit result which’s impact points z value is the closest to the player locations z value. If there are no valid hits left, it will get the first impact point and the last impact point and return the closest one as a result.

</details>

<details>

<summary>Multiple Projection Methods</summary>

To give you more flexibility on how to use the system, without having to make changes to the original code, we have added multiple projection presets that you can use for your game. To change the current projection method, you can just use the dropdown in the companion component, assigned to your instance of the companion AI.

**Simple Projection**

The first method is the simple projection. The simple projection method is more performant than the other methods but does also provide simple results. Essentially the simple projection only uses the First Projection functionality which is explained above. This means, using this projection method, the AI is not able to differentiate between multiple height levels and always returns the first thing it hits on its way down to the predicted player location. If you are having simple landscapes with only one height level and you want to save performance, this method is for you.

**Complex Projection**

The second method is the complex projection. This method was already explained in detail above. As the name suggests, this method is by far the most complicated method but does provide the best results. It gathers all hits on its way down to the predicted player location and selects the best suited option for the AI to move to. In addition, it also includes a system to detect if the detection of multiple hits is necessary, saving performance if possible.

**EQS Projection**

This method works the same way as the simple projection. The only difference is that when the first projection returns a hit, this method will run an environment query before returning the result to the AI. The EQS starts from a location, separately calculated by an EQS Context blueprint function. The EQS start location is a combination out of the players ground position and the result of the first projection (Z Value of players ground and X / Y from first projection).

The EQS then tries to find the closest navigable point from the just calculated position. Since the calculated start position is essentially just the first impact point but with the z value (height) of the player the results of the EQS should be comparable to the results of the complex projection. In addition, after testing the methods for some time, we came to the conclusion that using the EQS Projection is also more performant than the complex projection when using multiple instances of the AI (No noticeable impact on performance when using one instance or small groups of the AI).

In general, the results of the EQS projection are on the same level of quality as the results of the complex projection, sometimes even better. However, in some cases when using the EQS Projection it comes to weird behavior of the AI before the next prediction takes place. The reason for this is still unknown and I assume that it just happens sometimes when the environment at the EQS location is rather complex. Keep in mind that the “weird” behavior is not game breaking and since the prediction intervals are very short, the user might not even notice. Also, in hours of testing, this behavior was only observed one or twice and therefore is very rare.

Overall, using the EQS projection is a great way to get the best performance while still getting great results. If the EQS projection method might not work for you, you can still switch to the complex or simple projection. It is recommended to use the EQS projection, but everyone needs to find out for themselves what works best for them.

</details>

<details>

<summary>When is the Projection System used?</summary>

The projection system is used by the AI controller of the Advanced Companion AI. This means that every AI is calculating their own location. This is a great feature since it allows multiple AI instances to use different projection methods and have different settings like the offset or “For Run” distance.

Every AI Controller uses Unreal Engines prediction system to predict the player´s position in certain time intervals. The time intervals are also calculated separately for every instance of the AI by calculating the distance to the player (Pythagoras theorem) and then calculating the time the AI needs to move this distance based on its current movement speed plus a small offset. As soon as the AI reached its wanted follow distance to the player this results in the projection system generating a new location, shortly before the AI reaches the last generated location.

Now every time the AI is calculating the players location, the projection system is fired, provided with the predicted player location and all other settings it needs.

</details>

<details>

<summary>Why is the EQS not executed in a Function Library?</summary>

While the most logic of the projection system is collected in a function library, the logic for the environment query is stored in an event inside of the AI controller. This is simply because to the time of the creation of this asset, it was not possible to run environment queries inside of a function library and the only way to start this EQS from a blueprint was using an event.

When the AI predicts the players location, the projection system is fired. After the projection is done, its node returns an enumeration, stating if the EQS Projection method was used. If so, a switch calls the “Projection EQS” event and starts the environment query.

</details>

***
