0
\$\begingroup\$

I am using the arongranberg A* path finding project to create way points for one enemy to follow the player. However, the enemy vibrates back and forward by about 0.1 - 0.2 unit distance when moving. I have done a lot of research regarding this problem in the past few days but to no avail I could not find a solution that solves it. This is link to a gif to show what I mean.

I have tried,

changing Application.targetFrameRate = 30;

changing fixed update to update and vice versa;

using rigidbody2d and turn interpolate on plus using velocity to move;

turning iskinematic on and off;

using translate to move.

none of the above solution works. Below is the script I have for my enemy. Any advice would be appreciated.

    using UnityEngine;
    using System.Collections;
    //Note this line, if it is left out, the script won't know that the class 'Path' exists and it will throw compiler errors
    //This line should always be present at the top of scripts which use pathfinding
    using Pathfinding;

public class AstarAI : MonoBehaviour
{
    //The point to move to
    public Transform target;

    private Seeker seeker;

    //The calculated path
    public Path path;

    //The AI's speed per second
    public float speed = 200;

    //The max distance from the AI to a waypoint for it to continue to the next waypoint
    public float nextWaypointDistance = 0.02f;

    //The waypoint we are currently moving towards
    private int currentWaypoint = 0;

    Rigidbody2D rb;

    public void Start ()
    {
        rb = this.GetComponent<Rigidbody2D> ();
        seeker = GetComponent<Seeker>();

        //Start a new path to the targetPosition, return the result to the OnPathComplete function
        seeker.StartPath( transform.position, target.position, OnPathComplete );
    }

    public void GoToNewTarget(Transform newTarget) {
        //path = null;
        currentWaypoint = 0;
        nextWaypointDistance = 0.02f;
        target = newTarget;
        seeker = GetComponent<Seeker>();
        seeker.StartPath( transform.position, target.position, OnPathComplete );
    }

    public void OnPathComplete ( Path p )
    {
        Debug.Log( "Yay, we got a path back. Did it have an error? " + p.error );
        if (!p.error)
        {
            path = p;
            //Reset the waypoint counter
            currentWaypoint = 0;
        }
    }

    public void Update ()
    {
        if (path == null)
        {
            //We have no path to move after yet
            return;
        }

        if (currentWaypoint >= path.vectorPath.Count)
        {
            Debug.Log( "End Of Path Reached" );
            return;
        }

        //this.GetComponent<Rigidbody2D> ().MovePosition (path.vectorPath[currentWaypoint]);
        //Debug.Log (path.vectorPath[currentWaypoint]);
        //Direction to the next waypoint
        Vector3 dir = ( path.vectorPath[ currentWaypoint ] - transform.position ).normalized;
        //GetComponent<Rigidbody2D> ().velocity = new Vector2 (dir.x * 3, dir.y * 3);
        //Vector3.MoveTowards(transform.position, path.vectorPath[ currentWaypoint ], 2*Time.fixedDeltaTime);
        dir *= speed* Time.deltaTime;
        rb.velocity = dir;
        //this.gameObject.transform.Translate( dir );

        //Check if we are close enough to the next waypoint
        //If we are, proceed to follow the next waypoint    
        if (Vector3.Distance (transform.position, path.vectorPath [currentWaypoint]) < nextWaypointDistance) {
            currentWaypoint++;
            return;
        } 
    }
}
\$\endgroup\$
  • \$\begingroup\$ I think the glitch is in your currentWaypoint. My suggestion is to keep previous dir in everyframe, and where you find normalized direction change, make currentWaypoint =0 or no change in currentWaypoint instead of currentWaypoint++ \$\endgroup\$ – Hamza Hasan Feb 25 '16 at 20:36
  • \$\begingroup\$ We previously solves a similar issue by using a look-ahead (skipping the first waypoint since it should be close) and using obstacle avoidance to avoid walls/round corners. Unfamiliar with unity so I'm not sure how it would appply to your situation \$\endgroup\$ – Niels Feb 26 '16 at 12:21
1
\$\begingroup\$

What is most likely happening is you are calling GoToNewTarget before the enemy has finished the path it is currently on (which seems to be the case from the gif).

This is an issue because the path finding library takes some time to find a new path, and in that time the enemy has traveled further down the existing path. When the new path is found, it will start at a point behind the enemy's position (where the enemy was when seeker.StartPath was called), and so the enemy will move backwards to the start of the new path.

To fix this, you can move the next waypoint check to before the movement, and put it in a while loop to make sure you are up to the right waypoint whenever you go to move.

|improve this answer|||||
\$\endgroup\$
-1
\$\begingroup\$

If you are using a rigid body, then freeze the rotation and position under the rigid body constraints. This worked for me.

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ Except for the part where freezing the rigidbody position prevents the object from moving. Doesnt work very well with an enemy that is suppose to follow the player \$\endgroup\$ – Gnemlock Sep 12 '16 at 10:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.