Hello,
I’m simply trying to move bodies around smoothly in a constant speed, but I’m getting flickering; looks like it keeps freezing/slowing down while moving.
I’m using the A* Pathfinding Project and navigating each waypoint, so I can’t just use Lerp/Translate the direction of a key pressed and stop moving when the key is up for instance. I need to go through each waypoint (which I managed).
But the problem is: even if I just put manually to go from point A to point B I still get the flickering, even in straight lines.
So far I tried 3 approaches:
- MoveTowards: this is the one that is working the better so far, but still flickers.
- Lerp: the body “freezes” in position a LOT.
- Translate: looks like the smoother one, but then I didn’t manage to detect when it reaches a waypoint. Sometimes it detects proximity with a waypoint and sometimes it doesnt. So most of the times it keeps moving indefinetely in a direction.
Final question is: How to move without flickering with a constant speed?
CODE/PLAYER:
Web Player to test each approach (middle click anywhere to place a destination point and the target will move; and the top buttons can change the movement approach): https://dl.dropboxusercontent.com/u/11453596/Unity/MovementTypes/MovementTypes.html
Code for each approach:
MOVE TOWARDS:
if(canMove)
{
Vector3 currentPosition = t.position;
List<Vector3> vPath = path.vectorPath;
if(path != null (currentWaypoint == -1 || currentPosition == activeTarget))
{
int prevWaypointIdx = currentWaypoint;
currentWaypoint++;
if(currentWaypoint == 0) currentWaypoint = 1;
if (currentWaypoint < path.vectorPath.Count)
{
activeDirection = path.vectorPath[currentWaypoint] - t.position;
activeDirection.z = 0;
activeDirection.Normalize();
activeTarget = path.vectorPath[currentWaypoint];
}
else
{
canMove = false;
}
}
if(canMove)
{
t.position = Vector3.MoveTowards(currentPosition, activeTarget, speed * Time.deltaTime);
}
}
}
LERP:
protected float XZSqrMagnitude (Vector3 a, Vector3 b) {
float dx = b.x-a.x;
float dy = b.y-a.y;
return dx*dx + dy*dy;
}
if(canMove)
{
Vector3 currentPosition = t.position;
List<Vector3> vPath = path.vectorPath;
if(path != null (moveTime == 0f || moveTime >= 1f))
{
int prevWaypointIdx = currentWaypoint;
currentWaypoint++;
if(currentWaypoint == 0) currentWaypoint = 1;
if (currentWaypoint < path.vectorPath.Count)
{
activeDirection = path.vectorPath[currentWaypoint] - t.position;
activeDirection.z = 0;
activeDirection.Normalize();
activeTarget = path.vectorPath[currentWaypoint];
}
else
{
canMove = false;
}
moveTime = 0f;
}
if(canMove)
{
if(moveTime <= 1f)
{
moveTime += Time.deltaTime * (speed/gridSize) * 0.7071f;
t.position = Vector3.Lerp(currentPosition, activeTarget, moveTime);
}
if(XZSqrMagnitude(t.position, finalTarget) < 0.0000001f)
{
Debug.Log (XZSqrMagnitude(t.position, finalTarget));
Debug.Log (" Move Completed ");
canMove = false;
}
}
}
TRANSLATE:
if(canMove)
{
Vector3 currentPosition = t.position;
List<Vector3> vPath = path.vectorPath;
bool moveNext = false;
// Sometimes it correctly detects proximity, but most of the time this is ignored
if(XZSqrMagnitude(t.position, activeTarget) < 0.0001f)
moveNext = true;
if(path != null (moveNext || currentWaypoint == -1 || currentPosition == activeTarget))
{
int prevWaypointIdx = currentWaypoint;
currentWaypoint++;
if(currentWaypoint == 0) currentWaypoint = 1;
if (currentWaypoint < path.vectorPath.Count)
{
activeDirection = path.vectorPath[currentWaypoint] - t.position;
activeDirection.z = 0;
activeDirection.Normalize();
activeTarget = path.vectorPath[currentWaypoint];
}
else
{
canMove = false;
}
}
if(canMove)
{
t.Translate(activeDirection * speed * Time.deltaTime, Space.World);
}
}