关于 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 的详细介绍以及方法的介绍

    当涉及到Unity中的 Vector3 类时,以下是一些常用的方法和操作: magnitude 方法 :返回向量的长度。 sqrMagnitude 方法 :返回向量的平方长度,通常用于比较向量大小而无需进行开方运算,从而提高效率。 normalized 方法 :返回向量的单位向量,即长度为1但方向相同的向量。 Vect

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

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

    2024年02月11日
    浏览(42)
  • 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日
    浏览(50)
  • 没有Unity_光追2008年的书 Ray Tracing From The Ground Up 目录翻译

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

    2023年04月08日
    浏览(34)
  • 【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日
    浏览(41)
  • 关于docker-compose up -d在文件下无法运行的原因以及解决方法

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

    2024年02月12日
    浏览(38)
  • 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日
    浏览(137)
  • Unity基础篇-------Transform

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

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

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

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

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

    2024年02月04日
    浏览(40)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包