Search Unity

Help needed with moving an object according to its rotation

Discussion in 'Scripting' started by YeTii, Aug 1, 2018.

  1. YeTii

    YeTii

    Joined:
    Apr 3, 2015
    Posts:
    3
    Hi, first post here.
    First and foremost, I do know it could easily be done with "translate.forward" but I want to understand why my script doesn't work and what to do to fix it.

    So my problem is:
    I have an object controlled by wsad keys. When I press the key I want the object to move 1 unit per frame in the direction it's facing. The rotation of the object is changed by a separate script that handles the camera.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngineInternal;
    5.  
    6. public class PlayerControl : MonoBehaviour
    7. {
    8.  
    9.  
    10.     public Vector3 movement;    //
    11.     public float rot;            // rotation in radians in y axis
    12.     public Vector3 pos;        //current position on plane
    13.     public float inX;    //input horizontal
    14.     public float inZ;    //input vertical
    15.     public float tempR;     // for sine and cosine
    16.     public float tempZ;    //rotated z
    17.     public float tempX;    //rotated x
    18.    
    19.     void Start ()
    20.     {
    21.         movement.y = transform.position.y;
    22.  
    23.  
    24.     }
    25.    
    26.     void FixedUpdate ()
    27.     {
    28.         rot = transform.eulerAngles.y * Mathf.Deg2Rad;
    29.        
    30.         pos = transform.position;
    31.  
    32.         if (Input.GetKey(KeyCode.W))
    33.         {
    34.             inZ = 1;
    35.         }
    36.         if (Input.GetKey(KeyCode.S))
    37.         {
    38.             inZ = -1;
    39.         }
    40.         if (Input.GetKey(KeyCode.D))
    41.         {
    42.             inX = 1;
    43.         }
    44.         if (Input.GetKey(KeyCode.A))
    45.         {
    46.             inX = -1;
    47.         }
    48.        
    49.         tempR = Mathf.Sqrt((inX * inX) + (inZ * inZ));
    50.  
    51.         tempZ = tempR * Mathf.Sin(rot)// * inZ/10 //<- when uncommented it works fine but only on x and z axis
    52.             ;
    53.  
    54.         tempX = tempR * Mathf.Cos(rot) //* inX/10  //<-when uncommented it works fine but only on x and z axis
    55.             ;
    56.        
    57.        
    58.         movement.x = pos.x + tempX;
    59.         movement.z = pos.z + tempZ;
    60.  
    61.         transform.position = movement;
    62.         inZ = 0;
    63.         inX = 0;    
    64.     }
    65. }
    66.  
    67.  

    when i try to move in any direction it goes completely mad, anyone has any idea what to do?
    I thought that the math was all right but something has to be wrong.
    Thank you in advance.
     
  2. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,769
    Use Debug.Log () ;
    To get actual angle (rot) and see, in which direction your object is expected to be facing.
    Just to check, but I assume, you are aware that pressing WSAD in any combination, can output 0, 1, or 1.414, which is you temporary radius tempR?
    That is really the speed factor of you movement, in direction purely defined by rot. Which is in different script, as you said.
     
  3. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,317
    I think you've gone a bit into the weeds with your logic. You're not preserving the actual direction the player wants to go anywhere. The reason that uncommenting those lines made it "work" at all is because you were reintroducing the positive/negative values that you're setting via keypresses. There was basically no possibility for the code to work as is.

    Here's one example of what you would have to do to get this approach to work.
    Code (CSharp):
    1. void FixedUpdate () {
    2.    rot = transform.eulerAngles.y * Mathf.Deg2Rad;
    3.  
    4.    pos = transform.position;
    5.  
    6.    if( Input.GetKey( KeyCode.W ) ) {
    7.        inZ = 1;
    8.    }
    9.    if( Input.GetKey( KeyCode.S ) ) {
    10.        inZ = -1;
    11.    }
    12.    if( Input.GetKey( KeyCode.D ) ) {
    13.        inX = 1;
    14.    }
    15.    if( Input.GetKey( KeyCode.A ) ) {
    16.        inX = -1;
    17.    }
    18.  
    19.    tempZ = -Mathf.Sin( rot );
    20.    tempX = Mathf.Cos( rot );
    21.  
    22.    Vector3 delta;
    23.    delta.x = tempX * inX - tempZ * inZ;
    24.    delta.y = 0;
    25.    delta.z = tempZ * inX + tempX * inZ;
    26.  
    27.    delta = delta.normalized;
    28.  
    29.    transform.position = pos + delta;
    30.    inZ = 0;
    31.    inX = 0;
    32. }
    You could also simply perform a relative translation on the transform:

    Code (CSharp):
    1. void FixedUpdate () {
    2.     inX = 0;
    3.     inZ = 0;
    4.     if( Input.GetKey( KeyCode.W ) ) {
    5.         inZ = 1;
    6.     }
    7.     if( Input.GetKey( KeyCode.S ) ) {
    8.         inZ = -1;
    9.     }
    10.     if( Input.GetKey( KeyCode.D ) ) {
    11.         inX = 1;
    12.     }
    13.     if( Input.GetKey( KeyCode.A ) ) {
    14.         inX = -1;
    15.     }
    16.  
    17.     Vector3 delta;
    18.     delta.x = inX;
    19.     delta.y = 0;
    20.     delta.z = inZ;
    21.  
    22.     delta = delta.normalized;
    23.  
    24.     transform.Translate( delta, Space.Self );
    25. }
     
  4. YeTii

    YeTii

    Joined:
    Apr 3, 2015
    Posts:
    3
    @Madgvox
    I'm attaching a picture of what I was trying to get, basically transform the 2d vextor(x,z) in the world axis so that it looks "neat" ,for lack of a better word, in the "local" axis of the object.
    I must have gotten confused somewhere.
    The code you posted works just as I wanted for the X axis but when it comes to the Z axis no matter the rotation it only moves at the diagonal line.
    Could you please briefly walk me through this code so I may understand why's that happening?
    Code (CSharp):
    1.  tempZ = -Mathf.Sin( rot );
    2.    tempX = Mathf.Cos( rot );
    3.    Vector3 delta;
    4.    delta.x = tempX * inX - tempZ* inZ;
    5.    delta.y = 0;
    6.    delta.z = tempZ * inX + tempX * inZ;
    I understand the delta vector and why it's normalized I just don't get the calculations here.
    Thanks.

    EDIT:
    Finally got it to work and I ended up with the same code you posted, I have no bloody idea why it didn't work before but now I also have a basic understanding of why it looks the way it does. Thank You very much!
     

    Attached Files:

    Last edited: Aug 1, 2018
    Madgvox likes this.
  5. YeTii

    YeTii

    Joined:
    Apr 3, 2015
    Posts:
    3
    @Antypodish
    The reason all my variables are public is exactly because I was trying to figure out the angle and how the script behaves. As for 0,1 and √2, I wanted it to be the lenght of the "step" the object takes each frame