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\$
2
  • \$\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\$ Commented Feb 25, 2016 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\$ Commented Feb 26, 2016 at 12:21

2 Answers 2

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.

\$\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.

\$\endgroup\$
1
  • \$\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\$ Commented Sep 12, 2016 at 10:03

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.