- A* version: [5.4.4]
- Unity version: [6000.2.6f1]
Hi
I’m using AIPath (and AIDestinationSetter) to move my agents on a Recast Graph and I’m trying to find a way to set a maximum score/cost limit to the pathfinder.
In the example below, there is a viable path from the starting point (red square) to the target (blue square) but I don’t want my agents to find such paths when they exceed a certain distance.
Case A is what happens now, case B is what I want to happen: I want my agents to find the node closest to the target that doesn’t exceed the maximum cost.
I found a thread asking the same thing, “How to limit searched for path length” (can’t post the link) but it seems to be outdated
You can test with this a bit, maybe it helps;
using UnityEngine;
using Pathfinding;
using System.Collections.Generic;
public class LimitedRangePathfinder : MonoBehaviour
{
[Header("Settings")]
public Transform target;
[Tooltip("Max walking distance in World Units")]
public float maxDistance = 20f;
private IAstarAI ai;
private void Awake()
{
ai = GetComponent<IAstarAI>();
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
FindPathWithinLimit();
}
}
public void FindPathWithinLimit()
{
// 1. Convert World Distance to Cost
int maxCost = (int)(maxDistance * 1000f);
// 2. Create the path manually
ConstantPath cPath = ConstantPath.Construct(transform.position, maxCost, OnConstantPathComplete);
// 3. IMPORTANT FIX: Send it directly to the A* System, NOT the Seeker component.
// The Seeker component tries to automatically assign the result to the AIPath/FollowerEntity,
// which crashes because they can't "follow" a flood-fill result.
AstarPath.StartPath(cPath);
}
private void OnConstantPathComplete(Path p)
{
if (p.error) return;
ConstantPath cPath = p as ConstantPath;
List<GraphNode> reachableNodes = cPath.allNodes;
GraphNode bestNode = null;
float bestDistance = float.MaxValue;
Vector3 targetPos = target.position;
// 4. Find closest node to target in the reachable set
foreach (GraphNode node in reachableNodes)
{
Vector3 nodePos = (Vector3)node.position;
float distToTarget = Vector3.SqrMagnitude(nodePos - targetPos);
if (distToTarget < bestDistance)
{
bestDistance = distToTarget;
bestNode = node;
}
}
if (bestNode != null)
{
// 5. Now we give the AI a valid destination
// The AI will calculate a standard ABPath to this new, valid point.
ai.destination = (Vector3)bestNode.position;
ai.SearchPath();
Debug.DrawLine(transform.position, (Vector3)bestNode.position, Color.green, 2f);
}
}
}
1 Like