关于 Unity 的 Transform.up 和 Vector3.Up 的测试

这篇具有很好参考价值的文章主要介绍了关于 Unity 的 Transform.up 和 Vector3.Up 的测试。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

官方文档

关于 Unity 的 Transform.up 和 Vector3.Up 的测试,unity,游戏引擎

链接如下:

Unity官方文档的 Transform.up 链接

测试过程

  • 测试方法:提取刚体,坐标系,Space模式为参数,使用上下左右表示物体移动和旋转,测试不同情况的位移和旋转,Console选择Collapse模式

测试脚本 TestScript 如下:


using System;  
using UnityEngine;  
  
public enum Coordinate  
{  
    TransUp,  
    VectorUp  
}  
  
public enum MovePattern  
{  
    SetRigidVelocity,  
    SetTranslate  
}  
  
public enum SpaceSet  
{  
    SelfSpace,  
    WorldSpace  
}  
  
public class TestScript : MonoBehaviour  
{  
    public MovePattern MyMovePattern;  
    public Coordinate MyCoordinate;  
    public SpaceSet MySpace;  
  
    public Rigidbody Rigidbody;  
    public float Speed = 10f;  
  
  
    void Update()  
    {  
        // 首先看移动模式,在使用刚体,且模式为 Dynamic 时,不要使用 Transform.Translate 或者 MovePosition 等直接位移的函数,  
        // 直接位移是违背物理规律的,Velocity 将不会随位移而改变,必须受力或者直接调整 Velocity数值 才能改变 Velocity  
        SelectTestFunction(MyMovePattern, MyCoordinate, MySpace);  
    }  
  
    private void SelectTestFunction(MovePattern myMove, Coordinate myCo, SpaceSet mySpaceSet)  
    {  
        #region 刚体 & Transform.Up & Self  
  
        if (myMove == MovePattern.SetRigidVelocity && myCo == Coordinate.TransUp && mySpaceSet == SpaceSet.SelfSpace)  
        {  
            Debug.Log("本次测试模式:刚体 Dynamic ,使用坐标 Transform.Up , 旋转的 Space 模式为 Self ");  
  
            // 如果没有按任何键位,每帧给速度归零  
            if (!Input.anyKey)  
            {  
                Rigidbody.velocity = Vector3.zero;  
            }  
  
            // 上下左右移动  
            if (Input.GetKey(KeyCode.UpArrow))  
            {  
                Rigidbody.velocity = transform.up * Speed;  
            }  
  
            if (Input.GetKey(KeyCode.DownArrow))  
            {  
                Rigidbody.velocity = -transform.up * Speed;  
            }  
  
            if (Input.GetKey(KeyCode.LeftArrow))  
            {  
                transform.Rotate(new Vector3(0, 0, 1) * Time.deltaTime * Speed, Space.Self);  
            }  
  
            if (Input.GetKey(KeyCode.RightArrow))  
            {  
                transform.Rotate(new Vector3(0, 0, -1) * Time.deltaTime * Speed, Space.Self);  
            }  
        }  
  
        #endregion  
  
        #region 刚体 & Transform.Up & World  
  
        if (myMove == MovePattern.SetRigidVelocity && myCo == Coordinate.TransUp && mySpaceSet == SpaceSet.WorldSpace)  
        {  
            Debug.Log("本次测试模式:刚体 Dynamic ,使用坐标 Transform.Up , 旋转的 Space 模式为 World ");  
  
            // 如果没有按任何键位,每帧给速度归零  
            if (!Input.anyKey)  
            {  
                Rigidbody.velocity = Vector3.zero;  
            }  
  
            // 上下左右移动  
            if (Input.GetKey(KeyCode.UpArrow))  
            {  
                Rigidbody.velocity = transform.up * Speed;  
            }  
  
            if (Input.GetKey(KeyCode.DownArrow))  
            {  
                Rigidbody.velocity = -transform.up * Speed;  
            }  
  
            if (Input.GetKey(KeyCode.LeftArrow))  
            {  
                transform.Rotate(new Vector3(0, 0, 1) * Time.deltaTime * Speed, Space.World);  
            }  
  
            if (Input.GetKey(KeyCode.RightArrow))  
            {  
                transform.Rotate(new Vector3(0, 0, -1) * Time.deltaTime * Speed, Space.World);  
            }  
        }  
  
        #endregion  
  
        #region 刚体 & Vector.Up & Self  
  
        if (myMove == MovePattern.SetRigidVelocity && myCo == Coordinate.VectorUp && mySpaceSet == SpaceSet.SelfSpace)  
        {  
            Debug.Log("本次测试模式:刚体 Dynamic ,使用坐标 Vector3.Up , 旋转的 Space 模式为 Self ");  
  
            // 如果没有按任何键位,每帧给速度归零  
            if (!Input.anyKey)  
            {  
                Rigidbody.velocity = Vector3.zero;  
            }  
  
            // 上下左右移动  
            if (Input.GetKey(KeyCode.UpArrow))  
            {  
                Rigidbody.velocity = Vector3.up * Speed;  
            }  
  
            if (Input.GetKey(KeyCode.DownArrow))  
            {  
                Rigidbody.velocity = -Vector3.up * Speed;  
            }  
  
            if (Input.GetKey(KeyCode.LeftArrow))  
            {  
                transform.Rotate(new Vector3(0, 0, 1) * Time.deltaTime * Speed, Space.Self);  
            }  
  
            if (Input.GetKey(KeyCode.RightArrow))  
            {  
                transform.Rotate(new Vector3(0, 0, -1) * Time.deltaTime * Speed, Space.Self);  
            }  
        }  
  
        #endregion  
  
        #region 刚体 & Vector.Up & World  
  
        if (myMove == MovePattern.SetRigidVelocity && myCo == Coordinate.VectorUp && mySpaceSet == SpaceSet.WorldSpace)  
        {  
            Debug.Log("本次测试模式:刚体 Dynamic ,使用坐标 Vector3.Up , 旋转的 Space 模式为 World ");  
  
            // 如果没有按任何键位,每帧给速度归零  
            if (!Input.anyKey)  
            {  
                Rigidbody.velocity = Vector3.zero;  
            }  
  
            // 上下左右移动  
            if (Input.GetKey(KeyCode.UpArrow))  
            {  
                Rigidbody.velocity = Vector3.up * Speed;  
            }  
  
            if (Input.GetKey(KeyCode.DownArrow))  
            {  
                Rigidbody.velocity = -Vector3.up * Speed;  
            }  
  
            if (Input.GetKey(KeyCode.LeftArrow))  
            {  
                transform.Rotate(new Vector3(0, 0, 1) * Time.deltaTime * Speed, Space.World);  
            }  
  
            if (Input.GetKey(KeyCode.RightArrow))  
            {  
                transform.Rotate(new Vector3(0, 0, -1) * Time.deltaTime * Speed, Space.World);  
            }  
        }  
  
        #endregion  
  
        #region Tranlate & Transform.Up & Self  
  
        if (myMove == MovePattern.SetTranslate && myCo == Coordinate.TransUp && mySpaceSet == SpaceSet.SelfSpace)  
        {  
            Debug.Log("本次测试模式:SetTranslate ,使用坐标 Transform.Up , 旋转的 Space 模式为 Self ");  
  
  
            // 上下左右移动  
            if (Input.GetKey(KeyCode.UpArrow))  
            {  
                transform.Translate(transform.up * Time.deltaTime * Speed);  
            }  
  
            if (Input.GetKey(KeyCode.DownArrow))  
            {  
                transform.Translate(-transform.up * Time.deltaTime * Speed);  
            }  
  
            if (Input.GetKey(KeyCode.LeftArrow))  
            {  
                transform.Rotate(new Vector3(0, 0, 1) * Time.deltaTime * Speed, Space.Self);  
            }  
  
            if (Input.GetKey(KeyCode.RightArrow))  
            {  
                transform.Rotate(new Vector3(0, 0, -1) * Time.deltaTime * Speed, Space.Self);  
            }  
        }  
  
        #endregion  
  
        #region Tranlate & Transform.Up & World  
  
        if (myMove == MovePattern.SetTranslate && myCo == Coordinate.TransUp && mySpaceSet == SpaceSet.WorldSpace)  
        {  
            Debug.Log("本次测试模式:SetTranslate ,使用坐标 Transform.Up , 旋转的 Space 模式为 World ");  
  
  
            // 上下左右移动  
            if (Input.GetKey(KeyCode.UpArrow))  
            {  
                transform.Translate(transform.up * Time.deltaTime * Speed);  
            }  
  
            if (Input.GetKey(KeyCode.DownArrow))  
            {  
                transform.Translate(-transform.up * Time.deltaTime * Speed);  
            }  
  
            if (Input.GetKey(KeyCode.LeftArrow))  
            {  
                transform.Rotate(new Vector3(0, 0, 1) * Time.deltaTime * Speed, Space.World);  
            }  
  
            if (Input.GetKey(KeyCode.RightArrow))  
            {  
                transform.Rotate(new Vector3(0, 0, -1) * Time.deltaTime * Speed, Space.World);  
            }  
        }  
  
        #endregion  
  
        #region Tranlate & Vector3.Up & Self  
  
        if (myMove == MovePattern.SetTranslate && myCo == Coordinate.VectorUp && mySpaceSet == SpaceSet.SelfSpace)  
        {  
            Debug.Log("本次测试模式:SetTranslate ,使用坐标 Vector3.Up , 旋转的 Space 模式为 Self ");  
  
  
            // 上下左右移动  
            if (Input.GetKey(KeyCode.UpArrow))  
            {  
                transform.Translate(Vector3.up * Time.deltaTime * Speed);  
            }  
  
            if (Input.GetKey(KeyCode.DownArrow))  
            {  
                transform.Translate(-Vector3.up * Time.deltaTime * Speed);  
            }  
  
            if (Input.GetKey(KeyCode.LeftArrow))  
            {  
                transform.Rotate(new Vector3(0, 0, 1) * Time.deltaTime * Speed, Space.Self);  
            }  
  
            if (Input.GetKey(KeyCode.RightArrow))  
            {  
                transform.Rotate(new Vector3(0, 0, -1) * Time.deltaTime * Speed, Space.Self);  
            }  
        }  
  
        #endregion  
  
        #region Tranlate & Vector3.Up & World  
  
        if (myMove == MovePattern.SetTranslate && myCo == Coordinate.VectorUp && mySpaceSet == SpaceSet.WorldSpace)  
        {  
            Debug.Log("本次测试模式:SetTranslate ,使用坐标 Vector3.Up , 旋转的 Space 模式为 World ");  
  
  
            // 上下左右移动  
            if (Input.GetKey(KeyCode.UpArrow))  
            {  
                transform.Translate(Vector3.up * Time.deltaTime * Speed);  
            }  
  
            if (Input.GetKey(KeyCode.DownArrow))  
            {  
                transform.Translate(-Vector3.up * Time.deltaTime * Speed);  
            }  
  
            if (Input.GetKey(KeyCode.LeftArrow))  
            {  
                transform.Rotate(new Vector3(0, 0, 1) * Time.deltaTime * Speed, Space.World);  
            }  
  
            if (Input.GetKey(KeyCode.RightArrow))  
            {  
                transform.Rotate(new Vector3(0, 0, -1) * Time.deltaTime * Speed, Space.World);  
            }  
        }  
  
        #endregion  
    }  
}

测试场景物体布局如下图:

关于 Unity 的 Transform.up 和 Vector3.Up 的测试,unity,游戏引擎

测试结果

当脚本控制的物体没有父对象时

刚体速度和Translate对比

相同点:

  • 旋转的Space模式不会影响任何结果,没有父物体的情况下,Space.World 和 Space.Self 是一样的,这很正常
  • Transform.up 实际上是 Scene 窗口中 Local 模式下的绿色轴(Y轴)的方向
  • Vector3.up 则是世界坐标Y轴,Scene 窗口中 Global 模式下的绿色轴,无论物体是否旋转,都只会在Y轴上移动,不会改变X的值

不同点:

  • 在Transform.up方向上,当物体旋转后,刚体会沿着这个Y轴移动,但是Translate不是Y轴方向,会有偏移,实际情况如下图 :

关于 Unity 的 Transform.up 和 Vector3.Up 的测试,unity,游戏引擎

当脚本控制物体有父对象,且有旋转和偏移量时

父对象沿Z轴每秒旋转30°,子物体Y轴偏移2个单位

刚体速度运动
Transform.up
  • 当自身没有额外旋转时,Transform.up 实际上是 Scene 窗口中 Local 模式下的绿色轴(Y轴)的方向,Space.World 和 Space.Self 对此没有影响(至少总体的运动轨迹是一样的),但是最终方向都会受到父对象的旋转影响,而有偏移。
  • 当自身再旋转90°时,也是和上面一样
Vector3.up
  • 当自身没有额外旋转时,还是在世界坐标Global的Y轴上,Space.World 和 Space.Self 对此没有影响(至少总体的运动轨迹是一样的),最终位置会受到父对象的旋转影响。
  • 当自身再旋转90°时,也是和上面一样
Translate位移
Transform.up
  • 无论是否有额外旋转,Space.World 和 Space.Self 都会有影响,且不好判断具体移动行为
Vector3.up
  • 无论是否有额外旋转,还是还是在世界坐标Global的Y轴上,Space.World 和 Space.Self 对此没有影响(至少总体的运动轨迹是一样的),最终位置会受到父对象的旋转影响。

父对象Z轴旋转60°,子物体Y轴偏移2个单位

刚体速度运动
Transform.up
  • 当自身没有额外旋转时,Transform.up 实际上是 Scene 窗口中 Local 模式下的绿色轴(Y轴)的方向,Space.World 和 Space.Self 对此没有影响,只改变Transform的Y值,X值虽然会变化,但是为极小数,或者是错误数字,如下图所示,过程中可能刚好出现0,或者是极小数

关于 Unity 的 Transform.up 和 Vector3.Up 的测试,unity,游戏引擎
关于 Unity 的 Transform.up 和 Vector3.Up 的测试,unity,游戏引擎

  • 当自身再旋转90°时,X和Y轴的值都会改变,如果只拖动Position的Y值,最终方向为Scene 窗口中 Local 模式下的绿色轴(Y轴)的方向反向旋转90°。
Vector3.up
  • 当自身没有额外旋转时,还是在世界坐标Global的Y轴上直接移动
  • 当自身再旋转90°时,也是和上面一样
Translate位移
Transform.up
  • 无论是Space.World 或者 Space.Self,且是否旋转90°,都不是Scene窗口中任意一个坐标轴的方向
Vector3.up
  • 此时无论是Space.World 或者 Space.Self,都是Scene 窗口中 Local 模式下的绿色轴(Y轴)的方向移动,即Position的X值不变,只变化Y值,
  • 自身旋转90°之后,在Scene窗口中查看,依旧是 Local 模式下的绿色轴(Y轴)的方向移动,但是实际Position的X和Y值都会改变

测试总结

  • 开发过程中尽量避免以下情况:
    • 子物体和父物体都有旋转角度,需要开发者计算实际角度
    • 子物体和父物体都是持续旋转的,无法使用简单的计算得出最终结果
    • 子物体和父物体既有旋转又有位移,没必要,此种情况应该是可以优化的
  • 开发过程中尽量保持只有一个值是随时间变化的。
  • 虽然官方文档中编写Transform.up的解释为:The green axis of the transform in world space。经过测试后可以理解为物体自身的Transform的Y轴方向。
  • 根据以上结果,如果使用了刚体,速度方向为Transform.up时,通常可以达到物体自身的Y轴方向,Space优先使用World。
  • 特殊情况是使用Translate方法位移时,自身没有旋转的情况下,采用Vector3.up的方向可以达到只改变Position的Y值的方法。
  • 以上仅仅为简单测试,得出的结果不是非常精准的,具体项目中的位移和旋转可能更复杂,情况也可能不一样。根据目前的结果来看,笔者认为在遇到此类情况时,优先采用刚体速度进行位移,且选择Space.World,如果不符合实际情况再调整尝试。
  • 如果有大佬进行过测试且能准确的描述最终运动轨迹,请留下评论指教,不胜感激。

使用案例参考

2D旋转武器及升级详解文章来源地址https://www.toymoban.com/news/detail-774325.html

到了这里,关于关于 Unity 的 Transform.up 和 Vector3.Up 的测试的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【unity笔记】图解 Vector3.SignedAngle()方法的返回值

    【unity笔记】图解 Vector3.SignedAngle()方法的返回值

     这个方法可以理解为:“两个向量之间的夹角(有符号的)”。 我会将它想象成:将两个向量都放在坐标原点,一个向量要向 哪个方向 旋转 多少度 才能与另一个向量重合。 于是我在坐标原点放置了两个向量: OB 和 OA 。 OB 始终躺在X轴正方向,看看 OA 在4个象限的不同的

    2024年01月25日
    浏览(12)
  • Unity 3D之 利用Vector3 计算移动方向,以及实现位移多少

    Unity 3D之 利用Vector3 计算移动方向,以及实现位移多少

    这段代码是一个在游戏开发中常见的示例,用于获取玩家的输入,并将输入值转换为一个三维向量,以表示移动方向。让我们逐步解释这段代码: float horizontalInput = Input.GetAxis(\\\"Horizontal\\\"); :这一行代码获取水平方向上的输入。它调用 Input.GetAxis(\\\"Horizontal\\\") 来获取水平轴的输入

    2024年02月11日
    浏览(11)
  • Unity3D 基础——使用 Vector3.Lerp 实现缓动效果

    Unity3D 基础——使用 Vector3.Lerp 实现缓动效果

     让一个物体从当前位置移动到另一个位置   Vector3-Lerp - Unity 脚本 API https://docs.unity.cn/cn/current/ScriptReference/Vector3.Lerp.html 1.在场景中新建两个 Cube 立方体,在 Scene 视图中将两个 Cude的位置错开。  2.新建 C# 脚本 MoveToTarget.cs(写完记得保存) 3.将脚本绑定到 Cude 上,然后将其

    2024年02月06日
    浏览(13)
  • 没有Unity_光追2008年的书 Ray Tracing From The Ground Up 目录翻译

    之前个人居然完全没有听到过这本书,神作 之前看到的都是什么real-time 3rd,精要,精粹(其实真的都是鸡肋) 拿到手的pdf(从那个最大的同性交友网站)并没有目录,所以记录一下 最后会分享几个写Unity Shader工具(外连接) 看完目录,个人下一个篇幅直接是:AO 光线遮罩

    2023年04月08日
    浏览(8)
  • 【Unity报错】Some objects were not cleaned up when closing the scene.

    【Unity报错】Some objects were not cleaned up when closing the scene.

    Unity结束运行的时候报错Some objects were not cleaned up when closing the scene. (Did you spawn new GameObjects from OnDestroy?) 结束运行的时候突然报错,有概率,有时候有有时候没有 结束运行的时候在OnDestroy中调用了Mono的单例类,但是呢OnDestroy调用次序是不同的,有可能A先B后,也有可能是B先

    2024年02月02日
    浏览(16)
  • 关于docker-compose up -d在文件下无法运行的原因以及解决方法

    关于docker-compose up -d在文件下无法运行的原因以及解决方法

    一、确认文件下有docker-compose.yml文件  二、解决方法 检查 Docker 服务是否运行 : 使用以下命令检查 Docker 服务是否正在运行: 如果 Docker 未运行,可以使用以下命令启动它: 确认 Docker 服务开机自启动 : 如果 Docker 服务在启动后无法正常运行,您可以使用以下命令将其设置

    2024年02月12日
    浏览(10)
  • CANoe测试车载以太网 Link up/Link down时间

    CANoe测试车载以太网 Link up/Link down时间

    随着智能电动汽车的行业的发展,车载以太网的应用越来越广泛,最近很多朋友在问Link up和Link down如何设置,Link up时间和Link down时间如何测试。本章节就分享一下关于CANoe如何设置Link up/Link down,以及Link up时间/Link down时间如何查看。 首先描述一下什么是Link up、Link down: Lin

    2024年02月16日
    浏览(71)
  • Unity基础篇-------Transform

    Unity基础篇文章系列,是为了加深自己对组件内的一些函数及变量的印象,如果你对它们也不是很了解就一起看看吧。 Transform是每个需要移动、缩放、旋转的物体必不可缺的组件,也是我们平时用到的最高频率的组件,接下来看看Transform组件所常用的一些函数及变量的使用方

    2024年02月03日
    浏览(6)
  • Unity物体的控制(Transform)

    1.看向原点 2.沿某一轴自转 3.围绕某个目标点旋转 4.移动

    2024年02月04日
    浏览(10)
  • unity 之Transform组件(汇总)

    unity 之Transform组件(汇总)

    当在Unity中处理3D场景中的游戏对象时, Transform 组件是至关重要的组件之一。它管理了游戏对象的位置、旋转和缩放,并提供了许多方法来操纵和操作这些属性。以下是关于 Transform 组件的详细介绍: 位置(Position): Transform 组件的 position 属性表示游戏对象在世界坐标系中

    2024年02月04日
    浏览(22)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包