17.Transform变换组件角度和旋转

17.Unity重要组件和API-Transform角度和旋转


17.1 知识点

角度相关

rotation变量 返回旋转的四元数

// 一个 Quaternion,用于存储变换在世界空间中的旋转。
print(this.transform.rotation);

eulerAngles变量 相对世界坐标角度

// 以欧拉角表示的旋转(以度为单位)。
print(this.transform.eulerAngles);

localEulerAngles变量 相对父对象角度

// 以欧拉角表示的相对于父变换旋转的旋转(以度为单位)。
print(this.transform.localEulerAngles);

注意:设置角度和设置位置一样,不能单独设置 xyz,要用一个 Vector3 赋值一起设置。

// 如果我们希望改变的角度是面板上显示的内容,那一定是改变相对父对象的角度
// this.transform.localEulerAngles = new Vector3(10, 10, 10);
// 如果我们希望改变的角度是相对于世界坐标的绝对角度,那一定是改变相对世界坐标角度
// this.transform.eulerAngles = new Vector3(10, 10, 10);

旋转相关

  • 旋转的代码一般放在 Update 内。
  • 手动设置 eulerAngles 或 localEulerAngles 进行计算计算(省略不讲了,和位置一样,不停改变角度即可)。

Rotate方法 自转

使用 Transform.Rotate 以各种方式旋转 GameObjects。通常以欧拉角而不是四元数提供旋转。

  • Rotate 方法重载,设置 Vector3 变量确定每个轴每一帧旋转具体转多少度:
// 第一个参数是要应用的旋转,每一帧旋转的角度。
// 第二个参数确定在游戏对象本地还是相对于世界空间中的场景来旋转游戏对象。
// 默认不填,就是相对于自己坐标系进行的旋转。
// 如果填写,可以填写相对于世界坐标系进行旋转。
// this.transform.Rotate(new Vector3(0, 100, 0) * Time.deltaTime);
// this.transform.Rotate(new Vector3(0, 10, 0) * Time.deltaTime, Space.World);
  • Rotate 方法重载,相对于某个轴每一帧旋转具体转多少度:
// 参数一是要应用旋转的轴,是相对哪个轴进行转动。
// 参数二是要应用的旋转度数,每一帧旋转的角度。
// 参数三确定在游戏对象本地还是相对于世界空间中的场景来旋转游戏对象。
// 默认不填,就是相对于自己的坐标系进行旋转。
// 如果填,可以填写相对于世界坐标系进行旋转。
// this.transform.Rotate(Vector3.right, 10 * Time.deltaTime);
// this.transform.Rotate(Vector3.right, 10 * Time.deltaTime, Space.World);

RotateAround方法 相对于某一个点转

// 将变换围绕穿过世界坐标中的 point 的 axis 旋转 angle 度。
// 参数一:相当于哪一个点转圈圈。
// 参数二:相对于那一个点的哪一个轴转圈圈。
// 参数三:每一帧旋转具体转多少度,旋转速度 * 时间。
// this.transform.RotateAround(Vector3.zero, Vector3.right, 10 * Time.deltaTime);

总结

  • 角度相关和位置相关差不多。
  • 如何得到角度:通过 transform 可以得到相对于世界坐标系和相对于父对象的。
  • 如何自转和绕着别人赚:Rotate 方法和 RotateAround 方法。

17.2 知识点代码

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

public class Lesson17_必不可少Transform_角度和旋转 : MonoBehaviour
{
    void Start()
    {
        #region 知识点一 角度相关

        //rotation变量 返回旋转的四元数 
        //一个 Quaternion,用于存储变换在世界空间中的旋转。
        print(this.transform.rotation);

        //eulerAngles变量 相对世界坐标角度
        //以欧拉角表示的旋转(以度为单位)。
        print(this.transform.eulerAngles);

        //localEulerAngles变量 相对父对象角度
        //以欧拉角表示的相对于父变换旋转的旋转(以度为单位)。
        print(this.transform.localEulerAngles);

        //注意:设置角度和设置位置一样 不能单独设置xyz 要用一个Vector3赋值一起设置
        //如果我们希望改变的 角度 是面板上显示的内容 那一定是改变 相对父对象的角度
        //this.transform.localEulerAngles = new Vector3(10, 10, 10);
        //如果我们希望改变的 角度 是相对于世界坐标的绝对角度 那一定是改变 相对世界坐标角度
        //this.transform.eulerAngles = new Vector3(10, 10, 10);

        #endregion
    }

    void Update()
    {
        #region 知识点二 旋转相关

        //旋转的代码一般放在Update内

        //手动设置eulerAngles或localEulerAngles进行计算计算(省略不讲了 和位置一样 不停改变角度即可)

        //Rotate方法 自转
        //使用 Transform.Rotate 以各种方式旋转 GameObjects。通常以欧拉角而不是四元数提供旋转。
        //Rotate方法重载 设置Vector3变量 确定每个轴 每一帧旋转具体转多少度
        //第一个参数 要应用的旋转。每一帧旋转的角度 
        //第二个参数 确定在游戏对象本地还是相对于世界空间中的场景来旋转游戏对象。
        //默认不填 就是相对于自己坐标系 进行的旋转
        //如果填 可以填写相对于 世界坐标系进行旋转
        //this.transform.Rotate(new Vector3(0, 100, 0) * Time.deltaTime);
        //this.transform.Rotate(new Vector3(0, 10, 0) * Time.deltaTime, Space.World);
        //Rotate方法重载 相对于某个轴 每一帧旋转具体转多少度
        //参数一:要应用旋转的轴。是相对哪个轴进行转动
        //参数二:要应用的旋转度数。每一帧旋转的角度。
        //参数三:确定在游戏对象本地还是相对于世界空间中的场景来旋转游戏对象。
        //默认不填 就是相对于自己的坐标系 进行旋转
        //如果填  可以填写相对于 世界坐标系进行旋转
        //this.transform.Rotate(Vector3.right, 10 * Time.deltaTime);
        //this.transform.Rotate(Vector3.right, 10 * Time.deltaTime, Space.World);

        //RotateAround方法 相对于某一个点转
        //将变换围绕穿过世界坐标中的 point 的 axis 旋转 angle 度。
        //参数一:相当于哪一个点 转圈圈
        //参数二:相对于那一个点的 哪一个轴转圈圈
        //参数三:每一帧旋转具体转多少度 旋转速度 * 时间
        //this.transform.RotateAround(Vector3.zero, Vector3.right, 10 * Time.deltaTime);

        #endregion
    }

    //总结
    //角度相关和位置相关 差不多
    //如何得到角度:通过transform 可以得到相对于世界坐标系和相对于父对象的
    //如何自转和绕着别人赚:Rotate方法和RotateAround方法
}

17.3 练习题

使用你之前创建的坦克预设体,在坦克下面加一个底座(用自带几何体即可)让其可以原地旋转,类似一个展览台

创建一个圆柱底座,上面放坦克预设体

在脚本Update里添加旋转代码,脚本挂载到底座上,设置旋转变量

//Update内
//脚本挂载到底座上
this.transform.Rotate(Vector3.up, rotateSpeed * Time.deltaTime);

在第一题的基础上,让坦克的炮台可以自动左右来回旋转,炮管可以自动上下抬起

给坦克添加炮尾位置,方便控制炮管上下移动

角度示意图

在脚本Update里添加旋转代码,创建旋转变量和Transform变量,设置旋转变量,Transform变量拖拽赋值

//Update内

//注意:
//通过head.localEulerAngles得到的角度 不会出现负数的情况 
//虽然界面上显示出了负数 但是 通过代码获取 始终 只能得到0~360之间的数

//炮台左右来回旋转
head.Rotate(Vector3.up, headRotateSpeed * Time.deltaTime);

//localEulerAngles只能是0到360 那就只有特殊判断了
//不是315-360之间且大于45且旋转速度大于0
if (!(head.localEulerAngles.y >= 315 && head.localEulerAngles.y <= 360) &&
    head.localEulerAngles.y >= 45 && headRotateSpeed > 0)
    headRotateSpeed = -headRotateSpeed;
//不是0-45之间且小于315且旋转速度小于0
else if (!(head.localEulerAngles.y <= 45 && head.localEulerAngles.y >= 0) &&
          head.localEulerAngles.y <= 315 && headRotateSpeed < 0)
    headRotateSpeed = -headRotateSpeed;

//炮管上下来回旋转
gunTail.Rotate(Vector3.right, gunTailRotateSpeed * Time.deltaTime);


//localEulerAngles只能是0到360 那就只有特殊判断了
//不是350-360之间且大于10且旋转速度大于0
if (!(gunTail.localEulerAngles.x >= 350 && gunTail.localEulerAngles.x <= 360) &&
    gunTail.localEulerAngles.x >= 10 && gunTailRotateSpeed > 0)
    gunTailRotateSpeed = -gunTailRotateSpeed;
//不是0-10之间且小于350且旋转速度小于0
else if (!(gunTail.localEulerAngles.x <= 10 && gunTail.localEulerAngles.x >= 0) &&
          gunTail.localEulerAngles.x <= 350 && gunTailRotateSpeed < 0)
    gunTailRotateSpeed = -gunTailRotateSpeed;

请用3个球体,模拟太阳、地球、月亮之间的旋转移动

创建三个球体代表太阳地球月亮

在脚本Update里添加旋转代码,创建旋转变量和创建太阳地球月亮Transform变量,设置旋转变量,Transform变量拖拽赋值

//Update内

//太阳自转
sun.Rotate(Vector3.up, 10 * Time.deltaTime);
//地球自转
earth.Rotate(Vector3.up, 10 * Time.deltaTime);
//月亮自转
moon.Rotate(Vector3.up, 10 * Time.deltaTime);

//地球公转
earth.RotateAround(sun.position, Vector3.up, 10 * Time.deltaTime);

//月亮绕地球转
moon.RotateAround(earth.position, Vector3.up, 10 * Time.deltaTime);

17.4 练习题代码

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

public class Lesson17_练习题 : MonoBehaviour
{
    public float rotateSpeed = 20;
    public float headRotateSpeed = 20;
    public float gunTailRotateSpeed = 20;
    //头部位置信息
    public Transform head;
    public Transform gunTail;

    public Transform earth;
    public Transform sun;
    public Transform moon;
    
    void Start()
    {
        #region 练习题一 
        //1.使用你之前创建的坦克预设体,在坦克下面加一个底座(用自带几何体即可)
        //让其可以原地旋转,类似一个展览台
        #endregion

        #region 练习题二 
        //2.在第一题的基础上,让坦克的炮台可以自动左右来回旋转,炮管可以自动上下抬起
        #endregion

        #region 练习题三 
        //3.请用3个球体,模拟太阳、地球、月亮之间的旋转移动
        #endregion
    }

    void Update()
    {
        #region 练习题一

        //Update内
        //脚本挂载到底座上
        this.transform.Rotate(Vector3.up, rotateSpeed * Time.deltaTime);

        #endregion

        #region 练习题二

        //Update内

        //注意:
        //通过head.localEulerAngles得到的角度 不会出现负数的情况 
        //虽然界面上显示出了负数 但是 通过代码获取 始终 只能得到0~360之间的数

        //炮台左右来回旋转
        head.Rotate(Vector3.up, headRotateSpeed * Time.deltaTime);

        //localEulerAngles只能是0到360 那就只有特殊判断了
        //不是315-360之间且大于45且旋转速度大于0
        if (!(head.localEulerAngles.y >= 315 && head.localEulerAngles.y <= 360) &&
            head.localEulerAngles.y >= 45 && headRotateSpeed > 0)
            headRotateSpeed = -headRotateSpeed;
        //不是0-45之间且小于315且旋转速度小于0
        else if (!(head.localEulerAngles.y <= 45 && head.localEulerAngles.y >= 0) &&
                  head.localEulerAngles.y <= 315 && headRotateSpeed < 0)
            headRotateSpeed = -headRotateSpeed;

        //炮管上下来回旋转
        gunTail.Rotate(Vector3.right, gunTailRotateSpeed * Time.deltaTime);


        //localEulerAngles只能是0到360 那就只有特殊判断了
        //不是350-360之间且大于10且旋转速度大于0
        if (!(gunTail.localEulerAngles.x >= 350 && gunTail.localEulerAngles.x <= 360) &&
            gunTail.localEulerAngles.x >= 10 && gunTailRotateSpeed > 0)
            gunTailRotateSpeed = -gunTailRotateSpeed;
        //不是0-10之间且小于350且旋转速度小于0
        else if (!(gunTail.localEulerAngles.x <= 10 && gunTail.localEulerAngles.x >= 0) &&
                  gunTail.localEulerAngles.x <= 350 && gunTailRotateSpeed < 0)
            gunTailRotateSpeed = -gunTailRotateSpeed;

        #endregion

        #region 练习题三

        //Update内

        //太阳自转
        sun.Rotate(Vector3.up, 10 * Time.deltaTime);
        //地球自转
        earth.Rotate(Vector3.up, 10 * Time.deltaTime);
        //月亮自转
        moon.Rotate(Vector3.up, 10 * Time.deltaTime);

        //地球公转
        earth.RotateAround(sun.position, Vector3.up, 10 * Time.deltaTime);

        //月亮绕地球转
        moon.RotateAround(earth.position, Vector3.up, 10 * Time.deltaTime);

        #endregion
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏