大坑一: 内置物理系统不支持刚体和关节
Cocos的内置物理系统不能说是很垃圾, 只能说是没什么用. 只要你想做一点超出碰撞检测范围的物理效果, 那么就可以直接抛弃内置物理系统了. 以下内容摘自Cocos Creator 3.8官方文档, 可以看到官方文档明确写着不支持的能力.
由于 Builtin 2D 物理系统只带有碰撞检测的功能,所以刚体对于 Builtin 2D 物理系统是不生效的,本篇设置只对 Box 2D 物理系统产生作用。
关节组件在 Builtin 2D 物理模块中是无效的。
可以看到, 内置的物理系统不支持刚体和关节, 那还叫什么物理系统啊, 直接叫碰撞组件多好.
所以, 如果你的游戏如果需要一点物理效果, 请毫不犹豫地选择Box2D, 否则后面改起来会有点麻烦.
大坑二: Box2D的Collider必须配合RigidBody2D使用
选择了Box2D后, 幼稚的我, 以为只要给物体加上Collider就可以实现碰撞了. 但是我的子弹永远打不到怪物身上. 于是我把物理系统切到了内置, 就可以了.
从不看文档的我点开了文档, 赫然发现:
Box2D 物理模块需要先在 Rigidbody 中 开启碰撞监听,才会有相应的回调产生。EnabledContactListener
Builtin 物理模块只需要有碰撞体组件就可以产生碰撞回调。
…
关节组件都需要搭配 刚体 才可以正确运行。
这个回调想要回调到谁那里, 就给谁开启ContactListener, 否则不用开启.
大坑三: 节点销毁需要延迟一帧进行
上面的东西都弄好了之后, 我开开心心地继续写了起来, 突然, 报错
box2d.umd.js:7181 Uncaught Error
at b2Body.SetActive (box2d.umd.js:7181)
at b2RigidBody2D.setActive (rigid-body.ts:197)
at b2RigidBody2D.onDisable (rigid-body.ts:58)
at RigidBody2D.onDisable (rigid-body-2d.ts:516)
at ComponentScheduler.disableComp (component-scheduler.ts:445)
at NodeActivator.destroyComp (node-activator.ts:266)
at RigidBody2D._onPreDestroy (component.ts:395)
at RigidBody2D._destroyImmediate (object.ts:374)
at Node._onPreDestroyBase (base-node.ts:1397)
at Node._onPreDestroy (node.ts:278)
于是我点开了引擎的源码, 发现可能是重复设置active属性导致的, 于是我继续检查代码, 是否有重复释放节点的问题. 查了半天, 我的代码肯定是正确的, 于是继续Google.
https://forum.cocos.org/t/topic/136164
找到了论坛, 发现了这一大坑: 节点销毁要延迟一帧.
使用建议
技术选型
● 有任何物理效果的需要都请毫不犹豫选择Box2D
● 只需要碰撞检测能力,直接选择内置
具体使用
● 内置物理系统, 添加碰撞只需要放一个Collider, 其他不用管
● Box2D天假碰撞, 需要同时放Collider和RigidBody, 记得设置好分组
● 在游戏对象看不到后, 需要销毁, 销毁要延迟一帧, 使用scheduleOnce方法