• 【Unity300个技巧】牛顿的学问!如何优雅地使用力?


    Unity 提供了一个完备且强大物理引擎。但在刚接触的时候,你可能会对它与现实物理规律对应有一些疑惑。
    比如:

    • 现实中 1N 的力在 Unity 中怎么表现?
    • Unity 中物体的质量是计算的?
    • Unity 中给物体添加力的方法是 rb.AddForce(),但却又提供了4种力的模式,为什么呢?

    本文章,我们就来探讨一下以上的问题。

    额外资源

    Unity 中力的单位

    在 Unity 中,rb.AddForce()是给物体添加一个力的方法,传参是向量对象,向量的 x ,y,z 代表这方向,值代表力的大小。
    image.png
    这里可能会让人疑惑,这里力的单位是什么呢?是否对应现在中的力的单位 N ?
    要验证这个点,最好的办法就算找一个物理学中常量,看这个常量在 Unity 中是多少。
    毫无疑问,重力就是我们心中的那个常量。
    在现实中,重力约等于 9.81N。
    在Unity 中,我们可以在设置里看到重力的默认值,在Y轴方向的大小也是9.81。
    image.png
    所以,我们可以认为,传参向量值的单位等于现实中的 N。
    我们可以验证一下。
    在一个只有重力的场景,我们添加一个9.81的相对于重力反方向的力,物体时静止的。
    image.png
    代码实现

    public class TestGravity : MonoBehaviour
    {
    
        private Rigidbody2D _rigidbody2D;
        [Header("向上的力")]
        [SerializeField]
        private float _force;
        
        void Start()
        {
            _rigidbody2D = transform.GetComponent<Rigidbody2D>();
        }
    
        private void FixedUpdate()
        {
            _rigidbody2D.AddForce(new Vector3(0, _force, 0));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    运行一下。
    一开始,赋予一个9.81N向上的力时,人物时静止的。当逐渐增加力后,人物向上移动了。
    在这里插入图片描述

    Unity 中物体的质量

    在物理学中,涉及到力的计算肯定离不开物体的质量。
    在 Unity 中,我们可以认为单位是kg,因为这有助于我们计算。其实这个单位并不太重要,它在 Unity 引擎中的作用只是用于描述两个物体之间相对差异,比如两个物体质量分别是 10 和 100,可以确定的是 100 质量的物体是 10 质量物体的 10 倍重。
    images.png
    举个例子。
    从上面公式中得知,同一个力的大小作用在不同物体上,因为质量不同,物体移动的加速度就会不一样。
    质量不同.gif
    因此,在游戏里,我们不需要知道质量的单位是多少,只需要维护好每个对象的质量相对值就可以了。
    当游戏体量上来后,去维护他们的质量数值也比较麻烦。所以在 2D 模式下,Unity 提供了一个功能,自动计算质量。
    image.png
    当选择启用自动质量后,Unity 会根据 物体的密度和面积自己计算质量。
    image.png

    自动计算质量.gif

    举个例子。
    我们使用相同的力和相同的密度,只改变物体的面积。
    效果如下:
    自动质量,.gif

    力的模式

    从上文我们了解到改变力的大小和质量,从而控制物体的速度。
    但是公式 F=ma中,a 只是加速度,不够直观反馈物体的速度。
    我们变换一下公式,
    F= ma = m v/t, Ft = m v (t 为时间,v 为速度)

    这样我们就可以很直观的得到速度 v 的大小,但也引入多了一个数值-时间。

    时间 t 在 Unity 中应该怎么表示呢?
    我们知道,为了保证物理模拟正常运行都会把逻辑写在 FixedUpdate 方法里。因此时间 t 就等于固定频率,默认为0.02s。
    这样力,质量,时间都知道怎么表示了,我们可以快速算出物体的速度。

    但且慢,为了改变物体的速度,我需要控制3个变量,那也太麻烦了把。
    Unity 为此提供4种模式,目的就是为了减少开发者需要关心这么多的变量。

    image.png
    看起来很棒,但却又多了一对概念-连续力和瞬时力。无语~
    什么是连续力,什么是瞬时力呢?
    在我看来,他们之间没有区别。因为给物体添加力,都是在当前帧里完成的,与下一帧无关,根本不存在连续添加力的情况。
    那这里的连续力是什么意思呢?
    其实是将力的大小乘以每一固定帧的时间间隔 ,F * 0.02s = 当前帧的力大小。
    相比于瞬时力,瞬时力是没有乘以时间的 ,相当于 F * 1 = 当前帧的力大小。

    为了更好说明问题,我们演示一下。
    代码如下:
    Force 模式下的代码

    public class AddForce_Default : MonoBehaviour
    {
        // 赋予2的力
        public float force = 2;
        private Rigidbody2D _rigidbody2D;
        // 移动方向
        private Vector3 dir = Vector3.right;
        
        void Start()
        {
            _rigidbody2D = GetComponent<Rigidbody2D>();
        }
    
        private void FixedUpdate()
        {
            _rigidbody2D.AddForce(Vector2.right * force,ForceMode2D.Force);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    Impulse 模式下的代码

    public class AddForce_Impulse : MonoBehaviour
    {
        // 赋予2的力
        public float force = 2;
        private Rigidbody2D _rigidbody2D;
        // 移动方向
        private Vector3 dir = Vector3.right;
        
        void Start()
        {
            _rigidbody2D = GetComponent<Rigidbody2D>();
           
        }
    
        private void FixedUpdate()
        {
            _rigidbody2D.AddForce(Vector2.right * force,ForceMode2D.Impulse);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    运行效果:
    两种模式下,速度不同.gif
    可以看到在 Force 模式下,角色移动明显慢得多。
    那是因为每一固定帧下,Force 模式下只赋予角色 2*0.02 的力,而 Impulse 模式下,赋予角色 2 的力。

    为了验证这一点,我们可以将 Impulse 模式下的力改为0.04。
    运行效果:
    两种模式下,速度相同.gif

    Acceleration 模式和 VelocityChange 模式
    在 3D 模式下 ,还会额外多两个模式。在这两个力模式下,都会忽略物体的质量,默认为1。
    所以我们只控制力的大小,就可以控制速度大小了。
    在这里插入图片描述

    求点赞,求关注。

  • 相关阅读:
    java毕业设计校园商铺mybatis+源码+调试部署+系统+数据库+lw
    Linux CentOS7 vim重复行
    TypeScript——接口(对象接口)、函数(定义类型,可选参数,默认参数,剩余参数,函数类型变量,函数接口)
    3ds MAX 基本体建模,长方体、圆柱体和球体
    软件测试100天上岸2-测试必须有策略
    ViT:Vision transformer的cls token如何实现分类?
    React 入门:组件实例三大属性之props
    基于vue天气数据可视化平台
    Rycky9.0安装k8s1.25.0+containerd
    搜索引擎算法工程师,在query理解方面,都有哪些方面的工作
  • 原文地址:https://blog.csdn.net/GG_and_DD/article/details/127928483