get Pitch and Roll values from object

I’m making a rollercoaster game, where I need to get the roll & Pitch values from an object (cube), how do I get those values?
I tried… but nothing, any clue?

 var tempRight = transform.right;
 tempRight.y = 0;
float pitch = Vector3.Angle(transform.right, tempRight)*Mathf.Sign(transform.right.y);

First of all keep in mind that pitch, yaw and roll (euler angles) is not a unique way to represent a rotation in 3d space. There are always at least two ways you can set your angles to achieve the same rotation. That’s why it’s impossible to get a clear answer for both angles. For example if your up vector points straigned down, do you currently perform a roll (around the local z axis) or a looping (around the local x axis)?

Anyways, to get at least a continuous angle for both, you want to have at least one world reference. In both cases i recommend the up vector.

For pitch (around local x-axis):

var right = transform.right;
right.y = 0;
right *= Mathf.Sign(transform.up.y);
var fwd = Vector3.Cross(right, Vector3.up).normalized;
float pitch = Vector3.Angle(fwd, transform.forward) * Mathf.Sign(transform.forward.y);

For roll (around local forward axis)

var fwd = transform.forward;
fwd.y = 0;
fwd *= Mathf.Sign(transform.up.y);
var right = Vector3.Cross(Vector3.up, fwd).normalized;
float roll = Vector3.Angle(right, transform.right) * Mathf.Sign(transform.right.y);

Note that in those cases pitch and roll are independet from each other. However if you perform a looping and you pass the 90° mark (either up or down) the roll will suddenly switch from 0 to 180 or -180. Likewise when you perform a roll, when you pass ±90° the pitch will suddenly switch from 0 to 180 or -180

So those two methods are just a way to determine the current pitch / roll values but not to determine which kind of movement you carry out. For this you would need to analyse the movement over time.

Though there are edge cases where you can’t tell if you should call it a roll or a looping. If you have a “screw” looping at a 45° angle you equally perform a looping as well as a roll. It’s in general hard to define pitch and roll in absolute values. If you bank your cart 90° (so it lies on the side) and perform a “flat” looping, does that count as pitch? Locally it would, globally it doesn’t

Hi, @Bunny83 I’m looking at this, and trying to think if it’s worth the extra complication:

 var right = transform.right;
 right.y = 0;
 right *= Mathf.Sign(transform.up.y);
 var fwd = Vector3.Cross(right, Vector3.up).normalized;

If you take the cross of the right vector and the up vector, I think you’ll get the forward vector. So I might go:

  var fwd = transform.right;
  fwd.y = 0;

which would cut out the middle.

Assuming I’m correct that they get the same result. Maybe there’s a useful difference that I’m not thinking of?
hope you help me with this issue
thank you

You can also get the same result like this:

    pitch = (transform.rotation * Quaternion.Euler(180, 0, 0)).eulerAngles.x;
    roll = (transform.rotation * Quaternion.Euler(0, 0, 180)).eulerAngles.z;

Also it’s possible to do this

    pitch = (transform.rotation * Quaternion.Euler(180, 0, roll)).eulerAngles.x;
    roll = (transform.rotation * Quaternion.Euler(pitch, 0, 180)).eulerAngles.z;

Which gives a result that’s more like an absolute pitch and roll value (not affected by the rotation of the other)

However for most use cases the most robust way to get pitch and roll is using a Quaternion to Euler formula that works with the x,y,z,w components of the Quaternion directly, see this answer for more info