Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How to make a character turn around smoothly

Discussion in 'Scripting' started by eskovas, Dec 3, 2009.

  1. eskovas

    eskovas

    Joined:
    Dec 2, 2009
    Posts:
    1,373
    i posted this in the unity support but its better for me to post here in the scripting section
    hi,
    this is my first of many posts here in unity foruns
    i've been making a game for a month(we are basically biginners), we have been learning how to work with unity and blender ( for models, animations and other things).

    Now the priority is basically to make and test the script before making the real models and animations.

    so here's the problem

    ive been using the 3D Platform tutorial to make the script,
    i basically started from scratch and begin to write the script and learning how all of this works but i cant find how to make my model turn around smoothly ...

    i also made a video xD

    http://www.youtube.com/watch?v=Dg9l20RWqZk

    i think you can see the problem,
    how can i make him turn around smoothly?

    heres my code:
    the code is in portuguese... i started from scratch and ive been learning how it all works...

    Code (csharp):
    1. private var Velocidade1:float = 0;
    2. private var Velocidade2:float = 0;
    3. //VELOCIDADE ANDAR
    4. var VelocidadeAndar:float = 4;
    5. //VELOCIDADE CORRER
    6. var VelocidadeCorrer:float = 8;
    7. //VELOCIDADE SPRINT
    8.  
    9. var VelocidadeCorrer2:float = 4;
    10. var VelocidadeSprint:float = 6;
    11.  
    12. var VelocidadeAgachadoNormal:float = 2;
    13. var VelocidadeAgachadoRapido:float = 4;
    14. //VELOCIDADE ROTAÇAO
    15. var VelocidadeRotacao:float = 500;
    16. //suavizar Velocidade
    17. var SuavVelocidade = 10.0;
    18. //ALTURA do SALTO
    19. var AlturaSalto = 0.5;
    20. //Gravidade
    21. var gravity = 10.0;
    22. //Velocidade no ar
    23. private var VelocidadeNoAr = Vector3.zero;
    24. //A Direcção do movimento em XZ
    25. private var moveDirection = Vector3.zero;
    26. //A VELOCIDADE VERTICAL actual
    27. private var VelocidadeVertical = 0.0;
    28. //A VELOCIDADE actual em XZ
    29. private var Velocidade:float = 0;
    30. //Saber se está a SALTAR
    31. private var Salto = false;
    32. //Saber se está a ANDAR PARA TRAS
    33. private var AndarTras = false;
    34. //Saber se está a ANDAR
    35. private var EstaAndar = false;
    36.  
    37. // Average normal of the last touched geometry
    38. private var wallJumpContactNormal : Vector3;
    39. private var wallJumpContactNormalHeight : float;
    40.  
    41. private var estado = 0;
    42.  
    43. private var EstaAgachado = false;
    44.  
    45. private var collisionFlags : CollisionFlags;
    46.  
    47. private var AlturaMaxima = false;
    48.  
    49. ////////////////////////////////////////////////////////////////////////////////////////////
    50.  
    51. function Update_Movimento_Direccao()
    52. {
    53. var cameraTransform = Camera.main.transform;
    54. var NoChao = NoChao();
    55.  
    56. //Vector 'Frente' Relativo a camera
    57. var forward = cameraTransform.TransformDirection(Vector3.forward);
    58.     forward.y = 0;
    59.     forward = forward.normalized;
    60.  
    61. //Vector 'Direita' Relativo a camera
    62. var right = Vector3(forward.z, 0, -forward.x);
    63.  
    64.     var v = Input.GetAxisRaw("Vertical");
    65.     var h = Input.GetAxisRaw("Horizontal");
    66.  
    67. //Está a andar para tras ou a olhar para tras
    68. if (v < -0.2)
    69.         AndarTras = true;
    70.     else
    71.         AndarTras = false;
    72.    
    73.     var EstavaAndar = EstaAndar;
    74.     EstaAndar = Mathf.Abs (h) > 0.1 || Mathf.Abs (v) > 0.1;
    75.    
    76. var ProxDireccao = h * right + v * forward;
    77.  
    78. ///////////////////////////////////////////////////////////////////////////////////////////
    79.  
    80.  if (NoChao){
    81.  
    82. // We store speed and direction seperately,
    83.         // so that when the character stands still we still have a valid forward direction
    84.         // moveDirection is always normalized, and we only update it if there is user input.
    85.         if (ProxDireccao != Vector3.zero)
    86.         {
    87.             if (Velocidade < Velocidade1 * 0.9  NoChao())
    88.             {
    89.                 moveDirection = ProxDireccao.normalized;
    90.             }
    91.             // Otherwise smoothly turn towards it
    92.             else
    93.             {
    94.                 moveDirection = Vector3.RotateTowards(moveDirection, ProxDireccao, VelocidadeRotacao * Mathf.Deg2Rad * Time.deltaTime, 1000);
    95.                
    96.                 moveDirection = moveDirection.normalized;
    97.             }
    98.         }
    99.         // Smooth the speed based on the current target direction
    100.         var CurvaSuave = SuavVelocidade * Time.deltaTime;
    101.        
    102.         // Choose target speed
    103.         //* We want to support analog input but make sure you cant walk faster diagonally than just forward or sideways
    104.         var ProxVelocidade = Mathf.Min(ProxDireccao.magnitude, 1.0);
    105.    
    106.     }
    107.    
    108.     if (EstaAgachado == false)
    109.     {
    110.     estado = 0;
    111. //definir Velocidades De Inicio
    112. if (Velocidade1 != VelocidadeCorrer)
    113. {
    114. Velocidade1 = VelocidadeAndar;
    115. Velocidade2 = VelocidadeCorrer2;
    116. }
    117.  
    118. //Mudar de Estado
    119. if(Input.GetKeyDown("q")  Velocidade1 == VelocidadeCorrer)
    120. {
    121. Velocidade1 = VelocidadeAndar;
    122. Velocidade2 = VelocidadeCorrer2;
    123. }
    124. else if (Input.GetKeyDown("q"))
    125. {
    126. Velocidade1 = VelocidadeCorrer;
    127. Velocidade2 = VelocidadeSprint;
    128. }
    129.  
    130. ProxVelocidade *= Velocidade1;
    131. estado = ProxVelocidade + Velocidade2;
    132. if (Input.GetKey("e"))
    133. {
    134. ProxVelocidade = estado;
    135. }
    136. }
    137.  
    138. if ( EstaAgachado == true )
    139. {
    140. estado = 0;
    141. //definir Velocidades De Inicio
    142. if (Velocidade1 != VelocidadeCorrer)
    143. {
    144. Velocidade1 = VelocidadeAgachadoNormal;
    145. Velocidade2 = VelocidadeAgachadoRapido;
    146. }
    147.  
    148. ProxVelocidade *= Velocidade1;
    149. estado = ProxVelocidade + Velocidade2;
    150. if (Input.GetKey("e"))
    151. {
    152. ProxVelocidade = estado;
    153.  
    154. }
    155. }
    156.  
    157. Velocidade = Mathf.Lerp(Velocidade, ProxVelocidade, CurvaSuave);
    158.  
    159.  
    160. }
    161.  
    162. ///////////////////////////////////////////////////////////////////////////////////////////
    163.  
    164. function AplicarGravidade ()
    165. {
    166. if (!NoChao())
    167. VelocidadeVertical -= gravity * Time.deltaTime;
    168. }
    169.  
    170. ///////////////////////////////////////////////////////////////////////////////////////////
    171.  
    172. function AplicarSalto()
    173. {
    174.     if (Input.GetButtonDown("Jump"))
    175. VelocidadeVertical = 5;
    176. }
    177.  
    178. /////////////////////////////////////////////////////////////////////////////////////////////
    179.  
    180. function Update() {
    181.  
    182. print (VelocidadeVertical);
    183. //print(Velocidade);
    184.  
    185. if (Input.GetKeyDown("2")  EstaAgachado == false)
    186. {
    187. EstaAgachado = true;
    188. }
    189. else if (Input.GetKeyDown("2"))
    190. EstaAgachado = false;
    191.  
    192. Update_Movimento_Direccao();
    193.  
    194. AplicarGravidade();
    195.  
    196. // Calcular o movimento
    197.     var movemento = moveDirection * Velocidade + Vector3 (0, VelocidadeVertical, 0) + VelocidadeNoAr;
    198.     movemento *= Time.deltaTime;
    199.    
    200.     // Mover  Jogador
    201.     var controller : CharacterController = GetComponent(CharacterController);
    202.     wallJumpContactNormal = Vector3.zero;
    203.     collisionFlags = controller.Move(movemento);
    204.  
    205. if (Input.GetKeyDown("r"))
    206. {
    207. controller.height = 5;
    208. }
    209.  
    210. if (NoChao())
    211.     {
    212.         AplicarSalto();
    213.             var xzMove = movemento;
    214.             xzMove.y = 0;
    215.             if (xzMove.sqrMagnitude > 0.001)
    216.             {
    217.                 transform.rotation = Quaternion.LookRotation(xzMove);
    218.             }
    219.         }
    220.        
    221. }
    222.  
    223. /////////////////////////////////////////////////
    224. //Saber se está no chao
    225. function NoChao ()
    226.  {
    227.     return (collisionFlags  CollisionFlags.CollidedBelow) != 0;
    228. }
    229. /////////////////////////////////////////////////
    230. function GetVelocidade()
    231. {
    232. return Velocidade;
    233. }
    234.  
    235. function Esta_Agachado()
    236. {
    237. return EstaAgachado;
    238. }
    239.  
    i hope you understand, if you want i can translate it,

    thanks
     
  2. eskovas

    eskovas

    Joined:
    Dec 2, 2009
    Posts:
    1,373
    anyone?
     
  3. rozgo

    rozgo

    Joined:
    Feb 7, 2008
    Posts:
    158
    I haven't looked at your code, but can hint you in the right direction.

    Assuming your character is looking on:

    transform.forward (Vector3)

    and you want him to look in:

    newLookDirection (Vector3)

    find the amount he will need to rotate to look at that direction:

    deltaAngle (float) = Vector3.Angle(transform.forward, newLookDirection)

    now that you know the angle, you need to figure out if you need to turn clockwise or counter-clockwise:

    axisOfRotation (Vector3) = Vector3.Cross(transform.forward, newLookDirection)

    now create a rotation transform that will get you to the desired angle:

    deltaRotation (Quaternion) = Quaternion.AngleAxis(deltaAngle, axisOfRotation)

    now just applying this will snap to the desired angle, which is not what you want, so lets interpolate towards your destination:

    transform.rotation = Quaternion.Lerp(transform.rotation, transform.rotation * deltaRotation, Time.deltaTime)

    you will want to experiment with different kinds of interpolation tecniques, if this is not good for you

    try this for a start, and then search online for better (real) solutions, since this is overlooking too many details

    i used many steps so you could play with the intermediate steps
     
  4. Lokken

    Lokken

    Joined:
    Apr 23, 2009
    Posts:
    436
    This is a friendly suggestion; wrap any code you want to post in the code tags. It makes the code infinitely more readable.

    Code (csharp):
    1. code!
     
  5. eskovas

    eskovas

    Joined:
    Dec 2, 2009
    Posts:
    1,373
    thanks
    ill try it
     
  6. eskovas

    eskovas

    Joined:
    Dec 2, 2009
    Posts:
    1,373
    thanks, im new to this forum...
     
  7. eskovas

    eskovas

    Joined:
    Dec 2, 2009
    Posts:
    1,373
    it worked!
    its now turning smoothly, thanks

    i have other question xD

    when i go to the edge of the platform

    this happens



    is there other way to make the bounds of the character?
     
  8. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    Not sure what is happening from the picture. Do you mean the character is not falling under gravity or is the collider getting stuck on the edge?