How to set an unreachable point for ai.destination so that pathfinding can stop

How to set an unreachable point for ai.destination so that pathfinding can stop. Currently, the default setting automatically searches for a nearby point, which causes the FSM to think it has correctly reached the intended location and then executes the subsequent actions.

For example, when walking over to open a treasure chest, the character will collide with a wall and then activate the safety mechanism.

I’m using this MoveToAction script

    [System.Serializable]
    public class MoveToAction : InteractableAction
    {
        public Transform currnTransform;
        public Transform destination;
        public bool useRotation;
        public bool waitUntilReached;
        public float offsetDistance = 1f; // 偏移距离


        public override IEnumerator<CoroutineAction> Execute(IAstarAI ai)
        {
            var dest = destination.position;
            {
                if (useRotation)
                    Debug.LogError("useRotation is only supported for FollowerEntity agents", ai as MonoBehaviour);
                currnTransform = GameObject.FindGameObjectWithTag("PlayerList").transform.GetChild(0);

                // 设置新的目标位置
                ai.destination = dest;
            }

            if (waitUntilReached)
            {
                if (ai is AIBase || ai is AILerp)
                {
                    // Only the FollowerEntity component is good enough to set the reachedDestination property to false immediately.
                    // The other movement scripts need to wait for the new path to be available, which is somewhat annoying.
                    ai.SearchPath();
                    while (ai.pathPending) yield return CoroutineAction.Tick;
                }

                var modifiedAIPathType = ai.GetType().Assembly.GetType("ModifiedAIPath");
                if (modifiedAIPathType != null && ai.GetType() == modifiedAIPathType)
                {
                    var methodInfo = modifiedAIPathType.GetMethod("SearchPath", new[] { typeof(float) });
                    if (methodInfo != null)
                    {
                        var searchPath = methodInfo.Invoke(ai, new object[] { offsetDistance });
                        if (searchPath != null)
                        {
                            // Ensure the return value is cast to the appropriate type (if necessary)
                            dest = (Vector3)searchPath; // Assuming the return type is Vector3
                            ai.destination = dest;
                        }
                    }
                }

                while (!ai.reachedDestination)
                {
                    if (ai.destination != dest)
                    {
                        // Something else must have changed the destination
                        ai.destination = dest;
                    }

                    if (ai.reachedEndOfPath)
                    {
                        // We have reached the end of the path, but not the destination
                        // This must mean that we cannot get any closer
                        // TODO: More accurate 'cannot move forwards' check
                        Debug.Log(ai.endOfPath + " " + ai.reachedEndOfPath + ai.position);
                        Debug.Log("Cannot move forwards, cancelling movement...");
                        yield return CoroutineAction.Cancel;
                    }

                    yield return CoroutineAction.Tick;
                }
            }
        }

If your goal is to make your agent stop, you can set their destination to their current position? If you want to “pause” their position you can use isStopped. From the documentation:

Gets or sets if the agent should stop moving.

If this is set to true the agent will immediately start to slow down as quickly as it can to come to a full stop. The agent will still react to local avoidance and gravity (if applicable), but it will not try to move in any particular direction.

The current path of the agent will not be cleared, so when this is set to false again the agent will continue moving along the previous path.

This is a purely user-controlled parameter, so for example it is not set automatically when the agent stops moving because it has reached the target. Use reachedEndOfPath for that.

If this property is set to true while the agent is traversing an off-mesh link (RichAI script only), then the agent will continue traversing the link and stop once it has completed it.

Note

This is not the same as the canMove setting which some movement scripts have. The canMove setting disables movement calculations completely (which among other things makes it not be affected by local avoidance or gravity). For the AILerp movement script which doesn’t use gravity or local avoidance anyway changing this property is very similar to changing canMove.

The steeringTarget property will continue to indicate the point which the agent would move towards if it would not be stopped.

Hi

You can adjust the distance limit that it searches using A* Inspector → Settings → Max Nearest Node Distance.

If your script is checking reachedDestination, then it should only complete that if the destination is actually reached (within some distance threshold). reachedEndOfPath may complete anyway, though.

“If the start point of a path is not walkable, how can I stop this pathfinding and set reachedEndOfPath to false?”

I don’t need to find the nearest path. I’m really looking forward to your answer. Thx!

Path.path holds the list as a series of Nodes, of which you can call myPath.path[0] to get the first and check if Walkable is true. From there you call ai.SetPath(null) to stop the agent in it’s tracks.

From the documentation on SetPath:

If you pass null as a parameter then the current path will be cleared and the agent will stop moving. Note than unless you have also disabled canSearch then the agent will soon recalculate its path and start moving again.