A* Pathfinding Project

Entity only going to first node, then vibrating rapidly


#1

I’m trying to use a gridgraph with ECS entities to move units for an RTS. So far the unit I select moves to the next node, then vibrates from its last position to its intended position. Since I’m using entities I need to code a little differently. Here is my movement code, maybe someone can pin down what I’m doing wrong.

public class AStarMovementSystem : ComponentSystem
{
    GameSceneManager sceneManager;
    private Dictionary<Entity, pathData> pathLookup;
    private float nextWaypointDistance = 1;
    private float endpointStoppingDist=.1f;

    protected override void OnStartRunning()
    {
        sceneManager = GameSceneManager.instance;
        pathLookup = new Dictionary<Entity, pathData>();
    }

    

    protected override void OnUpdate()
    {
        if(Input.GetMouseButtonDown(1))
        {

            float3 ClickPoint = ExtensionMethods.ScreenToPoint(Camera.main, sceneManager.groundLayer);

            Entities.ForEach((Entity entity, ref AStarPathfindingComponent aStarComp, ref Translation translation) =>
            {
                // var path = ABPath.Construct(translation.Value, ClickPoint, OnPathComplete);
                //AstarPath.StartPath(path);
                sceneManager.seeker.StartPath(translation.Value, ClickPoint, OnPathComplete);
                aStarComp.move = true;

                void OnPathComplete(Path p)
                {
                    if (!p.error)
                    {
                        if (pathLookup.ContainsKey(entity))
                        {
                            pathLookup[entity] = new pathData { path = p, currentWaypoint = 0 };
                        }
                        else
                        {
                            pathLookup.Add(entity, new pathData { path = p, currentWaypoint = 0 });
                        }
                    }
                }
            });
        }



        float dt = Time.deltaTime;
        Entities.WithAll<SelectedComponent>().ForEach((Entity entity, ref AStarPathfindingComponent aStarComp, ref Translation translation) =>
        {
            
            if (aStarComp.move)
            {
                if (!pathLookup.ContainsKey(entity))
                    return;


                pathData pathData = pathLookup[entity];
                Path path = pathData.path;
                int currentWaypoint = pathData.currentWaypoint;
                if (path == null)
                    return;

               
                    bool reachedEndOfPath = false;
                    float distanceToWayPoint;
                    
                    while (true)
                    {
                        distanceToWayPoint = math.distance(translation.Value, path.vectorPath[currentWaypoint]);
                        if (distanceToWayPoint < nextWaypointDistance)
                        {
                            if (currentWaypoint+1 < path.vectorPath.Count)
                            {
                                currentWaypoint++;
                            }
                            else
                            {
                                //reached end of path
                                reachedEndOfPath = true;
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                     if (reachedEndOfPath && distanceToWayPoint < endpointStoppingDist)
                       aStarComp.move = false;

                    Debug.Log(currentWaypoint);
                    var speedFactor = 1f;//change this for lerp slowdown or whatnot with  (condidtion)? num:1;

                    float3 direction = math.normalize(((float3)path.vectorPath[currentWaypoint] - translation.Value));

                    float3 velocity = direction * aStarComp.moveSpeed * speedFactor*dt;

                    translation.Value += velocity;

                
            }
        });

        
    }


    public struct pathData
    {
        public Path path;
        public int currentWaypoint;
    }

Any help is appreciated!

EDIT1: Code updated to reflect more complete code. There were many issues before. I fixed the ones I saw. The same problem is still happening though. It seems that CurrentWaypoint is switching between its last node, its current node, and its next target node numbers, rather than moving on to the next node.


#2

My knowledge of ECS is near nill. So correct me if I’m wrong.

Though it came to my attention that your pathData is a struct, but in your code you make a copy
int currentWaypoint = pathData.currentWaypoint;

Then continue modifying the copy, rather than the original. Not sure if this is intended.


#3

Yup! that was my problem. I forgot to set pathlookup[entity]=pathData after I was done modifying it.