unity引擎之Rotation旋转

  • Post author:
  • Post category:其他

一、Unity中的Rotation

        在unity中,旋转的表示的常用方法之一,是一个三维向量(x、y、z):

图1、Unity中的旋转

        实际上这是欧拉角。这三个分量分别是绕x轴、y轴、z轴旋转的角度。

        要对一个object进行旋转,还可以通过代码:

transform.Rotate(x, y, z);

这里,如果看过《坐标系》一文,就会产生以下两个疑问:

        1)x轴、y轴、z轴指的是那组基?是世界坐标系下的xyz轴,还是本地坐标系下的xyz轴?

        2)旋转的正方向是如何确定的?

        下面分别讨论。

二、旋转轴:静态欧拉角和动态欧拉角

        首先回答第一个问题:到底哪个是旋转轴。这又要分为 3种情况。

1、旋转轴:Editor 中 Transform的旋转数值

        对这个情况来说,其显示的旋转轴既不是世界坐标系的坐标轴,也不是本地坐标系的坐标轴。Editor中transform的旋转轴是父节点的坐标轴。这点在editor中看的非常明显,因此不再赘述。

2、旋转轴:在script中使用 rotate 函数,在 Space.Self 中旋转

        Rotate 函数有两个入参:

public void Rotate(Vector3 eulerAngles, Space relativeTo = Space.Self);

 第二个入参的取值有两种:Space.Self 或者 Space.World。我们先看默认的 Self 的情况。使用下面的一段简单的代码来进行测试:

public class TestRotate : MonoBehaviour {
 
    public Space rotateSpace;
 
    // Update is called once per frame
    void Update () {
        if (Input.GetKeyDown(KeyCode.R))
            transform.Rotate(new Vector3(0, 10, 0), rotateSpace);
    }
}

场景中进行测试的是一个圆柱体,其父节点的旋转为(30,30,0),圆柱体初始的旋转为(30,0,0),每次按下R键,就会在Space.Self 下绕 Y轴旋转10度,则结果为:

 

 

图2、在Space.Self中旋转

 

        可以看到,圆柱体是绕着本地坐标系的Y轴旋转的。使用Space.Self进行旋转,旋转轴就是本地坐标系的坐标轴

 

3、在script中使用 rotate 函数,在 Space.World 中旋转

        下面测试 Space.World 

图3、在Space.World中旋转

        注意到这里 Parent 的 Y轴并不是 world 的 Y 轴,而这里的圆柱体明显是绕着世界坐标系下的 Y 轴旋转的,所以如代码所述,使用Space.World旋转,旋转是绕着世界坐标系的坐标轴旋转的

 

4、静态欧拉角和动态欧拉角

        前面说到的旋转轴的问题,在数学上有对应的概念。这就是所谓的静态欧拉角和动态欧拉角。

        所谓静态欧拉角,就是其旋转轴使用的是静止不动的参考系。动态欧拉角,使用的是刚体本身作为参考系,因而会随着刚体的旋转而旋转。

        因此,再看看前面的三种情况,使用Space.World旋转,以及 Editor 中的旋转,是静态欧拉角;使用Space.self,是动态欧拉角。

代码示例:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestRotate : MonoBehaviour {


    private bool isTransRotate; //绕父部件旋转
    private bool isSelfRotate;  //绕自身旋转
    private bool isWorldRotate; //绕世界坐标系旋转


    private string transRotateInfo;
    private string selfRotateInfo;
    private string worldRotateInfo;

    public float speed;
    private GameObject objCylinder;



	// Use this for initialization
	void Start () {
        isTransRotate = false;
        isSelfRotate = false;
        isWorldRotate = false;

        transRotateInfo = "绕圆柱体旋转";
        selfRotateInfo = "绕自身旋转";
        worldRotateInfo = "绕世界坐标系旋转";

        speed = 200;
        objCylinder = GameObject.Find("Cylinder");
    }
	
	// Update is called once per frame
	void Update () {

        if (isTransRotate) {
            //gameObject.transform.Rotate(0,Time.deltaTime*speed,0);
            //gameObject.transform.Rotate(Vector3.up* Time.deltaTime * speed);
            gameObject.transform.RotateAround(objCylinder.transform.position, Vector3.up, Time.deltaTime * speed);
        }

        if (isSelfRotate) {
            gameObject.transform.Rotate(new Vector3(0,10,0), Time.deltaTime * speed, Space.Self);
        }

        if (isWorldRotate) {
            gameObject.transform.Rotate(new Vector3(0,10,0), Time.deltaTime * speed,Space.World);
        }

	}

    private void OnGUI()
    {
        if (GUILayout.Button(transRotateInfo, GUILayout.Height(50))) {
            if (!isTransRotate)
            {
                isTransRotate = true;
                transRotateInfo = "停止绕圆柱体旋转";
            }
            else {
                isTransRotate = false;
                transRotateInfo = "绕圆柱体旋转";
            }
        }

        if (GUILayout.Button(selfRotateInfo, GUILayout.Height(50)))
        {
            if (!isSelfRotate)
            {
                isSelfRotate = true;
                selfRotateInfo = "停止绕自身旋转";
            }
            else
            {
                isSelfRotate = false;
                selfRotateInfo = "绕自身旋转";
            }
        }

        if (GUILayout.Button(worldRotateInfo, GUILayout.Height(50)))
        {
            if (!isWorldRotate)
            {
                isWorldRotate = true;
                worldRotateInfo = "停止绕世界坐标系旋转";
            }
            else
            {
                isWorldRotate = false;
                worldRotateInfo = "绕世界坐标系旋转";
            }
        }

    }

}

 


版权声明:本文为weixin_40449071原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。