A* Pathfinding Project

Finding a Suitable Destination Node


#1

Hi again! Further along with my turn-based system now, I’m having some trouble with figuring out an algorithm for the opponent AI to find a node to attack the player from. Each attack has a specific integer range that it’s able to reach. The criteria I need for a suitable node are:

  • Node must be able to create an unobstructed raycast from itself to any of the nodes the player is on (typically more than one, as explained in my previous thread)
  • The raycast’s length must be less than or equal to the specified attack’s range
  • The path distance from the opponent to the node must be as small as possible

What’s the best way of going about this? Trying to wrap my head around it is rather headache-inducing. Thanks again!


#2

Hey,

The exact requirements are definitely out of the scope of this project. However you might find some of the wander examples interesting as a starting point. You can read about them here https://arongranberg.com/astar/docs/wander.php

What also could be interesting to you is the TurnBasedAI example, can be found as one of the example scenes included with the project.

Hope that gets you on the right path!


#3

Hi

You can use the XPath class. It works like a normal path, but it has a few extra options. Among other things it has a PathEndingCondition which can be used to tell the path which nodes are valid end points of the path. We can do a linecast inside that check to get the correct result.

class RaycastEndingCondition : PathEndingCondition {
	// You may want to change this to an array
	public Vector3 raycastTarget;
	public float maxRange;

	public override bool TargetFound (PathNode node) {
		Vector3 nodePos = (Vector3)node.node.position;
		// Check range
		if (Vector3.Distance(nodePos, raycastTarget) < maxRange) {
			// Check line of sight
			if (!Physics.Raycast(nodePos, raycastTarget)) {
				return true;
			}
		}
		return false;
	}
}
public void SearchPath() {
	// If you have your own movement script
	// Try to reach the targetPosition, but stop once the ending condition is fulfilled
	var path = XPath.Construct(myPosition, targetPosition);
	path.endingCondition = new RaycastEndingCondition {
		raycastTarget = targetPosition,
		maxRange = myPosition,
	};
	var seeker = GetComponent<Seeker>();
	seeker.StartPath(path, SomeCallbackHere);

	// -----------------

	// Or, if you are using one of the built-in movement scripts
	var path = XPath.Construct(myPosition, targetPosition);
	path.endingCondition = new RaycastEndingCondition {
		raycastTarget = targetPosition,
		maxRange = myPosition,
	};
	var ai = GetComponent<IAstarAI>();
	// Disable the built-in path recalculation
	ai.canSearch = false;
	ai.SetPath(path);
}

See also https://arongranberg.com/astar/docs/callingpathfinding.html
and https://arongranberg.com/astar/docs/xpath.html