How to rotate locally in Y axis

Viewed 163

Hello I have character control like astronaut in zero gravity but I want to rotate it locally in y axis but it can't rotate. I tried rotating it in y axis but the player is rotating relative to world. i want it relative to the object. thanks for help.

here is my script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class Astronaut : MonoBehaviour
{
    private static AstronautControls astronautControls;
    public Rigidbody rb;
    public float force;
    public float torque;
    public Vector2 move;
    float rotateHorizontal;
    float rotateVertical;
    float upDown;
    public PlayerInput playerInput;

    private void Awake()
    {
        astronautControls = new AstronautControls();
    }


    private void OnEnable()
    {
        astronautControls.Enable();
    }

    private void OnDisable()
    {
        astronautControls.Disable();
    }

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {
        Move();
        MoveUpDown();
        RotateHorizontal();
        RotateVertical();
    }

    private void Move()
    {
        move = playerInput.actions["Move"].ReadValue<Vector2>();
        rb.AddForce(transform.forward * force * move.y * Time.deltaTime);
        rb.AddForce(transform.right * force * move.x * Time.deltaTime);
        rb.AddForce(transform.up * force * upDown * Time.deltaTime);
    }

    private void MoveUpDown()
    {
        upDown = playerInput.actions["MoveVertical"].ReadValue<float>();
        rb.AddForce(transform.up * force * upDown * Time.deltaTime);
    }

    private void RotateHorizontal()
    {
        rotateHorizontal = playerInput.actions["RotateHorizontal"].ReadValue<float>();
        MouseLook.Z += rotateHorizontal;
    }

    //here is the problem when i rotate it seems it has gimbal lock or something i want local rotate relative to the player
    private void RotateVertical()
    {
        rotateVertical = playerInput.actions["RotateVertical"].ReadValue<float>();
        MouseLook.Y += rotateVertical;
    }
}

and here is the mouse look

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;


public class MouseLook : MonoBehaviour
{
    Mouse mouse;
    public static float X;
    public static float Y;
    public static float Z;
    const float MIN_X = -90f;
    const float MAX_X = 90f;
    const float MIN_Y = -180f;
    const float MAX_Y = 180f;
    public static Vector3 euler;

    public float Sensitivity;
 
    void Awake()
    {
        mouse = Mouse.current;
        euler = transform.rotation.eulerAngles;
        X = euler.x;
        Y = euler.y;
        Z = euler.z;
    }

    void Update()
    {
        X -= mouse.delta.y.ReadValue() * (Sensitivity * Time.deltaTime);
        if (X < MIN_X) X = MIN_X;
        else if (X > MAX_X) X = MAX_X;
        Y += mouse.delta.x.ReadValue() * (Sensitivity * Time.deltaTime);
        if (Y < MIN_Y) Y = MIN_Y;
        else if (Y > MAX_Y) Y = MAX_Y;
        transform.parent.localRotation = Quaternion.Euler(X, Y, Z);
    }
}

settings for my rigidbody

enter image description here

1 Answers

I mentioned a few solutions on how to rotate an object in local space, but I believe the one that should work for your implementation would be the last one. To showcase it working, here is a simple test script:

using UnityEngine;

public class TestScript2 : MonoBehaviour
{
    private float changeInX = 0f;
    private float changeInY = 10f;
    private float changeInZ = 0f;

    private void Update()
    {
        if(Input.GetKey(KeyCode.Space))
        {
            transform.rotation = transform.rotation * Quaternion.Euler(changeInX, changeInY, changeInZ);
        }
    }
}

All it will do is rotate an object whenever the Space key is pressed. The object I have set up with this script is childed to a rotated object. Here is a gif showing the one cube childed to another rotating around its local Y-axis.

Example

If you would like all axes to rotate locally, I believe inserting a changeInX and changeInZ will result in similar results to the gif, where the rotations are applied locally.

Related