Problem with eulerAngles ?

Hi
I’m facing issue with eulerAngles of my object. What i need to do is to make a max rotation angel that can’t pass it. one using time till reach 0 value. other have max angel.

public float z_max;

    // Update is called once per frame
    void Update () {

        z_max = gameObject.transform.eulerAngles.z;

        if (gameObject.transform.eulerAngles.z >= 30.0f) {
            gameObject.transform.eulerAngles.z = 30f; // max angel is 30
        }

        if (gameObject.transform.eulerAngles.z <= -30.0f) {
            gameObject.transform.eulerAngles.z =  Time.deltaTime; // count till 0 ?
        }
       
    }

Yes, there are some fundamental problems with Euler angles, and you shouldn’t use them.

1 Like

It doesn’t help me. what else can help me ?
My car keeps fall down if it jumps of a hill or turn right/left ?
that’s why i need to make a max angle.

Lower the centre of gravity on the car.

the gravity is works good. i don’t want to change it.
I need to make max angle for the z value. why I can’t do that ?

Did you read the blog StarManta showed you?

Clamping via eulerAngles isn’t effective due to the fact euler angles don’t work like that.

  1. 350 degrees is a valid angle that might come out, but that’s technically -10 degrees as well, so you might end up setting your angle to 30 when it’s -10

  2. if there is rotation around x or y, z is wayyyy not accurate to your clamping. For example if you rotate to 90 around the x-axis, you’ve locked the y and z gimbals, and any rotation around y is the same as any negative rotation around z. This implication means that if there is any rotation around the x, your z might return a less than accurate value relative to your desired clamping.

If you ONLY plan to rotate around 1 axes, then point 2 won’t matter. And what you can do is normalize your z angle before modifying it. Basically pass your z value into this wrap function:

        public static float Wrap(float value, float max, float min)
        {
            max -= min;
            if (max == 0)
                return min;

            return value - max * (float)Math.Floor((value - min) / max);
        }

Using 180 as the max, and -180 as the min.

Wrap(gameObject.transform.eulerAngles.z, 180, -180);

Lastly… there is some bad logic in your code.

transform.eulerAngles returns a COPY of the rotation.

Setting a field on that vector doesn’t actually update the transform.

This is just a quark of the fact that eulerAngles is a ‘property’ and not a ‘field’, and the way C# works, you can’t do this.

So what you need to do is:

Vector3 angles = transform.eulerAngles;
angles.z = Wrap(angles.z, 180f, -180f);
if(angles.z > 30f) angles.z = 30f;
if(angles.z <= -30f) angles.z = Time.deltaTime; //no idea what this is about
transform.eulerAngles = angles;

But again… rotating in the x and y will screw up your z, and you should be using quaternion’s in that regard.

1 Like

I’m not talking about adjusting the world gravity. Lower the centre of gravity on the rigidbody, although Unity refere to it as center of mass.

1 Like