1
\$\begingroup\$
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class MeshGenerator : MonoBehaviour
{
    public GameObject meshPrefab;
    public Vector3[] newVertices;
    public Vector2[] newUV;
    public int[] newTriangles;

    private List<Vector3> verticesList = new List<Vector3>();
    private List<Vector2> uvsList = new List<Vector2>();
    private List<int> trianglesList = new List<int>();
    private GameObject go;

    private void Start()
    {
        Mesh meshprefab = meshPrefab.GetComponent<MeshFilter>().sharedMesh;
        newVertices = meshprefab.vertices;
        newTriangles = meshprefab.triangles;

        for (int i = 0; i < newVertices.Length - 2; i++)
        {
            DrawLine(newVertices[i], newVertices[i + 1], Color.red);
            DrawLine(newVertices[i + 1], newVertices[i + 2], Color.red);
            DrawLine(newVertices[i + 2], newVertices[i], Color.red);
        }
    }

    void DrawLine(Vector3 start, Vector3 end, Color color, float duration = 0.2f)
    {
        go = GameObject.Find("Lines");
        GameObject myLine = new GameObject();
        myLine.transform.parent = go.transform;
        myLine.transform.position = start;
        myLine.AddComponent<LineRenderer>();
        LineRenderer lr = myLine.GetComponent<LineRenderer>();
        lr.material = new Material(Shader.Find("Particles/Alpha Blended Premultiply"));
        lr.startColor = color;
        lr.endColor = color;
        lr.startWidth = 0.05f;
        lr.endWidth = 0.05f;
        lr.useWorldSpace = false;
        lr.SetPosition(0, start);
        lr.SetPosition(1, end);
    }

    private void Update()
    {
        var p = go.transform.eulerAngles;
        p.x += 1;
        go.transform.eulerAngles = p;
    }
}

This is the rotation part:

private void Update()
    {
        var p = go.transform.eulerAngles;
        p.x += 1;
        go.transform.eulerAngles = p;
    }

It's rotating 360 degrees once, then it stops rotating but keeps shaking like it's trying to keep rotating but something keeps it from continue.

\$\endgroup\$
1
  • \$\begingroup\$ Hint: print the value of eulerAngles before and after setting it. It's not just a variable, it's a getter, so what you put in it last frame isn't necessarily what you'll find in it this frame. \$\endgroup\$ – DMGregory Apr 22 '18 at 3:04
4
\$\begingroup\$

Euler angles are used to print a human-readable description of the object's orientation in the Inspector, but they're not the underlying model that Unity uses.

That means that when you set an orientation in Euler angles, Unity transforms that description into its internal representation (likely a quaternion). When you then ask for Euler angles in the next frame, it calculated new Euler angles from that internal model.

Because each orientation has many possible Euler angle representations (eg. add or remove a multiple of 360 on any axis and you get the same orientation), Unity has to have a policy about which one to return - and you're not guaranteed to get back the same one you put in. There have to be wrap-around points somewhere, where the angles you get back are very different from those you put in.

In this case, as you reach (91, 0, 0), Unity will return this orientation as (89, 180, 180) - an equivalent way to describe that orientation, with |x| <= 90.

But there's one crucial difference:

  • near (90, 0, 0), increasing x causes the object to pitch downward

  • near (90, 180, 180), increasing x causes the object to pitch upward

That's because order of rotations matters, and in Unity's angle system, the y rotation is applied first. So the object rotates 180 degrees around y, flipping the local x axis around to the other side, then rotates about the x axis, then finally rotates around the z axis to undo the earlier flip. But by that time it's already applied the pitch in the opposite direction to what you were expecting.

This flip in pitch direction means in one frame your object pitches down to (90+e, 0, 0), then in the next frame it starts from (90-e, 180, 180) and the +1 takes it back the other way to (89+e, 0, 0). So it sits there vibrating, constantly bouncing between the two orientations.

For this reason, you should be very careful when trying to calculate an orientation by doing math on Euler angles. It's rarely what you really want.

Instead, if you want to rotate 1 degree on the local x axis, don't try to calculate the Euler angles yourself, just tell Unity you want to rotate 1 degree on the local x axis:

transform.Rotate(1, 0, 0); // Equivalently, transform.Rotate(Vector3.right, 1);

Fewer lines, and actually does the right thing.

Don't forget to correct for framerate though, so you probably want instead:

transform.Rotate(pitchSpeed * Time.deltaTime, 0 , 0);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.