Search Unity

Changing The WASD Direction of a Player based on their Rotation

Discussion in 'Scripting' started by popuppirate, Sep 22, 2014.

  1. popuppirate

    popuppirate

    Joined:
    Sep 15, 2014
    Posts:
    21
    Hello!

    I'm almost there with a third person player/camera control setup that does exactly what I'd like. However, the player's WASD remains the same regardless of player rotation. I have tried using sine(on the z-plane) and cosine (on the x plane) as functions of the mouse input to transform the direction as is usual with vectors, but this causes very strange behaviour.

    Any chance someone could lend me a hand with my code?

    Cheers,

    popuppirate

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4.  
    5. public class Player_Control : MonoBehaviour {
    6.     public float player_Speed=10.0f;
    7.     public float player_Tilt=0.1f;
    8.     public Vector3 player_Direction;
    9.     public float player_Turn=0.0f;
    10.     public float player_TurnSpeed=2f;
    11.  
    12.     void Start(){
    13.         }
    14.    
    15.  
    16.     void Update(){
    17.         player_Turn+=Input.GetAxis ("Mouse X");
    18.         float player_Horizontal = Input.GetAxis ("Horizontal");
    19.         float player_Vertical = Input.GetAxis ("Vertical");
    20.         //player_Direction= new Vector3 (player_Horizontal*Mathf.Sin(player_Turn*player_TurnSpeed*Mathf.PI/180),0f,player_Vertical*Mathf.Sin(player_Turn*player_TurnSpeed*Mathf.PI/180)); This is my attempt here, commented out because it doesn't work!
    21.         player_Direction=new Vector3(player_Horizontal, 0.0f, player_Vertical);
    22.         rigidbody.velocity = player_Direction*player_Speed;
    23.         rigidbody.rotation = Quaternion.Euler (0.0f,player_Turn*player_TurnSpeed,rigidbody.velocity.x * -player_Tilt);
    24.                
    25.            
    26.                    
    27. }
    28.  
     
  2. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
  3. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    Two options:
    Code (csharp):
    1.  
    2. player_Direction = transform.rotation * new Vector3(player_Horizontal, 0.0f, player_Vertical);
    3.  
    4. player_Direction = transform.right * player_Horizontal + transform.forward * player_Vertical;
    5.  
     
    GarthSmith likes this.
  4. popuppirate

    popuppirate

    Joined:
    Sep 15, 2014
    Posts:
    21
    Thank you both,

    @Garth Smith. I did wonder if there was an easier option. Thanks for the links!

    @StarManta Option 2 works excellently. Now I just need to Clamp the maximum/minimum rotation to +/-90 degrees to prevent a bug I'm getting where the player turns back to front. I think...
     
  5. popuppirate

    popuppirate

    Joined:
    Sep 15, 2014
    Posts:
    21
    Retested and noticed some strange bugs. Because the object tilts, the 'Strafe' (Horizonta;) now pushes the object up in the y plane. This is probably because I have a tilt on the object player when strafing/turning to make the motion more realistic (hovering). Any ideas why?

    PS. This is true in both suggestions.
     
  6. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    Yep. When the object tilts, its "right" vector is pointing upwards slightly. The solution would be to "flatten" the resulting vector: just set player_direction.y to be 0.
     
    GarthSmith likes this.
  7. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
    One thing, removing the y component makes the direction vector smaller. You should normalize it before multiplying by speed.
    Code (csharp):
    1. player_Direction = transform.right * player_Horizontal + transform.forward * player_Vertical;
    2. player_Direction.y = 0f; // May shorten direction vector!
    3. rigidbody.velocity = player_Direction.normalized * player_Speed;
     
    StarManta likes this.
  8. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    I knew I forgot something.
     
  9. popuppirate

    popuppirate

    Joined:
    Sep 15, 2014
    Posts:
    21
    Thanks guys, your time is really appreciated!

    Two things I have noticed:

    The 'normalisation' part of the code only seems to make the player's tilt much more rigid with little other effect. I have therefore kept using what I was using before.

    While setting the y component of the velocity to 0 worked a treat, the tilt is unfortunately still tied to the x plane of the game rather than the object's. I did consider using the method above to multiply by the object's transform.rotation.x but a) that didn't work and b) it shouldn't work because the x component of the player_Movement Vector is already being multiplied by the rotation held by the game and so for all intents and purposes the rotation should match the new movement. Any thoughts?

    Cheers you guys! I've been stuck on this for ages and I can almost see the end of the tunnel!

    Code (CSharp):
    1. player_Direction = transform.rotation * new Vector3(player_Horizontal, 0.0f, player_Vertical);//Rotates the Direction Vector
    2. player_Direction.y = 0.0f;
    3. rigidbody.velocity = player_Direction*player_Speed;// Sets Player Velocity
    4. float Test = rigidbody.velocity.x*-player_Tilt;// Tested here. Tried multiplying by transform.rotation.x but didn't work.
    5. rigidbody.rotation = Quaternion.Euler (0.0f,player_Turn*player_TurnSpeed,Test);