Rigibody 2D

2019-07-18  本文已影响0人  JJJJJJJJJJC

Rigibody 2D:

所有被附加在同一个具有Rigidbody2D组件的GameObject、以及其子GameObject上的Collider2D,都会被隐式地附加到该Rigidbody2D上。当Collider2D被附加到Rigidbody2D上后,它将随着Rigidbody2D移动。一个Collider2D不应该直接使用Transform或者其offset属性来移动它,而是应该使用Rigidbody2D的移动代替之。这样会得到最好的表现和正确的碰撞检测。被附加在同一个Rigidbody2D的Collider2D之间不会发生碰撞。所以我们可以创建一个包含多个Collider2D的复合Collider2D,这样所有的Collider2D的移动、旋转都将与Rigidbody2D的运动同步。

那么针对之前使用Transform移动的方式,我们应该改为如下方式:
void FixedUpdate()
    {
        rigidbody2D.MovePosition (rigidbody2D.position + Vector2.left * speed * Time.fixedDeltaTime);
    }

似乎没有规定要在Fixed里移动.
或者如下方式:

void Start () {
        rigidbody2D.velocity = Vector2.left * speed;
    }

注意前一种方式每一物理帧设置一次Rigidbody2D的位置,看起来Rigidbody2D在以一定速度移动,但实际上它的velocity依旧是零。

后一种方式则不存在上面的问题,设置好velocity后,物理系统会自动对它进行模拟,代码看起来也更简洁。

再看看Rigidbody2D的Body Type属性:


它有三个可选项:Dynamic(动态,默认)、Kinematic(运动学)、Static(静态)。
这三种类型确定了不同的运动行为(移动和旋转)和碰撞方式。
注意虽然Rigidbody2D描述了与其他物体碰撞,但是如果没有附加Collider2D组件,它仍然是不能检测到碰撞的。

关于Body Type,这个属性不要在运行时去修改它。原因还是引用官方文档的说明:

意思就是运行时去改变此属性会引起不同的表现。具体什么表现,就是前面说的会立即引发一系列的重计算,这会是性能的额外开销。

再看看三种不同的Body Type究竟确定了哪些不同的运动行为和碰撞方式。

Body Type —— Dynamic

Dynamic Rigidbody2D被设计用来制作在物理模拟下会移动的物体。它会与所有类型的Rigidbody2D进行碰撞,是最常用的Rigidbody2D类型、默认的类型,同时也是最耗费性能的类型。
文档中粗体部分的意思就是千万不要使用Transform组件来设置Dynamic Rigidbody2D的position和rotation。
如果想要移动或旋转它,可以使用上面提到的方式,通过Rigidbody2D的接口来完成。

Body Type —— Kinematic

Kinematic所谓的碰撞仅限于脚本.物理上是不会产生任何物理效果的.

Kinematic Rigidbody2D被设计用来制作在物理模拟下会移动、但是仅仅在明确的用户控制下运动的物体,它不会受到重力和AddForce、AddTorque等力相关的函数的影响。

文档中粗体部分的意思是Kinematic Rigidbody2D对系统资源的要求比Dynamic Rigidbody2D更低(所以更有效率)。Kinematic Rigidbody2D被设计用来通过Rigidbody2D.MovePosition或Rigidbody2D.MoveRotation来进行重定位。

对于Kinematic Rigidbody2D,velocity属性对它依旧有效,只不过施加力和重力都不会对velocity造成影响。

Kinematic Rigidbody2D仅仅只会与Dynamic的Rigidbody2D发生碰撞(在不勾选Use Full Kinematic Contacts的情况下),它在碰撞行为上类似于Static Rigidbody2D,可以理解为具有无限质量、无法被撼动(不能通过力或碰撞改变速度,但是可以设置其速度和位置、旋转)的刚体。

Body Type —— Static

Static Rigidbody2D被设计用来制作在物理模拟下不会移动的物体。它在表现上可以理解为一个具有无限质量、不可移动的物体。此时velocity、AddForce、gravity、MovePosition、MoveRotation都是不可用的。

文档中粗体部分意思是Static Rigidbody2D对资源最不敏感(对性能要求低),Static Rigidbody2D仅仅会与Dynamic Rigidbody2D发生碰撞。两个Static Rigidbody2D之间也不会发生碰撞,因为他们本来就被设计成不可移动的。

Simulated(模拟)

该属性就是字面意思,设置为true(勾选)时开启模拟;设置为false(不勾选)时关闭模拟。
关闭时不与Static碰撞.

模拟包括:

更改此属性在内存和处理上,都比直接启用/禁用Collider2D组件和Joint2D组件更有效率。要知道原理的话,可以查看官方文档,这里就不再作详细解释了。

Use Full Kinematic Contacts(使用全运动触点)

如果想要Kinematic Rigidbody2D与所有类型的Rigidbody2D发生碰撞,可以勾选此选项。勾选上后,它在碰撞上类似于Dynamic Rigidbody2D,但是不会受到力的影响。
只能在脚本触发ColliderEnter等事件函数.其他物理效果并不会生效.

当此属性被设置为false(不勾选)时,该Kinematic Rigidbody2D只会与Dynamic Rigidbody2D发生碰撞;它不会与其他的Kinematic Rigidbody2D或Static Rigidbody2D(设置为trigger时除外)发生碰撞。所以此时脚本上的碰撞检测函数(OnCollisionEnter2D,OnCollisionStay2D,OnCollisionExit2D)不会被触发。

总结:

1、在操作附加了Rigidbody2D的物体时,不要直接通过操作Transform来移动、旋转它。

2、要接受碰撞的Rigidbody2D必须添加Collider2D组件。

3、如果一个Rigidbody2D需要移动,但不接受力的作用,那么需要将它设置成Kinematic;如果它附加了Collider2D组件,在Rigidbody的Use Full Kinematic Contacts属性为false(不勾选)时,它只会与Dynamic的Rigidbody2D碰撞,而不会与Kinematic的或者Static的Rigidbody2D发生碰撞;如果需要它能与受所有类型的Rigidbody2D碰撞,那就设置Use Full Kinematic Contacts为true(勾选)。

4、如果一个Rigidbody2D需要移动,并且接受完全的物理模拟,包括重力、碰撞、施加力等,那么需要将Rigidbody2D设置成Dynamic,并附加Collider2D组件。

5、如果一个Rigidbody2D不需要移动,也不需要接收力的作用,但是需要接受碰撞,那么需要将Rigidbody2D设置为Static,并附加Collider2D组件。

6、在运行中不要修改Rigidbody2D的Body Type属性。

7、在运行中,如果想要停止/启用对一个Rigidbody2D进行物理模拟,那么将这个Rigidbody2D的Simulate属性设置为false/true会比关闭/打开它的Collider2D、Joint2D组件效率高。

Dynamic:

Kinematic:

Static:

常用API

AddForce:这个方法是真实地给物体施加力。等同于动能方程。我的按键必须持续的按下,它才能持续的给物体施加力,增加物体的速度。如果是kinematic的刚体类型,则这个施加力是无效的。

Velocity:这个就是刚体的速度属性,当刚体加力或者被撞飞的时候,就会有速度。当然我们也可以直接赋值是刚体具有速度来移动。

MovePosition:这个就是直接改变刚体的位置。同等position=vecto2。通常在Kinematic类型使用。
MoveRotation:同上

除此之外,刚体组件还有一些方法很常用。

上一篇下一篇

猜你喜欢

热点阅读