Dijkstra Integration

This week, I started with making a slight adjustment to the weight UI. Originally, I had the weight UI following the location of the player, however, I determined that a better option would be to have the UI update to follow the player camera. The advantage of this change is that if the player moves the camera, then the UI is guaranteed to be facing in a readable position, while going based off the player location did work, the UI might look slightly slanted since the player location is never the same as the camera.

Next, I reconsidered how to approach creating the graphs to make them more designer- and pathfinding-friendly. I decided it would be best to revert to my BP_Node concept, where each node contains information about the nodes it links to. One node will own the path that moves across, while the other node will simply reference it. When a node is selected to link to another node, it will automatically generate a new BP_Spline in between to connect the nodes, which can be adjusted to define the path. In cases where I need to traverse between two nodes without using a spline, I will either utilize the nav mesh or perform a climbing jump. This approach should resolve the issue of determining how to represent edges and nodes in a graph for Dijkstra’s algorithm within the game. The creation of the splines that link the nodes would be done in the BP_Node construction script.

However, when I attempted to generate a spline through the construction script, I discovered that Unreal does not seem to support creating actors to be added to the outliner outside of runtime. Therefore, I changed my strategy. I decided I would try to make it so the construction script would automatically set the end points to the node location instead.

In the video above, you can see two nodes connected by a spline. These actors are functioning correctly, with the spline points updating based on the BP_Node locations. However, you may notice that the other splines and nodes I attempted to attach are not working as intended. It appears that these splines are not updating their locations appropriately. As a result, I had to conduct further debugging to address the issue.

The issue with the other nodes and spline was that the spline needed to be manually extended initially. Once extended, when a node was moved, the spline would update correctly to be visually accurate. It is unclear why the manual extension was required for proper functionality, as the code technically moved the spline points correctly.

The next issue I encountered with this system was that I didn’t consider how multiple nodes should correctly reference the associated splines. This resulted from my choice of data structures, where I had two arrays for the nodes and splines, as well as two sets for the reference nodes and reference splines. To address this issue, I realized that changing these data structures to two separate maps of AActor* would not only simplify the code but also achieve the desired functionality.

Above is a video demonstration of the this functionality working as intended.

Above you can see the main functions that are used to automatically connect the splines and nodes. The SetSplinePointLocations function is called in the BP_Node construction script. So anytime an adjustment is made to the node, it will automatically update appropriately. Additionally, you can see in the code the spline point location values are updated properly, I call the RerunConstructionScript on the spline so that the spline instanced static meshes update appropriately.

The next step in the process was to ensure that the weights were displayed correctly between the C++ code and the splines. Technically, the variable I used to display the weights is valid, but I decided it would be best to have the variable reside in C++ so that I could set the default value of the weights to the maximum float. Then, I updated the weight text to represent the maximum float value as ‘inf’ for infinity. I did spend some time attempting to display the infinity symbol, but I discovered that it would require importing another font or using a sprite image. Using ‘inf’ seemed like a viable alternative that still provides a clear understanding of which edges have been set with appropriate weights.

Afterwards, I had to refactor the C++ code to function with the two node-to-spline maps so that the pathfinding algorithm would utilize the values set in Blueprint. Furthermore, the “graph” map in the AI class currently requires manually selecting all the nodes in the scene and setting their IDs, which is not an ideal approach. A better solution would be to move this map to the BP_Graph and allow the AI to select which BP_Graph to use.


What’s Next?

First, I need to address the integration issue between the pathfinding algorithm and the nodes and splines. Currently, it does not produce the expected output when I test it with manually set weights and targets. Once I resolve this issue, my next step will be to enable a single AI to navigate the path using the algorithm. Lastly, I aim to implement the capability for the AI to navigate a graph that may not have a spline for traversal connecting two nodes, such as incorporating jumping in a climbing graph or utilizing the nav mesh on the ground.