Search Unity

Character controller rotating downward on the X axis.

Discussion in 'Scripting' started by Hotpockets26, Jul 8, 2018.

  1. Hotpockets26

    Hotpockets26

    Joined:
    Dec 16, 2017
    Posts:
    32
    Hello! I am new to Unity and coding in general, and I am making a character controller for my game. Basically what I'm trying to do is make movement similar to Wind Waker (What I mean by wind waker movement is the player moves facing towards the players input direction no matter the position of the camera, but the cameras forward is always the players forward.)

    So the problem is my character rotates on the X Axis whenever I look up or down with my camera.


    What I want is what my character does now for the most part, which is rotate toward my WASD input based on the direction of the camera (AKA the cameras forward is the characters forward whenever I am moving), and all that works fine except it is rotating on the X axis as well.

    This only happens when I am moving because I set an IF statement to make sure my character doesn't rotate toward WASD input when I am standing still.

    Here is my code for the Character Controller

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PCTest : MonoBehaviour
    6. {
    7.  
    8.     public CharacterController _controller;
    9.  
    10.     // The Vector3 used to store the player input, and then output it into the controller.move function.
    11.     private Vector3 _moveDirection;
    12.  
    13.     // The movement speed of the player.
    14.     public float moveSpeed;
    15.  
    16.     // The gravity up or down for the player
    17.     public float gravityWeight;
    18.  
    19.     // The catch up rotation speed of the capsule to the camPivot using slerp
    20.     public float capsuleRotSpeed;
    21.  
    22.     // Use this for initialization
    23.     void Start()
    24.     {
    25.  
    26.         _controller = GetComponent<CharacterController>();
    27.         //  anim = GetComponent<Animator>();
    28.  
    29.     }
    30.  
    31.     // Update is called once per frame
    32.     void Update()
    33.     {
    34.  
    35.         // WASD input with speed applied
    36.         float moveH = Input.GetAxis("Horizontal") * moveSpeed;
    37.         float moveV = Input.GetAxis("Vertical") * moveSpeed;
    38.  
    39.         // Stores the movement in a Vector3 so that it can be used where a Vector3 is needed ////GET RID OF new Vector3////
    40.         _moveDirection = new Vector3(moveH, 0f, moveV);
    41.  
    42.         _moveDirection = Camera.main.transform.TransformDirection(_moveDirection);
    43.  
    44.         // Makes sure the character doesnt bounce back to the forward position when no input is pressed
    45.         if (_moveDirection != Vector3.zero)
    46.         {
    47.             // Rotates the player toward the WASD input.
    48.             transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(_moveDirection), capsuleRotSpeed * Time.deltaTime);
    49.         }
    50.  
    51.         // Applies gravity to the Y axis
    52.         _moveDirection.y = Physics.gravity.y * gravityWeight * Time.deltaTime;
    53.  
    54.         //transform.rotation = Quaternion.Euler(testRot);
    55.  
    56.         // Moves the player with the _moveDirection Vector3's input, and applies Time.deltaTime
    57.         _controller.Move(_moveDirection * Time.deltaTime);
    58.     }
    59. }
    I tried to force the X rotation of the player to be 0f so it wouldn't rotate down or up, but unfortunately all that did was make my character not rotate at all in any direction.

    The script is attached to a Capsule which is what is doing the rotating, the capsule has two children, the character model, and the pivot point that my camera uses to rotate with.

    Any help or advice is greatly appreciated, let me know if you need anymore information from me.
     
  2. TimmyTheTerrible

    TimmyTheTerrible

    Joined:
    Feb 18, 2017
    Posts:
    186
    Do something like this for the players rotation:

    Code (CSharp):
    1. Vector3 v = Camera.main.transform.forward;
    2.  
    3. v.y = 0f;
    4. v.Normalize();
    5.  
    6. Quaternion rotation = Quaternion.LookRotation(v);
    7.  
    8. float smoothing = 5f;
    9.  
    10. transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * smoothing);
     
  3. Hotpockets26

    Hotpockets26

    Joined:
    Dec 16, 2017
    Posts:
    32
    Thanks for the code Timmy, I figured it out before you posted it. I ended up creating another game object to copy the Y rotation of the cameras pivot, and setting the forward based on the new object.

    Code (CSharp):
    1.     // Update is called once per frame
    2.     void Update()
    3.     {
    4.  
    5.         // WASD input with speed applied
    6.         float moveH = Input.GetAxis("Horizontal") * moveSpeed;
    7.         float moveV = Input.GetAxis("Vertical") * moveSpeed;
    8.  
    9.         // Stores the movement in a Vector3 so that it can be used where a Vector3 is needed ////GET RID OF new Vector3////
    10.         _moveDirection = new Vector3(moveH, 0f, moveV);
    11.  
    12.         // Copies the Camera Pivot's Y Rotation.
    13.         Quaternion camYRot = Quaternion.Euler(0, camPivot.transform.eulerAngles.y, 0);
    14.  
    15.         // Sets the Camera Pivot's Y Rotation object's Y rotation to be equal to the Y rotation of the Camera Pivot Object.
    16.         this.camYRot.transform.rotation = camYRot;
    17.  
    18.         // Sets the Camera Pivot's Position to be the same as the Camera Pivot's position.
    19.         this.camYRot.transform.position = camPivot.transform.position;
    20.  
    21.         // Sets the inputs forward direction to be dependent on the Camera Pivot's Y Rotation Object's Y rotation.
    22.         _moveDirection = this.camYRot.transform.TransformDirection(_moveDirection);
    23.  
    24.         // Makes sure the character doesnt bounce back to the forward position when no input is pressed
    25.         if (_moveDirection != Vector3.zero)
    26.         {
    27.             // Rotates the player toward the WASD input.
    28.             transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(_moveDirection), capsuleRotSpeed * Time.deltaTime);
    29.         }
    30.  
    31.         // Applies gravity to the Y axis
    32.         _moveDirection.y = Physics.gravity.y * gravityWeight * Time.deltaTime;
    33.  
    34.         //transform.rotation = Quaternion.Euler(testRot);
    35.  
    36.         // Moves the player with the _moveDirection Vector3's input, and applies Time.deltaTime
    37.         _controller.Move(_moveDirection * Time.deltaTime);
    38.  
    39.     }
    I don't know how efficient this is. I plan on cleaning it up more and trying your method out to see which way I like more.

    Thank you