A* Movement Pack issue (many)

Hi, I've been having issues with the A* Pathfinder movement pack addon, there seems to be many issues with it. The worse one is that it doesn't seem to be able to pick the right nodes position... the code is just wrong and it breaks the AI behavior from the very first attempt. The same exact issue can be found on any movement related implementation involving A*.

Oh sorry, I'm on Unity 2021.12f , Behavior Designer 1.0.2, Movement pack 1.5.6, A* Pro 4.2.15 and I've also removed my A* Movement Pack to install the one you can download from the Opsive site to see if the issues were fixed there but they're exactly the same.
 
Last edited:

Justin

Administrator
Staff member
Can you list specifically what issues you are having? Have you tried comparing against the demo scene?
 
There's many, like wrong height for a target point, outside navmesh target point selection. Just these two are enough to break the AI completely. The first one makes the agent walk in circles trying to catch a point that's not close enough to trigger the stop task while the second one makes the agent unable to keep moving or hugging walls while the target repeatedly falls outside bounds close to a corner of a navmesh (25% chance of falling back inside the navmesh against 75% of falling outside in that case).

I could work on it and fix it myself but I've bought your addon to have a good place to start at least ^^
 

Justin

Administrator
Staff member
like wrong height for a target point,
This looks related to this thread:


I wonder if @Cheo found a solution?

outside navmesh target point selection.
This one should work with the latest version of the integration. If it doesn't can you list the steps to reproduce?
 
Raycasting may help but also finding the navmesh cell height and simply setting it to the target. I will test on this later on during the day. Also maybe have a look at how the A* algorithm finds path in the method 5 breadth-first pattern, I have a feeling that would be the right way to navigate uneven terrain https://arongranberg.com/astar/documentation/dev_4_3_43_939d7455/wander.html .

For the outside navmesh you can easily reproduce it at any time, it's not an uncommon case. Try and make a navmesh smaller than the maximum wander distance and it's going to happen all the time cause it's just not working at all for me.
 
So... if you get the nearest node to a target position isn't this always be true?

protected bool SamplePosition(Vector3 position)
{
return AstarPath.active.GetNearest(position).node.Walkable;
}
 

Justin

Administrator
Staff member
Are you using wander? It should retry a new destination if the current destination is invalid. It does not use SamplePosition since it is instead determined by if the path is valid.
 
Are you using wander? It should retry a new destination if the current destination is invalid. It does not use SamplePosition since it is instead determined by if the path is valid.
I'm using wander for this test cause it's one of the simplest locomotion behavior. I can see why you say it should retry if the destination is invalid cause I've read your code but I'm telling you it doesn't, the condition you use to check it always returns true whether your agent can reach the navmesh point or not. Also the code is not readjusting target height so the target can be anywhere in 3d space and the agent fails to meet the distance stop even if it reaches the point in xz space.
 

Justin

Administrator
Staff member
Focusing on one issue at a time, with wander I am following similar logic to number 1 from the A* documentation. In the demo scene I let the wander task run for about 10 minutes and it didn't get stuck so I wonder why yours is. Can you tell me how to reproduce it from the demo scene?
 
Just close the AI agent inside 4 walls and give it a good range and you'll see how many targets will fall outside bounds, that's the bias towards walls the A* documentation is mentioning. What's worse is that you forgot to snap the points to the nearest node so the wander node can't return a close enough state if you want it to be somewhat precise in reaching the target and that's why it gets stuck and stops running in the long run. Eventually the agent will go in an angle and the next point would be so far outside the navmesh that it will never be able to return task complete.


1625741499117.png
 

Justin

Administrator
Staff member
You're right on the bias - there really isn't one method that will work for all use cases so I could add different options to the A* wander task. Part of the issue is that the task requires the A* interface to make it ambiguous of the graph type.

I have updated the integration so wander will always move towards a valid destination. For best results if you are within an enclosed area you'll want to reduce the range so it doesn't always try to generate a point outside of the gird.
 

Cheo

Member
Hello, I had indeed managed to solve my problem but didn't take the time to write about it, sorry ! It was about the formation addon though, from what I've read it seems that you have issues with a single character ? Either way in my case Justin was right about using a raycast, it did give the rest of the squad a correct height. The Line script from the Astar integration can be modified like this :


C#:
using UnityEngine;
using BehaviorDesigner.Runtime.Tasks;
using Tooltip = BehaviorDesigner.Runtime.Tasks.TooltipAttribute;
using HelpURL = BehaviorDesigner.Runtime.Tasks.HelpURLAttribute;

namespace BehaviorDesigner.Runtime.Formations.AstarPathfindingProject.Tasks
{
    [TaskCategory("Formations/A* Pathfinding Project")]
    [TaskDescription("Arrange the group in a straight horizontal line.")]
    [TaskIcon("Assets/Behavior Designer Formations/Editor/Icons/{SkinColor}LineIcon.png")]
    [HelpURL("https://www.opsive.com/support/documentation/behavior-designer-formations-pack/")]
    public class Line : IAIAgentFormationGroup
    {
        [Tooltip("The separation between agents")]
        public SharedFloat separation = 2;
        [Tooltip("Should the formation be to the right of the leader?")]
        public SharedBool right;
        public LayerMask mask;

        protected override Vector3 TargetPosition(int index, float zLookAhead)
        {
            var leaderTransform = leader.Value == null ? transform : leader.Value.transform;

            Vector3 returnedTarget = leaderTransform.TransformPoint(separation.Value * index * (right.Value ? 1 : -1), 0, zLookAhead);

            if (leader.Value != null)
            {
                Vector3 targetCheck = returnedTarget;
                targetCheck.y += 10;
                RaycastHit hit;
                if (Physics.Raycast(targetCheck, Vector3.up * -1, out hit, 50f, mask))
                {
                    returnedTarget.y = hit.point.y;
                }
            }
            return returnedTarget;
        }

        public override void OnReset()
        {
            base.OnReset();

            separation = 2;
            right = false;
        }
        
    }
}

Not sure that using a raycast for each group member is an ideal thing to do, but to me it's a good solution so far ! Hope this was helpful.
 
Top