Need smooth movement of cube instead of instantaneous

I am starting to learn unity by making a simple snakes and ladders game. Currently I am using 2 cubes as players. I have made the code for moving the players as per the dice throw and the snakes and ladders present on the board. But there is a problem. They move instantaneously. The Unity Javascript code that I am using is given below. Can someone suggest what to do?

//The movement actually occurs in the update() function. All others are the support functions.

EDIT:- Someone also tell me how to make this code displayed small. My post has became too big.

#pragma strict

//These are set from GUI
var p1 			: GameObject;
var p2			: GameObject;
var cube 		: GameObject;
var cubeUp 		: GameObject;
var cubeRight 	: GameObject;

//These remain Constant
private var moveRight 	: Vector3;
private var moveLeft 	: Vector3;
private var moveUp 		: Vector3;
private var moveDown 	: Vector3;

private var p1_pos : int = 1;
private var p2_pos : int = 1;
private var turn 		: int = 0;

private var moves		: float = 0.0;

//Functions to be called
function move(Left : float, Right : float, Up : float, Down : float)
{//Left Right Up Down
	if(turn ==0)
		p1.transform.Translate((moveRight * Right)+(moveLeft * Left) + (moveUp * Up) + (moveDown * Down));
	else
		p2.transform.Translate((moveRight * Right)+(moveLeft * Left) + (moveUp * Up) + (moveDown * Down));
}
function in_range(lower : int, higher : int): boolean
{
	var pos : int;
	
	if(turn ==0)
		pos = p1_pos;
	else
		pos = p2_pos;
		
	if( pos >= lower   pos <= higher)
		return true;
	else
		return false;
}
function on_snake_or_ladder(pos : int) : int
{
	switch(pos)
	{
	//Ladders	 L R U D
		case 2:
			move(0,1,1,0); return(18);
		case 11:
			move(0,0,2,0); return(31);
		case 12:
			move(1,0,1,0); return(28);
		case 22:
			move(1,0,1,0); return(40);
		case 36:
			move(3,0,3,0); return(62);
		case 41:
			move(0,1,1,0); return(59);
		case 46:
			move(0,0,1,0); return(55);
		case 70:
			move(3,0,3,0); return(94);
		case 77:
			move(0,0,1,0); return(84);
		case 85:
			move(1,0,1,0); return(97);
			
		//Snakes L R U D
		case 21:
			move(0,5,0,1);  return(15);
		case 23:
			move(0,3,0,2); return(6);
		case 29:
			move(3,0,0,1); return(15);
		case 35:
			move(3,0,0,2); return(18);
		case 47:
			move(0,2,0,1); return(32);
		case 52:
			move(6,0,0,2); return(38);
		case 71:
			move(3,0,0,4); return(34);
		case 82:
			move(0,0,0,3); return(59);
		case 95:
			move(3,0,0,2); return(78);
		case 99:
			move(0,0,0,2); return(79); 
		default:				
			break;
	}
	return(-1);
}
//Functions to be called END HERE

function Start()
{	
	var distance : Vector3 = p2.transform.position - p1.transform.position;

	moveRight = (cubeRight.transform.position - cube.transform.position);
	moveLeft  = - moveRight ;
	moveUp    = (cubeUp.transform.position - cube.transform.position);
	moveDown  = - moveUp;
	
	p1.transform.Translate(cube.transform.position - p1.transform.position);
	p2.transform.position = p1.transform.position;
	p2.transform.Translate(distance);
}

function OnGUI () 
{	
	if(moves == 0.0)
	{
		if(GUI.Button(Rect (20,70,80,40), "Throw\n Dice"))
		{
			var moves_int : int;
			moves_int = Random.Range(1,6);
			moves =  moves_int;
		}
	}
}

function Update()
{
	if(moves > 0) //Executes if any plane is yet to move
	{
		if(p1_pos < 100  turn == 0)
		{
			if(in_range(1,9) || in_range(21,29) || in_range(41,49) || in_range(61,69) || in_range(81,89))
				move(0,1,0,0);
			else if(in_range(11,19) || in_range(31,39) || in_range(51,59) || in_range(71,79) || in_range(91,99))
				move(1,0,0,0);
			else if((p1_pos % 10 == 0)(p1_pos != 100))
				move(0,0,1,0);
			
			p1_pos = p1_pos + 1;
		}
		else if(p2_pos < 100  turn == 1)
		{
			if(in_range(1,9) || in_range(21,29) || in_range(41,49) || in_range(61,69) || in_range(81,89))
				move(0,1,0,0);
			else if(in_range(11,19) || in_range(31,39) || in_range(51,59) || in_range(71,79) || in_range(91,99))
				move(1,0,0,0);
			else if((p2_pos % 10 == 0)(p2_pos != 100))
				move(0,0,1,0);
			
			p2_pos = p2_pos + 1;
		}
		moves = moves - 1;
		
		if(moves == 0) //If for Player done moving 
		{
		//This if executes when player has done moving his turn.
		//After that snake bites or ladder is climbed
			var returned_pos : int;
			
			if(turn == 0)
			{
				returned_pos = on_snake_or_ladder(p1_pos);
				if(returned_pos != -1)
				{
					p1_pos = returned_pos;
				}
			}
			else
			{
				returned_pos = on_snake_or_ladder(p2_pos);
				if(returned_pos != -1)
				{
					p2_pos = returned_pos;
				}
			}
						
			turn = (turn + 1) % 2;
		}//If for Player done moving ENDS here
	}
}//Update() function ENDS here

I would suggest you to multiply the Vector3 inside Translate for Time.deltaTime. It’s the time between an Update and another. And read the references about it in the Docs.

I’m sure you can decrease your script’s length with some built-in functions as well.

You mean changing the argument of translate in the move function? I multiplied it with Time.deltaTime but there was no change.

This:

p1.transform.Translate( ((moveRight * Right)+(moveLeft * Left) + (moveUp * Up) + (moveDown * Down)) * Time.deltaTime);

Change all the float directions to 1 to see what am I talking about.

The players are moving only a very little distance now. Much lesser than the distance that I actually want them to move.
I want them to move the distance given by the vectors but such that their movement is visible.

Now is up to you tweak your speed till it’s enough. But the deltaTime part is very important for smoothness.

I have tried but there is no smoothness in the movement. It is even now instantaneous.

I think I need to explain my code better.

The way I understand about Unity’s working is that the Update() function works every frame. So, the move() function is being called from the Update() function which is leading to near instantaneous movements. So, if I make any changes in the move function it will not make any difference in the speed which is actually being determined by the Update() function. I need some kind of delay for this. Any suggestions?

@Westerbly
Wouldn’t multiplying the arguments with Time.DeltaTime just change the Vector3 without adding any time delay?

You might consider using a “blocking” Coroutine - while the routine is running, don’t trigger it again, but let it run independently of Update. (“blocking” is the wrong terminology but i’m not sure exactly what word is appropriate :p)

private var moving : boolean = false;
var speed : float = 1.0; // 1.0 = one second, 0.5 = two seconds, 0.25 = four seconds

function MoveTo( targetPosition : Vector3 ) {
  var ratio : float = 0.0;
  var startPosition : Vector3 = transform.position;
  if ( moving ) return;
  moving = true;
  while ( ratio < 1.0 ) {
    ratio = Mathf.Min( 1.0, ratio + Time.deltaTime * speed );
    transform.position = Vector3.Lerp( startPosition, targetPosition, ratio );
    yield;
  }
  moving = false;
}

...

if ( !moving ) {
  StartCoroutine( MoveTo( transform.position + Vector3.up * 10 ) );
}

Use a coroutine, such as MoveObject.

–Eric

Found the solution.
Firstly tried to make the player move in more steps than usual using floating point numbers. But there is some error with floating point number’s accuracy so changed every float to integer. Then multiplied the number of moves by 10 and made each movement (1/10) times the initial. Working like the way I wanted.

Thanks to all for the help. Thank you.

I will now be trying to make classes for the 2 players. That will make my code shorter.

Modified Code is:–

#pragma strict

//These are set from GUI
var p1 			: GameObject;
var p2			: GameObject;
var cube 		: GameObject;
var cubeUp 		: GameObject;
var cubeRight 	: GameObject;

//These remain Constant
private var moveRight 	: Vector3;
private var moveLeft 	: Vector3;
private var moveUp 		: Vector3;
private var moveDown 	: Vector3;

//These change according to player's position
private var p1_pos 	: int = 1;
private var p2_pos 	: int = 1;

//This decides whose turn
private var turn	: int = 0;
//This is for current moves
private var moves	: int = 0;
private var moves_done : int = 0;

//Functions to be called
function move(Left : int, Right : int, Up : int, Down : int)
{	//L R U D
	//Automatically decides which player to move according to turn
	if(turn ==0)
		p1.transform.Translate((moveRight * Right)+(moveLeft * Left) + (moveUp * Up) + (moveDown * Down));
	else
		p2.transform.Translate((moveRight * Right)+(moveLeft * Left) + (moveUp * Up) + (moveDown * Down));
}

function move_scaled(Left : int, Right : int, Up : int, Down : int)
{	//L R U D
	//Automatically decides which player to move according to turn
	if(turn ==0)
		p1.transform.Translate(((moveRight * Right)+(moveLeft * Left) + (moveUp * Up) + (moveDown * Down)) * 0.1);
	else
		p2.transform.Translate(((moveRight * Right)+(moveLeft * Left) + (moveUp * Up) + (moveDown * Down)) * 0.1);
}

function in_range(lower : int, higher : int): boolean
{//Checks whether 2 numbers in a range
	var pos : int;
	
	if(turn ==0)
		pos = p1_pos;
	else
		pos = p2_pos;
		
	if( pos >= lower   pos <= higher)
		return true;
	else
		return false;
}
function on_snake_or_ladder(pos : int) : int
{
	switch(pos)
	{
	//Ladders	 L R U D
		case 2:
			move(0,1,1,0); return(18);
		case 11:
			move(0,0,2,0); return(31);
		case 12:
			move(1,0,1,0); return(28);
		case 22:
			move(1,0,1,0); return(40);
		case 36:
			move(3,0,3,0); return(62);
		case 41:
			move(0,1,1,0); return(59);
		case 46:
			move(0,0,1,0); return(55);
		case 70:
			move(3,0,3,0); return(94);
		case 77:
			move(0,0,1,0); return(84);
		case 85:
			move(1,0,1,0); return(97);
			
		//Snakes L R U D
		case 21:
			move(0,5,0,1);  return(15);
		case 23:
			move(0,3,0,2); return(6);
		case 29:
			move(3,0,0,1); return(15);
		case 35:
			move(3,0,0,2); return(18);
		case 47:
			move(0,2,0,1); return(32);
		case 52:
			move(6,0,0,2); return(38);
		case 71:
			move(3,0,0,4); return(34);
		case 82:
			move(0,0,0,3); return(59);
		case 95:
			move(3,0,0,2); return(78);
		case 99:
			move(0,0,0,2); return(79); 
		default:				
			break;
	}
	return(-1);
}
//Functions to be called END HERE

function Start()
{	
	var distance : Vector3 = p2.transform.position - p1.transform.position;

	moveRight = (cubeRight.transform.position - cube.transform.position);
	moveLeft  = - moveRight ;
	moveUp    = (cubeUp.transform.position - cube.transform.position);
	moveDown  = - moveUp;
	
	p1.transform.Translate(cube.transform.position - p1.transform.position);
	p2.transform.position = p1.transform.position;
	p2.transform.Translate(distance);
}

function OnGUI () 
{	
	if(moves == 0)
	{
		if(GUI.Button(Rect (20,70,80,40), "Throw\n Dice"))
		{
			moves = Random.Range(1,6);
			moves = moves * 10;
			moves_done = 0;
		}
	}
}

function Update()
{
	if(moves > 0) //Executes if any player is yet to move
	{
		if(p1_pos < 100  turn == 0)
		{
			if(in_range(1,9) || in_range(21,29) || in_range(41,49) || in_range(61,69) || in_range(81,89))
				move_scaled(0,1,0,0);
			else if(in_range(11,19) || in_range(31,39) || in_range(51,59) || in_range(71,79) || in_range(91,99))
				move_scaled(1,0,0,0);
			else if((p1_pos % 10 == 0)(p1_pos != 100))
				move_scaled(0,0,1,0);
			
			moves_done = moves_done + 1;
			
			if(moves_done % 10 == 0)
				p1_pos = p1_pos + 1;
		}
		else if(p2_pos < 100  turn == 1)
		{
			if(in_range(1,9) || in_range(21,29) || in_range(41,49) || in_range(61,69) || in_range(81,89))
				move_scaled(0,1,0,0);
			else if(in_range(11,19) || in_range(31,39) || in_range(51,59) || in_range(71,79) || in_range(91,99))
				move_scaled(1,0,0,0);
			else if((p2_pos % 10 == 0)(p2_pos != 100))
				move_scaled(0,0,1,0);
			
			moves_done = moves_done + 1;
			
			if(moves_done % 10 == 0)
				p2_pos = p2_pos + 1;
		}
		
		if((moves_done == moves) ||(turn == 0  p1_pos == 100)||(turn == 1  p2_pos == 100))
			moves = 0;
		
		if(moves == 0) //If the player is done moving 
		{
		//This executes when player has done moving his turn.
		//After that snake bites or ladder is climbed
			var returned_pos : int;
			
			if(turn == 0)
			{
				returned_pos = on_snake_or_ladder(p1_pos);
				if(returned_pos != -1)
				{
					p1_pos = returned_pos;
				}
			}
			else
			{
				returned_pos = on_snake_or_ladder(p2_pos);
				if(returned_pos != -1)
				{
					p2_pos = returned_pos;
				}
			}
						
			turn = (turn + 1) % 2;
		}//If the Player is done moving ENDS here
	}
}//Update() function ENDS here