Smooth grid movement (script "GridMove" with tweaks), similar to Legend of Grimrock

Hello,

I’m trying to achieve a smooth grid movement.

By that I mean:

  • If you hold the walk button you will keep walking as a non-constrained movement, fixed speed.
  • No “jerkiness” in the movement.

But as soon as you release the button, the character should be smoothed to the closest rounded position (i.e. x = 1, z = 1), keeping the same speed.

I.e. similar Legend of Grimrock: http://www.youtube.com/watch?v=_HnTeQFBIq0, but a bit smoother and one that allows different speeds :stuck_out_tongue:

TRY 1: Using the common GridMove script I increased the moveSpeed.

Web build with this: https://dl.dropbox.com/u/11453596/Dev/gridNonSmooth/gridTest/gridTest.html

Problems:

  • Jerkiness
  • At high speeds, it skips some grid positions. Say you have a high speed and just want move to the cell next to you, the task turns out to be pretty hard.

TRY 2: A translate as in a “normal” movement:

movement = new Vector3(amountMove, 0f, 0f);
movement *= Time.deltaTime * moveSpeed;
transform.Translate(movement.x, 0f, 0f);

Then when releasing the button, a Vector3.Lerp to smooth to the closest rounded position.

Problems:

  • I couldn’t find the right time formula to use in Lerp to get the same speed as in Translate.
  • Grid collisions won’t be trivial, since there is a lot of mid movements

TRY 3: iTween (note: prototype code :p):

		if(Input.GetAxis("Horizontal") > 0  !isMoving)
		{
			isMoving = true;
			float travelTime = Vector3.Distance(transform.position, new Vector3(transform.position.x+1, transform.position.y, transform.position.z))/rate;
			iTween.MoveBy(gameObject,iTween.Hash("x",1.0f,"easetype","easeinoutsine","time",travelTime,"oncomplete","notmoving"));
		}
		else if(Input.GetAxis("Horizontal") < 0  !isMoving)
		{
			isMoving = true;
			float travelTime = Vector3.Distance(transform.position, new Vector3(transform.position.x-1, transform.position.y, transform.position.z))/rate;
			iTween.MoveBy(gameObject,iTween.Hash("x",-1.0f,"easetype","easeinoutsine","time",travelTime,"oncomplete","notmoving"));
		}

Problems: Same problem as Try 1.

QUESTION: I’m considering TRY 2, since the movement was the best one, except when smoothing to a cell position. What is the best way to calculate a fixed speed/time to move in small distances?

Consider I was walking with a fixed time of 0.5f per grid cell and release the movement at Vector3(1.7, 0, 0). It has to smooth to x = 2.0f.

How to calculate the time to Lerp, to be in the same speed as in the walk speed?

This kind of behavior is so common on old games that it makes me depressed that I can’t come with a solution (i.e. everyone does that, but me).

Thanks!

Thinking of working on something similar. Did you ever get this working as you desired?

For movement, I use Vector3.MoveTowards(…).

It must be called through Update() repeatedly to create nice smooth movements. What you should do is take the coordinates of the square in front of you, and move towards it when walking. When the player releases the walk key/button, continue to movetowards the center of the square the player is closest to until he’s centered.

character.position = Vector3.MoveTowards (character.position, new Vector3 (gridSquareX, gridSquareY, gridSquareZ), speed * Time.deltaTime);

Thanks - will give it a whirl.