Why is my enemy not moving towards the player in my A* pathfinding system?

So I’ve created a grid and A* pathfinding system that works for my player character. I have an enemy in scene and want him to move towards the player following the pathfinding system but for some reason the enemy just won’t move. I have the correct target transform set and have debugged to ensure that a list of positions has been created. If you’d be able to look at this code and figure out where I’m going wrong it would be greatly appreciated. Feel like I’m blind running around in circles.

public class EnemySkeleton : NPC
{
    [SerializeField] Transform targetTransform;

    private List<Vector3> pathList;

    private GridPosition gridPos;
    private GridPosition targetGridPos;

    private float moveSpeed = 3;
    private float rotationSpeed = 10;
    private bool toMove;

    private void Update()
    {
        gridPos = GetGridPosition();

        if (targetTransform == null)
        {
            return;
        } 
        
        if (toMove)
        {
            MoveToPlayer(targetTransform, moveSpeed, rotationSpeed);
            toMove = false;
        }

        if (targetGridPos != CharacterMovement.Instance.GetPlayerGridPosition())
        {
            toMove = true;
            targetGridPos = CharacterMovement.Instance.GetPlayerGridPosition();
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.GetComponent<CharacterMovement>() != null)
        {
            targetTransform = other.transform;
            targetGridPos = LevelGrid.Instance.GetGridPosition(targetTransform.position);
            toMove = true;
        }
    }
}


public class NPC : MonoBehaviour
{
    private const float STOPPING_DISTANCE = 0.1f;

    private GridPosition currentGridPosition;
    private GridObject currentGridObject;
    private Vector3 currentPosition;
    int currentIndex = 0;

    private void Start()
    {
        currentGridPosition = LevelGrid.Instance.GetGridPosition(transform.position);
        currentGridObject = LevelGrid.Instance.GetGridObject(currentGridPosition);

        currentPosition = LevelGrid.Instance.GetWorldPosition(currentGridPosition);
        transform.position = currentPosition;

        AddNPCToGrid();
    }

    public void MoveToPlayer(Transform target, float moveSpeed, float rotationSpeed)
    {
        GridPosition playerPosition = LevelGrid.Instance.GetGridPosition(target.position);

        List<Vector3> pathPositions = FindTilePath(playerPosition);

        if (pathPositions != null && currentIndex < pathPositions.Count - 1)
        {
            Vector3 targetPosition = pathPositions[currentIndex];
            Vector3 direction = (targetPosition - transform.position).normalized;

            transform.forward = Vector3.Lerp(transform.forward, direction, rotationSpeed * Time.deltaTime);

            Debug.Log(targetPosition.ToString());

            if (Vector3.Distance(transform.position, targetPosition) > STOPPING_DISTANCE)
            {
                transform.position += direction * moveSpeed * Time.deltaTime;
            }
            else
            {
                currentIndex++;
            }
        }
    }
    public List<Vector3> FindTilePath(GridPosition targetPosition)
    {
        GridPosition currentGridPosition = LevelGrid.Instance.GetGridPosition(transform.position);
        List<GridPosition> gridPositions = Pathfinding.Instance.FindPath(currentGridPosition, targetPosition, out int pathLength);
        List<Vector3> pathList = new List<Vector3>();

        foreach (GridPosition gridPosition in gridPositions)
        {
            pathList.Add(LevelGrid.Instance.GetWorldPosition(gridPosition));
        }
        currentIndex = 0;   
        return pathList;
    }

    public GridPosition GetGridPosition()
    {
        return LevelGrid.Instance.GetGridPosition(transform.position);
    }

    public GridObject GetGridObject()
    {
        return LevelGrid.Instance.GetGridObject(GetGridPosition());
    }

    public void AddNPCToGrid()
    {
        LevelGrid.Instance.AddNPCToGrid(this, GetGridPosition());
    }
}

You only call MoveToPlayer once and it doesn’t update again unless the target moves. Since it uses deltaTime, it causes it to only move part way to the first path index.

You should adjust some logic so that FindTilePath is only called if the target moves and call MoveToPlayer every frame if there is a target and a path. That will also allow your currentIndex to increment through the points properly. Right now it gets reset to zero every time MoveToPlayer is called because it recalculates the path and resets the currentIndex.

1 Like

Thanks a tonne, was starring at this code for too long.

1 Like