Gun leaning script leaning player in wrong direction

Hello,
I am trying to make a gun lean script so that whenever I click the Q key it leans my player left and it will do the opposite for the E key. But I have a issue where I can only lean into the right directions (left and right) if I am facing a certain direction. So if I am facing a different direction it will lean me forwards and backwards instead of left and right. I have attached my code and a google drive link to my video that contains my issue below just to shot what I mean.
Google Drive: Issue - Google Drive (Copy and paste into browser, you should have access to the folder, it also does not contain any viruses)
Code:
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class GunLean : MonoBehaviour { [SerializeField] private float Amount; [SerializeField] private float LerpTime; [SerializeField] private Quaternion initalRoatation; [SerializeField] private bool IsLeaningLeft; [SerializeField] private bool IsLeaningRight;
private void Awake() { initalRoatation = transform.rotation; }
private void Update() { if (Input.GetKey(KeyCode.Q) && !IsLeaningRight) { IsLeaningLeft = true; Quaternion newRot = Quaternion.Euler(transform.localRotation.x, transform.localRotation.y, transform.localRotation.y + Amount); transform.localRotation = Quaternion.Slerp(transform.localRotation, newRot, Time.deltaTime LerpTime); } else { IsLeaningLeft = false; transform.localRotation = Quaternion.Slerp(transform.localRotation, initalRoatation, Time.deltaTime LerpTime); }
if (Input.GetKey(KeyCode.E) && !IsLeaningLeft)
{
IsLeaningRight = true;
Quaternion newRot = Quaternion.Euler(transform.localRotation.x, transform.localRotation.y, transform.localRotation.y - Amount);
transform.localRotation = Quaternion.Slerp(transform.localRotation, newRot, Time.deltaTime * LerpTime);
}
else
{
IsLeaningRight = false;
transform.localRotation = Quaternion.Slerp(transform.localRotation, initalRoatation, Time.deltaTime * LerpTime);
}
} }

Hi! The problem seems to be the fact that you are reading from transform.localRotation - a quaternion - instead of transform.localEulerAngles - a vector 3 - (at least when defining newRot).

Quaternions have 4 numbers ranging from -1 to 1 and don’t clearly relate to the three Euler angles most of us are used to. In an unfortunate coincidence, the numbers making up Vector3s - x, y and z - happen to be named the same as some of the induvial numbers of a quaternion - w, x, y and z -, which makes this mixup more common than it should be.

This means instead of rotating your player to something like this:

Quaternion newRot = Quaternion.Euler(
    transform.localEulerAngles.x, 
    transform.localEulerAngles.y, 
    transform.localEulerAngles.z + Amount);

Your code was doing something like this (obviously simplified):

Quaternion newRot = Quaternion.Euler(Random.Range(-1, 1), Random.Range(-1, 1), Random.Range(-1, 1) + Amount);

Which explains why your player was only rotating along the Z axis: It wasn’t taking into account its own rotation.

So just use Euler angles when accessing the individual axes (x, y and z), and use quaternions for rotations as a whole e.g. when lerping.

P.S. You were also making newRot with the (x, y, y) components instead of (x, y, z)

Hope this helps!

public class GunLean : MonoBehaviour
{
public GameObject player; // You could just set in the Inspector, or
GameObject playerBody;

	 Quaternion myRotation;
 
     private void Start()
     {
		 // Find it through the script
		 player = GetComponent<PlayerScript>().transform.gameObject;
		 
		 // Once the parent object is found, get the body
		 playerBody = player.transform.Find("Body").gameObject;
     }
 
     private void Update()
     {
		 // get the body's Z, whether negative or positive, due to "Body" movement
		 myRotation = playerBody.transform.rotation;
		 
		 // then tell the gun to rotate with that Quaternion
		 transform.localRotation = myRotation;
		 
		 // if rotation is weird, it's because it's not a child of correct rotation
		 // you could use this as an example, test out the first method though
		 transform.position = parentObj.transform.position - (parentObj.transform.forward / float forwardBackOffset) + Vector3(0, float heightOffset, 0);
         transform.rotation = Quaternion.Euler(objRotation + parentObj.transform.rotation.eulerAngles);
		 
		 
         if (Input.GetKey(KeyCode.Q))
         {} // not sure if you still want these, as it rotates if "Body" does
         
         if (Input.GetKey(KeyCode.E))
         {} // ditto^
     }
 }

I just wrote this up quickly, you are definitely going to need to set the variables. But see if this doesn’t help you out some :slight_smile: @AshCodes202