- Home /
GridMove-based movement 'jerkiness'
G'day lads, I've written the core gameplay of a "Snake" game (as seen on every terrible old phone you ever owned), but this time modified Eric5h6's GridMove script to create actual Point A - Point B movement. The game works, the snake grows when picking up food etc, but there's an almost - almost - impercetible jerkiness between movement cycles.
At first I thought it was because my "Snake Head" is passing Input coordinates (Vector2) to the "Snake Body" segments at the end of each movement cycle, but even after commenting this out there's the tiniest of "jerks" when moving.
I've stripped it down to the bare essentials of movement, in the hopes that somebody can spot what's wrong here, as I've all but exhausted every solution I can muster.
Anyway, here's the code:
private var desiredBearing: String = 'South';
private var currentBearing: String;
var moveSpeed : float = 2.0;
var MyCamera : Transform;
var gridSize : int = 1;
enum Orientation {Horizontal, Vertical}
var gridOrientation = Orientation.Horizontal;
var allowDiagonals = false;
var correctDiagonalSpeed = true;
private var input = Vector2(0,-1);
var myTransform: Transform;
function Awake() {
myTransform = transform;
}
function Start () {
var myTransform = transform;
var startPosition : Vector3;
var endPosition : Vector3;
var t : float;
var tx : float;
while (true) {
while (input == Vector2.zero) {
GetAxes();
tx = 0.0;
yield;
}
transform.forward = Vector3.Normalize(new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")));
startPosition = myTransform.position;
endPosition = gridOrientation == Orientation.Horizontal?
Vector3(Mathf.Round(myTransform.position.x), 0.0, Mathf.Round(myTransform.position.z)) +
Vector3(System.Math.Sign(input.x)*gridSize, 0.0, System.Math.Sign(input.y)*gridSize)
:
Vector3(Mathf.Round(myTransform.position.x), Mathf.Round(myTransform.position.y), 0.0) +
Vector3(System.Math.Sign(input.x)*gridSize, System.Math.Sign(input.y)*gridSize, 0.0);
t = tx;
while (t < 1.0) {
t += Time.deltaTime * (moveSpeed/gridSize) * (correctDiagonalSpeed && input.x != 0.0 && input.y != 0.0? .7071 : 1.0);
myTransform.position = Vector3.Lerp(startPosition, endPosition, t);
yield;
}
tx = t - 1.0;
if(ready == true){
Grow();
}
GetAxes();
}
}
function Update () {
var horizontalMovement = Input.GetAxis("Horizontal");
var verticalMovement = Input.GetAxis("Vertical");
if (horizontalMovement > 0 && currentBearing != 'West'){
desiredBearing = 'East';
} else if (horizontalMovement < 0 && currentBearing != 'East'){
desiredBearing = 'West';
} else if (verticalMovement > 0 && currentBearing != 'South'){
desiredBearing = 'North';
} else if (verticalMovement < 0 && currentBearing != 'North'){
desiredBearing = 'South';
}
}
function GetAxes () {
input = Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
if (desiredBearing == 'East'){
currentBearing = desiredBearing;
input.x = 1;
input.y = 0;
} else if (desiredBearing == 'West'){
currentBearing = desiredBearing;
input.x = -1;
input.y = 0;
} else if (desiredBearing == 'North'){
currentBearing = desiredBearing;
input.y = 1;
input.x = 0;
} else if (desiredBearing == 'South'){
currentBearing = desiredBearing;
input.y = -1;
input.x = 0;
}
}
For what it's worth, since I'm using my own method of setting the input (and ensuring perpetual motion if the player doesn't press any buttons), I noticed that removing this line of code (below) from Start() doesn't affect anything, but leaving it in warns me that the look rotation is zero... whatever that means exactly.
transform.forward = Vector3.Normalize(new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")));
Is all your movement being done in the start function? You really should move that to just run at each update ins$$anonymous$$d of the while(true), it could be that things are being called in a weird order.
Also, a useful tool for simple smooth movement is a free library called iTween which does a lot of the heavy lifting for you in single line calls to functions. Just a thought for an alternative.
I'm not totally sure what Time.deltaTime is returning you in the middle of that coroutine - might be right, I can see why it would work. I guess this style of coding may well work, but it worries me that you have so many different states in that coroutine - perhaps one of them is consu$$anonymous$$g a frame or two and creating the "jerk" before the rest of the code gets to move things?
@shadowriffe: no, it's a coroutine. Using Update screws up the whole idea.
As for this code, there seems to a lot of weirdness added to what I did for the original, so I can't really parse it. For one thing, I didn't have any Update function at all, so I'm not sure what that's supposed to do.
@Eric5h5 where can I find your original? I'd love to see how that works, looks like it could be an interesting technique.
Answer by Waz · May 30, 2012 at 01:33 AM
I suspect the problem lies in the order of these lines:
while (t < 1.0) {
t += Time.deltaTime * (moveSpeed/gridSize) * (correctDiagonalSpeed && input.x != 0.0 && input.y != 0.0? .7071 : 1.0);
myTransform.position = Vector3.Lerp(startPosition, endPosition, t);
yield;
}
Try:
while (t < 1.0) {
myTransform.position = Vector3.Lerp(startPosition, endPosition, t);
yield;
t += Time.deltaTime * (moveSpeed/gridSize) * (correctDiagonalSpeed && input.x != 0.0 && input.y != 0.0? .7071 : 1.0);
}
That seems to correspond to the rest of the logic: move to the current position (including any excess tx time from last cycle), wait, move by about of time just past.
Your answer
Follow this Question
Related Questions
Unable to move Gameobject properly and smoothly to where mouse clicked , using Vector3.Lerp 1 Answer
Vector3.lerp and Mathf.pingpong not moving smoothly 3 Answers
Help with Snake like movement algorithm. 1 Answer
snake 3d movement 0 Answers
Make GameObject move in one direction continuously on key press on C# 1 Answer