Simpler IsStanding Calculation

Hey, I figured I’d put out my solution to calculating IsStanding, as I think it simplifies the other solutions I’ve seen. I’d also like some feedback, as I’m worried my solution my be oversimplifying the problem, and be missing something.

public bool IsStanding()
{
	float tiltAngle = Quaternion.Angle(transform.rotation, Quaternion.identity);
	return (tiltAngle < standingThreshold);
}

This one uses Quaternion.Angle, which is a static method that just gives the difference between two rotations in degrees. It seems to account for negative rotation (like getting 355 when the rotation is -5) and it always returns the value as absolute. It compares the Pin’s angle to Quaternion.identity, which I understand as the equivalent of “up” in world space.

Is there something I’m missing with this? Any feedback would be appreciated, as I’m quite new to the concepts of Quaternions and Euler angles.

3 Likes

I used quaternions too, it is way better performance wise and works better too. Vector3 isn’t very recommended to handle rotations.

Note that unity save rotations as quaternions (just turn on the debug mode on the inspector that you will see it).

Your approach is the “right one”, the one shown in the class is the “oversimplified” (quaternions is a more advanced tool, probably it is the reason why Ben avoided using it here)

If you want to learn more about quats, I highly recommend this video:

2 Likes

I actually did find an issue with my solution, in that it didn’t account for twist around the Y axis triggering false positives of IsStanding.

I solved that by converting rotation to euler first, then factoring out Y and converting back into a quaternion before calculating the angle:

	public bool IsStanding()
	{
		// Ignore the Y axis (twist) of the pin, only falling (X/Z) axes by splitting the
		// rotation quaternion into X,Y,Z and scaling out the Y axis (multiply by 1,0,1)
		Vector3 eulerWithoutTwist = Vector3.Scale(transform.rotation.eulerAngles, new Vector3(1, 0, 1));

		// Create a quaternion to store the rotation without the twist
		Quaternion rotationWithoutTwist = Quaternion.Euler(eulerWithoutTwist);

		// Get the angle between pin's rotation and world's "up"
		float tiltAngle = Quaternion.Angle(rotationWithoutTwist, Quaternion.identity);

		return (tiltAngle < standingThreshold);
	}
4 Likes

Never thought about this problem,

Nice solution!

1 Like

Awesome Video.

Thanks!

@bendman
Love this solution. Thanks for sharing.

Fabulous

Privacy & Terms