# 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;
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")));
``````

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.