Confusion with Aron Granberg's A* Pathfinding

Hello people :slight_smile:

I’m currently working on a turn-based project which requires pathfinding based on a hexagon grid, and have been looking into Aron Granberg’s A* Pathfinding packages (which are extremely powerful from what I’ve seen so far).

But I’ve come up against a snag… I can’t work out exactly how to make the unit (or game object, that is) move exactly along the path, consisting of a series of waypoints or ‘nodes,’ each in the centre of each hexagon which make up the grid.

What happens at the moment is that the unit travels in a straight line toward a waypoint, but it has a radius around it which searches for the waypoint to confirm the ‘waypoint reached.’ When this radius (say a radius of 1) touches the waypoint, the unit instantly starts moving toward the next waypoint, effectively cutting the corner of the turn. Scale-wise, think of the unit itself being say 0.2 radius, and the detection radius being about 1. This may seem ok in normal navigation, but it doesn’t suit the hex-grid-based pathfinding I’m trying to accomplish.

Here’s the code I have came up with so far…

using UnityEngine;
using System.Collections;
using Pathfinding;

public class AstarAI : MonoBehaviour {
	public Vector3 targetPosition;
	public GameObject targetNode;
	
	private Seeker seeker;
	private CharacterController controller;
	
	//the calculated path
	public Path path;
	
	//the AI's speed per second
	public float speed = 100;
	
	//the max distance from the AI to a waypoint for it to continue to the next waypoint
	public float nextWaypointDistance = 1;
	
	//the waypoint we are currently moving towards
	private int currentWaypoint = 0;
	
	public GameObject clickedObject;
	
	public Ray ray;
	public RaycastHit hit;
	
	public void Start () {
		controller = GetComponent<CharacterController>();
	}
	
	public void MyCompleteFunction (Path p) {
		Debug.Log ("Yay we got a path back! Is there an error?" + p.error);
		if (!p.error) {
			path = p;
			//reset the waypoint counter
			currentWaypoint = 0;
		}
	}
	
	public void Update () {
		//Find the closest node to this GameObject's position
		Node node = AstarPath.active.GetNearest (transform.position);
		ray = Camera.main.ScreenPointToRay(Input.mousePosition);
		if (Physics.Raycast(ray, out hit, 100)) {
			targetPosition = AstarPath.active.GetNearest (hit.point);
			Debug.DrawLine(ray.origin, hit.point);
			if (node.walkable) {
				Debug.Log ("this is walkable" + node.position);
				MoveOnThePath();
			}
		}

		if (path == null) {
			//we have no path to move toward yet
			return;
		}
		
		if (currentWaypoint >= path.vectorPath.Length) {
			Debug.Log ("End of path reached");
			return;
		}
		
		//direction to the next waypoint
		Vector3 dir = (path.vectorPath[currentWaypoint] - transform.position).normalized;
		dir *= speed * Time.deltaTime;
		controller.SimpleMove (dir);
		
		if (Vector3.Distance (transform.position, path.vectorPath[currentWaypoint]) < nextWaypointDistance) {
				currentWaypoint++;
				return;
			}
	}
	
	public void MoveOnThePath () {
		Seeker seeker = GetComponent<Seeker>();
		controller = GetComponent<CharacterController>();
		seeker.StartPath (transform.position, targetPosition, MyCompleteFunction);
	}
}

Any help would be greatly appreciated!

Thanks, Aaron :slight_smile:

I actually had this problem too: if the radius to check for a reached waypoint was too small (my case was somewhere around 1.8), the seeker wouldn’t move at all. I was losing my mind over it for a couple of days, until I noticed that the seeker object’s transform.position.z was 1.8. It was quite easy to overlook this since it didn’t affect anything else and it wasn’t visible in the 2D viewport.