Search Unity

Need smooth movement of cube instead of instantaneous

Discussion in 'Scripting' started by Aseem Bansal, Oct 21, 2012.

  1. Aseem Bansal

    Aseem Bansal

    Joined:
    Oct 21, 2012
    Posts:
    21
    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.


    Code (csharp):
    1. #pragma strict
    2.  
    3. //These are set from GUI
    4. var p1          : GameObject;
    5. var p2          : GameObject;
    6. var cube        : GameObject;
    7. var cubeUp      : GameObject;
    8. var cubeRight   : GameObject;
    9.  
    10. //These remain Constant
    11. private var moveRight   : Vector3;
    12. private var moveLeft    : Vector3;
    13. private var moveUp      : Vector3;
    14. private var moveDown    : Vector3;
    15.  
    16. private var p1_pos : int = 1;
    17. private var p2_pos : int = 1;
    18. private var turn        : int = 0;
    19.  
    20. private var moves       : float = 0.0;
    21.  
    22. //Functions to be called
    23. function move(Left : float, Right : float, Up : float, Down : float)
    24. {//Left Right Up Down
    25.     if(turn ==0)
    26.         p1.transform.Translate((moveRight * Right)+(moveLeft * Left) + (moveUp * Up) + (moveDown * Down));
    27.     else
    28.         p2.transform.Translate((moveRight * Right)+(moveLeft * Left) + (moveUp * Up) + (moveDown * Down));
    29. }
    30. function in_range(lower : int, higher : int): boolean
    31. {
    32.     var pos : int;
    33.    
    34.     if(turn ==0)
    35.         pos = p1_pos;
    36.     else
    37.         pos = p2_pos;
    38.        
    39.     if( pos >= lower   pos <= higher)
    40.         return true;
    41.     else
    42.         return false;
    43. }
    44. function on_snake_or_ladder(pos : int) : int
    45. {
    46.     switch(pos)
    47.     {
    48.     //Ladders    L R U D
    49.         case 2:
    50.             move(0,1,1,0); return(18);
    51.         case 11:
    52.             move(0,0,2,0); return(31);
    53.         case 12:
    54.             move(1,0,1,0); return(28);
    55.         case 22:
    56.             move(1,0,1,0); return(40);
    57.         case 36:
    58.             move(3,0,3,0); return(62);
    59.         case 41:
    60.             move(0,1,1,0); return(59);
    61.         case 46:
    62.             move(0,0,1,0); return(55);
    63.         case 70:
    64.             move(3,0,3,0); return(94);
    65.         case 77:
    66.             move(0,0,1,0); return(84);
    67.         case 85:
    68.             move(1,0,1,0); return(97);
    69.            
    70.         //Snakes L R U D
    71.         case 21:
    72.             move(0,5,0,1);  return(15);
    73.         case 23:
    74.             move(0,3,0,2); return(6);
    75.         case 29:
    76.             move(3,0,0,1); return(15);
    77.         case 35:
    78.             move(3,0,0,2); return(18);
    79.         case 47:
    80.             move(0,2,0,1); return(32);
    81.         case 52:
    82.             move(6,0,0,2); return(38);
    83.         case 71:
    84.             move(3,0,0,4); return(34);
    85.         case 82:
    86.             move(0,0,0,3); return(59);
    87.         case 95:
    88.             move(3,0,0,2); return(78);
    89.         case 99:
    90.             move(0,0,0,2); return(79);
    91.         default:               
    92.             break;
    93.     }
    94.     return(-1);
    95. }
    96. //Functions to be called END HERE
    97.  
    98. function Start()
    99. {  
    100.     var distance : Vector3 = p2.transform.position - p1.transform.position;
    101.  
    102.     moveRight = (cubeRight.transform.position - cube.transform.position);
    103.     moveLeft  = - moveRight ;
    104.     moveUp    = (cubeUp.transform.position - cube.transform.position);
    105.     moveDown  = - moveUp;
    106.    
    107.     p1.transform.Translate(cube.transform.position - p1.transform.position);
    108.     p2.transform.position = p1.transform.position;
    109.     p2.transform.Translate(distance);
    110. }
    111.  
    112. function OnGUI ()
    113. {  
    114.     if(moves == 0.0)
    115.     {
    116.         if(GUI.Button(Rect (20,70,80,40), "Throw\n Dice"))
    117.         {
    118.             var moves_int : int;
    119.             moves_int = Random.Range(1,6);
    120.             moves =  moves_int;
    121.         }
    122.     }
    123. }
    124.  
    125. function Update()
    126. {
    127.     if(moves > 0) //Executes if any plane is yet to move
    128.     {
    129.         if(p1_pos < 100  turn == 0)
    130.         {
    131.             if(in_range(1,9) || in_range(21,29) || in_range(41,49) || in_range(61,69) || in_range(81,89))
    132.                 move(0,1,0,0);
    133.             else if(in_range(11,19) || in_range(31,39) || in_range(51,59) || in_range(71,79) || in_range(91,99))
    134.                 move(1,0,0,0);
    135.             else if((p1_pos % 10 == 0)(p1_pos != 100))
    136.                 move(0,0,1,0);
    137.            
    138.             p1_pos = p1_pos + 1;
    139.         }
    140.         else if(p2_pos < 100  turn == 1)
    141.         {
    142.             if(in_range(1,9) || in_range(21,29) || in_range(41,49) || in_range(61,69) || in_range(81,89))
    143.                 move(0,1,0,0);
    144.             else if(in_range(11,19) || in_range(31,39) || in_range(51,59) || in_range(71,79) || in_range(91,99))
    145.                 move(1,0,0,0);
    146.             else if((p2_pos % 10 == 0)(p2_pos != 100))
    147.                 move(0,0,1,0);
    148.            
    149.             p2_pos = p2_pos + 1;
    150.         }
    151.         moves = moves - 1;
    152.        
    153.         if(moves == 0) //If for Player done moving
    154.         {
    155.         //This if executes when player has done moving his turn.
    156.         //After that snake bites or ladder is climbed
    157.             var returned_pos : int;
    158.            
    159.             if(turn == 0)
    160.             {
    161.                 returned_pos = on_snake_or_ladder(p1_pos);
    162.                 if(returned_pos != -1)
    163.                 {
    164.                     p1_pos = returned_pos;
    165.                 }
    166.             }
    167.             else
    168.             {
    169.                 returned_pos = on_snake_or_ladder(p2_pos);
    170.                 if(returned_pos != -1)
    171.                 {
    172.                     p2_pos = returned_pos;
    173.                 }
    174.             }
    175.                        
    176.             turn = (turn + 1) % 2;
    177.         }//If for Player done moving ENDS here
    178.     }
    179. }//Update() function ENDS here
     
    Last edited: Oct 21, 2012
  2. Westerbly

    Westerbly

    Joined:
    Aug 15, 2012
    Posts:
    60
    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.
     
  3. Aseem Bansal

    Aseem Bansal

    Joined:
    Oct 21, 2012
    Posts:
    21
    You mean changing the argument of translate in the move function? I multiplied it with Time.deltaTime but there was no change.
     
  4. Westerbly

    Westerbly

    Joined:
    Aug 15, 2012
    Posts:
    60
    This:
    Code (csharp):
    1. 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.
     
  5. Aseem Bansal

    Aseem Bansal

    Joined:
    Oct 21, 2012
    Posts:
    21
    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.
     
  6. Westerbly

    Westerbly

    Joined:
    Aug 15, 2012
    Posts:
    60
    Now is up to you tweak your speed till it's enough. But the deltaTime part is very important for smoothness.
     
  7. Aseem Bansal

    Aseem Bansal

    Joined:
    Oct 21, 2012
    Posts:
    21
    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?
     
    Last edited: Oct 21, 2012
  8. Loius

    Loius

    Joined:
    Aug 16, 2012
    Posts:
    546
    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)

    Code (csharp):
    1. private var moving : boolean = false;
    2. var speed : float = 1.0; // 1.0 = one second, 0.5 = two seconds, 0.25 = four seconds
    3.  
    4. function MoveTo( targetPosition : Vector3 ) {
    5.   var ratio : float = 0.0;
    6.   var startPosition : Vector3 = transform.position;
    7.   if ( moving ) return;
    8.   moving = true;
    9.   while ( ratio < 1.0 ) {
    10.     ratio = Mathf.Min( 1.0, ratio + Time.deltaTime * speed );
    11.     transform.position = Vector3.Lerp( startPosition, targetPosition, ratio );
    12.     yield;
    13.   }
    14.   moving = false;
    15. }
    16.  
    17. ...
    18.  
    19. if ( !moving ) {
    20.   StartCoroutine( MoveTo( transform.position + Vector3.up * 10 ) );
    21. }
     
  9. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
  10. Aseem Bansal

    Aseem Bansal

    Joined:
    Oct 21, 2012
    Posts:
    21
    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:--
    Code (csharp):
    1. #pragma strict
    2.  
    3. //These are set from GUI
    4. var p1          : GameObject;
    5. var p2          : GameObject;
    6. var cube        : GameObject;
    7. var cubeUp      : GameObject;
    8. var cubeRight   : GameObject;
    9.  
    10. //These remain Constant
    11. private var moveRight   : Vector3;
    12. private var moveLeft    : Vector3;
    13. private var moveUp      : Vector3;
    14. private var moveDown    : Vector3;
    15.  
    16. //These change according to player's position
    17. private var p1_pos  : int = 1;
    18. private var p2_pos  : int = 1;
    19.  
    20. //This decides whose turn
    21. private var turn    : int = 0;
    22. //This is for current moves
    23. private var moves   : int = 0;
    24. private var moves_done : int = 0;
    25.  
    26. //Functions to be called
    27. function move(Left : int, Right : int, Up : int, Down : int)
    28. {   //L R U D
    29.     //Automatically decides which player to move according to turn
    30.     if(turn ==0)
    31.         p1.transform.Translate((moveRight * Right)+(moveLeft * Left) + (moveUp * Up) + (moveDown * Down));
    32.     else
    33.         p2.transform.Translate((moveRight * Right)+(moveLeft * Left) + (moveUp * Up) + (moveDown * Down));
    34. }
    35.  
    36. function move_scaled(Left : int, Right : int, Up : int, Down : int)
    37. {   //L R U D
    38.     //Automatically decides which player to move according to turn
    39.     if(turn ==0)
    40.         p1.transform.Translate(((moveRight * Right)+(moveLeft * Left) + (moveUp * Up) + (moveDown * Down)) * 0.1);
    41.     else
    42.         p2.transform.Translate(((moveRight * Right)+(moveLeft * Left) + (moveUp * Up) + (moveDown * Down)) * 0.1);
    43. }
    44.  
    45. function in_range(lower : int, higher : int): boolean
    46. {//Checks whether 2 numbers in a range
    47.     var pos : int;
    48.    
    49.     if(turn ==0)
    50.         pos = p1_pos;
    51.     else
    52.         pos = p2_pos;
    53.        
    54.     if( pos >= lower   pos <= higher)
    55.         return true;
    56.     else
    57.         return false;
    58. }
    59. function on_snake_or_ladder(pos : int) : int
    60. {
    61.     switch(pos)
    62.     {
    63.     //Ladders    L R U D
    64.         case 2:
    65.             move(0,1,1,0); return(18);
    66.         case 11:
    67.             move(0,0,2,0); return(31);
    68.         case 12:
    69.             move(1,0,1,0); return(28);
    70.         case 22:
    71.             move(1,0,1,0); return(40);
    72.         case 36:
    73.             move(3,0,3,0); return(62);
    74.         case 41:
    75.             move(0,1,1,0); return(59);
    76.         case 46:
    77.             move(0,0,1,0); return(55);
    78.         case 70:
    79.             move(3,0,3,0); return(94);
    80.         case 77:
    81.             move(0,0,1,0); return(84);
    82.         case 85:
    83.             move(1,0,1,0); return(97);
    84.            
    85.         //Snakes L R U D
    86.         case 21:
    87.             move(0,5,0,1);  return(15);
    88.         case 23:
    89.             move(0,3,0,2); return(6);
    90.         case 29:
    91.             move(3,0,0,1); return(15);
    92.         case 35:
    93.             move(3,0,0,2); return(18);
    94.         case 47:
    95.             move(0,2,0,1); return(32);
    96.         case 52:
    97.             move(6,0,0,2); return(38);
    98.         case 71:
    99.             move(3,0,0,4); return(34);
    100.         case 82:
    101.             move(0,0,0,3); return(59);
    102.         case 95:
    103.             move(3,0,0,2); return(78);
    104.         case 99:
    105.             move(0,0,0,2); return(79);
    106.         default:               
    107.             break;
    108.     }
    109.     return(-1);
    110. }
    111. //Functions to be called END HERE
    112.  
    113. function Start()
    114. {  
    115.     var distance : Vector3 = p2.transform.position - p1.transform.position;
    116.  
    117.     moveRight = (cubeRight.transform.position - cube.transform.position);
    118.     moveLeft  = - moveRight ;
    119.     moveUp    = (cubeUp.transform.position - cube.transform.position);
    120.     moveDown  = - moveUp;
    121.    
    122.     p1.transform.Translate(cube.transform.position - p1.transform.position);
    123.     p2.transform.position = p1.transform.position;
    124.     p2.transform.Translate(distance);
    125. }
    126.  
    127. function OnGUI ()
    128. {  
    129.     if(moves == 0)
    130.     {
    131.         if(GUI.Button(Rect (20,70,80,40), "Throw\n Dice"))
    132.         {
    133.             moves = Random.Range(1,6);
    134.             moves = moves * 10;
    135.             moves_done = 0;
    136.         }
    137.     }
    138. }
    139.  
    140. function Update()
    141. {
    142.     if(moves > 0) //Executes if any player is yet to move
    143.     {
    144.         if(p1_pos < 100  turn == 0)
    145.         {
    146.             if(in_range(1,9) || in_range(21,29) || in_range(41,49) || in_range(61,69) || in_range(81,89))
    147.                 move_scaled(0,1,0,0);
    148.             else if(in_range(11,19) || in_range(31,39) || in_range(51,59) || in_range(71,79) || in_range(91,99))
    149.                 move_scaled(1,0,0,0);
    150.             else if((p1_pos % 10 == 0)(p1_pos != 100))
    151.                 move_scaled(0,0,1,0);
    152.            
    153.             moves_done = moves_done + 1;
    154.            
    155.             if(moves_done % 10 == 0)
    156.                 p1_pos = p1_pos + 1;
    157.         }
    158.         else if(p2_pos < 100  turn == 1)
    159.         {
    160.             if(in_range(1,9) || in_range(21,29) || in_range(41,49) || in_range(61,69) || in_range(81,89))
    161.                 move_scaled(0,1,0,0);
    162.             else if(in_range(11,19) || in_range(31,39) || in_range(51,59) || in_range(71,79) || in_range(91,99))
    163.                 move_scaled(1,0,0,0);
    164.             else if((p2_pos % 10 == 0)(p2_pos != 100))
    165.                 move_scaled(0,0,1,0);
    166.            
    167.             moves_done = moves_done + 1;
    168.            
    169.             if(moves_done % 10 == 0)
    170.                 p2_pos = p2_pos + 1;
    171.         }
    172.        
    173.         if((moves_done == moves) ||(turn == 0  p1_pos == 100)||(turn == 1  p2_pos == 100))
    174.             moves = 0;
    175.        
    176.         if(moves == 0) //If the player is done moving
    177.         {
    178.         //This executes when player has done moving his turn.
    179.         //After that snake bites or ladder is climbed
    180.             var returned_pos : int;
    181.            
    182.             if(turn == 0)
    183.             {
    184.                 returned_pos = on_snake_or_ladder(p1_pos);
    185.                 if(returned_pos != -1)
    186.                 {
    187.                     p1_pos = returned_pos;
    188.                 }
    189.             }
    190.             else
    191.             {
    192.                 returned_pos = on_snake_or_ladder(p2_pos);
    193.                 if(returned_pos != -1)
    194.                 {
    195.                     p2_pos = returned_pos;
    196.                 }
    197.             }
    198.                        
    199.             turn = (turn + 1) % 2;
    200.         }//If the Player is done moving ENDS here
    201.     }
    202. }//Update() function ENDS here