[c3d/cocos]cocos 中刚体类型的区别
clq
浏览(395) -
2023-10-17 18:40:25 发表
编辑
关键字:
[c3d/cocos]cocos 中刚体类型的区别
比较意外的是,这次讲解得最好的是官方文档。这点比 u3d 的文档强。
https://docs.cocos.com/creator/manual/zh/physics/physics-rigidbody.html
https://www.jianshu.com/p/0804991ccd6e
--------------------------------------------------------
两个文档结合起来看比较好。网友的一针见血有讲解了各自的应用方式。
而官方文档详细解释了这其中的疑问。
--------------------------------------------------------
Cocos Creator 3.7 刚体的类型
程序员小宋同学
IP属地: 新疆
2023.05.14 08:22:11
字数 1,774阅读 550
在 Cocos Creator 中,RigidBody(刚体)是用于控制节点上物理行为的组件。它有三种类型:DYNAMIC(动态)、STATIC(静态)和 KINEMATIC(运动学)。
1. DYNAMIC
DYNAMIC 类型的刚体表示物体可以在物理世界中自由移动,受到外部力和约束的影响,包括重力、摩擦力和碰撞等。这种类型的刚体通常用于游戏中动态交互的元素,例如跳跃的角色、移动的平台、掉落的物品等。
示例:
import { _decorator, Component, RigidBody, RigidBody2D, ERigidBody2DType } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('DynamicBody')
export class DynamicBody extends Component {
onLoad() {
const rigidBody = this.node.getComponent(RigidBody);
rigidBody.type = RigidBody.Type.Dynamic;
}
}
2. STATIC
STATIC 类型的刚体表示物体在物理世保持静止,不受外部力和约束影响。这种类型的刚体通常用于游戏中静止元素,例如地面、墙壁、障碍物等。
示例:
import { _decorator, Component, RigidBody, RigidBody2D, ERigidBody2DType } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('StaticBody')
export class StaticBody extends Component {
onLoad() {
const rigidBody = this.node.getComponent(RigidBody);
rigidBody.type = RigidBody.Type.Static;
}
}
3. KINEMATIC
KINEMATIC 类型的刚体表示物体在物理世界中可以手动控制其运动状态,不受外部力和约束影响,但可以与其他类型的刚体产生碰撞和反应。这种类型的刚体通常用于游戏中需要手动控制的元素,例如通过脚本控制的平台、电梯等。
示例:
import { _decorator, Component, RigidBody, RigidBody2D, ERigidBody2DType } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('KinematicBody')
export class KinematicBody extends Component {
onLoad() {
const rigidBody = this.node.getComponent(RigidBody);
rigidBody.type = RigidBody.Type.Kinematic;
}
update(deltaTime: number) {
// 根据需要实现移动逻辑
const velocity = this.node.getComponent(RigidBody).getLinearVelocity();
velocity.x = 10;
this.node.getComponent(RigidBody).setLinearVelocity(velocity);
}
}
总结
DYNAMIC 类型的刚体能够自由移动并受到物理效应的影响; STATIC 类型的刚体保持静止,不受物理效应影响;而 KINEMATIC 类型的刚体可以手动控制,不受物理效应影响,但可以与其他类型的刚体产生碰撞和反应。
实际运用的例子
在 Cocos Creator 3.0 及以上版本中,RigidBody 是物理刚体组件,它用于表示游戏对象在物理世界中的存在。RigidBody 有三种类型:DYNAMIC、STATIC 和 KINEMATIC。下面我将为您解释这三种类型的实际运用例子。
DYNAMIC (动态刚体)
动态刚体是指受到物理引擎管理并受到重力、碰撞和其他力影响的游戏对象。它可以与其他动态刚体、静态刚体和运动学刚体发生碰撞和互动。
例子:在一个射击游戏中,子弹是一个动态刚体。当玩家射击时,子弹会受到重力的影响并沿着指定的轨迹移动。当子弹与其他游戏对象发生碰撞时,它们会互相施加力,导致它们的运动方式发生变化。
STATIC (静态刚体)
静态刚体是指始终保持固定位置和状态的游戏对象。它不受到重力、碰撞和其他力的影响,也不会改变它的速度或位置。然而,它可以与动态刚体和运动学刚体发生碰撞。
例子:在一个跑酷游戏中,墙壁和地面是静态刚体。它们始终保持固定的位置,不受到游戏中其他物体的影响。当玩家角色与墙壁或地面发生碰撞时,玩家角色的运动轨迹会受到影响,但墙壁和地面仍然保持不变。
KINEMATIC (运动学刚体)
运动学刚体是指通过代码控制其位置和速度变化的游戏对象。虽然它不受物理引擎的直接影响,但它可以与动态刚体和静态刚体发生碰撞。
例子:在一个平台游戏中,一个会自动上下移动的平台是一个运动学刚体。通过代码可以控制它的运动轨迹,使其在两个点之间来回移动。当玩家角色站在上面时,角色会跟随平台的移动而移动。与动态刚体或静态刚体碰撞时,运动学刚体不会改变其运动轨迹,但会影响其他物体的运动状态。
总结起来,在 Cocos Creator 3.0 及以上版本中,RigidBody 三种类型的实际运用例子如下:
动态刚体(DYNAMIC)主要用于受物理引擎管理并与其他物体互动的游戏对象,如子弹、角色等。
静态刚体(STATIC)主要用于始终保持固定位置和状态的游戏对象,如墙壁、地面等。
运动学刚体(KINEMATIC)主要用于通过代码控制其位置和速度变化的游戏对象,如自动移动的平台等。
台球的 RigidBody 类型为什么是 DYNAMIC,而不是 KINEMATIC?
在 Cocos Creator 中,RigidBody 组件有三种类型:STATIC、DYNAMIC 和 KINEMATIC。这三种类型分别有不同的特点,选择不同类型的 RigidBody 会导致物体的运动行为受到不同的控制:
STATIC:静态刚体。静态刚体不会根据物理系统进行自动移动,也不会受到力的影响。它通常用于创建不会移动的环境物体,如台球桌周围的墙壁或者台球洞。
DYNAMIC:动态刚体。动态刚体会受到力的影响并根据物理系统自动移动,具有质量、速度、摩擦力等物理特性。动态刚体在碰撞后会自动更改速度和角速度。
KINEMATIC:运动刚体。运动刚体与动态刚体类似,但不会受到力的影响。它的运动行为需要通过脚本手动控制。这种类型的刚体通常适用于需要精确控制、不受物理影响的对象,如可移动平台、电梯等。
在创建台球游戏时,台球的 RigidBody 类型选择 DYNAMIC 而不是 KINEMATIC 的原因如下:
自然物理反应:台球在进行碰撞和移动时,需要模拟现实世界中的质量、速度、摩擦力、旋转等物理属性。使用动态刚体可以轻松实现自然的运动行为和碰撞反应,无需通过脚本自行计算。
自动碰撞处理:选择动态刚体后,物理系统会自动处理台球之间的碰撞和弹性,这会让游戏表现得更加真实自然。
外力作用:在游戏中,玩家需要击打台球来改变它的移动方向和速度。使用动态刚体后,可以通过施加力或设置线性速度来实现这一效果,无需自己编写复杂的碰撞和运动控制逻辑。
总之,在创建台球游戏时,选择台球的 RigidBody 类型为 DYNAMIC 可以让游戏更加真实、自然,减少自行实现物理逻辑的复杂性,提高开发效率。而 KINEMATIC 类型更适用于那些需要精确控制、不受物理影响的游戏对象。
--------------------------------------------------------
刚体组件
刚体是组成物理世界的基本对象,它可以使游戏对象的运动方式受物理控制。例如:刚体可以使游戏对象受重力影响做自由下落,也可以在力和扭矩的作用下,让游戏对象模拟真实世界的物理现象。
添加刚体
通过编辑器添加
点击 属性检查器 下方的 添加组件 -> Physics -> RigidBody,即可添加刚体组件到节点上。
add-rigidbody-in-inspector
程序化添加/获取
import { RigidBody } from 'cc'
// 添加刚体
const rigidbody = this.node.addComponent(RigidBody);
// 获取刚体
const rigidBody = this.node.getComponent(RigidBody);
刚体的 API 接口请参考 Class RigidBody。
什么情况下需要添加刚体
配置碰撞分组并让其生效。
物体需要具备运动学或动力学行为。
注意:物体需要具备完全物理特性的前提条件物体同时具备 刚体 和 碰撞体,并调整好其质心位置和碰撞体的形状。
刚体属性
rigidbody
属性 说明
Group 刚体分组
Type 刚体类型。
DYNAMIC:动力学
STATIC:静态
KINEMATIC:运动学
注意:碰撞体间定义碰撞发生的可能性是通过刚体的 Group 属性,而非 Node 的 Layer 属性。
以下属性仅在 Type 设为 DYNAMIC 时生效:
属性 说明
Mass 刚体质量,该值需大于 0
AllowSleep 是否允许自动休眠
LinearDamping 线性阻尼,用于衰减线性速度,值越大,衰减越快
AngularDamping 角阻尼,用于衰减角速度,值越大,衰减越快
UseGravity 是否使用重力
LinerFactor 线性因子,用于缩放每个轴方向上的物理数值(速度和力)
AngularFactor 角因子,用于缩放每个轴方向上的物理数值(速度和力)
刚体组件接口请参考 RigidBody API。
刚体类型
目前刚体类型包括 DYNAMIC、KINEMATIC 和 STATIC。
rigidbody-type
STATIC:静态刚体。可以是手动设置刚体类型的游戏对象,也可以是具有碰撞体而没有刚体的游戏对象。如果一个节点默认只添加了碰撞器而没有添加刚体,那么这个节点可以认为默认使用的是 静态刚体。静态刚体在大多数情况下用于一些始终停留在一个地方,不会轻易移动的游戏物体,例如:建筑物。若物体需要持续运动,应设置为 KINEMATIC 类型。静态刚体与其他物体发生碰撞时,不会产生物理行为,因此,也不会移动。
DYNAMIC:动力学刚体。刚体碰撞完全由物理引擎模拟,可以通过 力的作用 运动物体(需要保证质量大于 0)。例如:斯诺克游戏击球后,母球滚动与其他球撞击;
KINEMATIC:运动学刚体。具有碰撞体和运动刚体,可以直接通过移动刚体对象的变换属性,但不会像动力学刚体一样响应力和碰撞,通常用于表达电梯这类平台运动的物体。它与静态刚体类似,不同的地方在于移动的运动刚体会对其他对象施加摩擦力,并在接触时唤醒其他刚体。
示例:通过一个简单的物理模拟说明各种类型刚体所具有的表现。下图方块中白色用了静态刚体,蓝色用了运动学刚体,黄色用了动力学刚体。其中白色和蓝色都是操控的变换信息,很明显的看出几个表现:
白色和蓝色之间会出现穿透现象。
白色的静态物体也可以运动。
两个黄色方块表现不同,白色上方的静止不动,蓝色上方的会跟随着运动。
physics-type
以上现象的原因是:
静态刚体和运动学刚体都不会受到力的作用,所以产生了穿透,这是正常现象。
静态物体的确是可以运动的,静态是指在时空中,每一个时刻都是静态,不会考虑其它时刻的状态。
与静态物体不同,运动学物体会根据附近时刻估算出运动状态(比如速度),又由于摩擦力的作用,因此带动了黄色方块。
刚体质心
在默认情况下,刚体的质心和模型的原点是一致的。
下图演示了当模型原点不一致时,质心位置的变化:
Centroid
这里用一个示例来说明如何调整碰撞的质心:
新建一个空的节点 Node 并添加下图所示的组件:
add comp
在 Node 的子节点下添加一个胶囊体,如下图所示:
add capsule
调整 cc.CapsuleCollider 的 Center 为下图所示,则此时胶囊体的质心则在胶囊体的底部:
result
通过下图可观察到当质心不一致时的运动表现,右边的胶囊体质心位于胶囊体的底部,左边的胶囊体质心位于物体的中心。
result
控制刚体
让刚体运动起来
针对不同的类型,让刚体运动的方式不同:
对于静态刚体(STATIC),应当尽可能保持物体静止,但仍然可以通过变换(位置、旋转等)来改变物体的位置。
对于运动学刚体(KINEMATIC),应当通过改变变换(位置、旋转等)使其运动。
对于动力学(DYNAMIC)刚体,需要改变其速度,有以下几种方式:
通过重力
刚体组件提供了 UseGravity 属性,需要使用重力时候,需将 UseGravity 属性设置为 true。
通过施加力
刚体组件提供了 applyForce 接口,根据牛顿第二定律,可对刚体某点上施加力来改变物体的原有状态。
import { math } from 'cc'
rigidBody.applyForce(new math.Vec3(200, 0, 0));
通过施加扭矩
刚体组件提供了 applyTorque 接口,可用于改变刚体的角速度。
rigidBody.applyTorque(new math.Vec3(200, 0, 0));
通过施加冲量
刚体组件提供了 applyImpulse 接口,施加冲量到刚体上的一个点,根据动量定理,将立即改变刚体的线性速度。 如果冲量施加到的点在力方向上的延长线不过刚体的质心,那么将产生一个非零扭矩并影响刚体的角速度。
rigidBody.applyImpulse(new math.Vec3(5, 0, 0));
通过改变速度
刚体组件提供了 setLinearVelocity 接口,可用于改变线性速度。
rigidBody.setLinearVelocity(new math.Vec3(5, 0, 0));
刚体组件提供了 setAngularVelocity 接口,可用于改变旋转速度。
rigidBody.setAngularVelocity(new math.Vec3(5, 0, 0));
限制刚体的运动
通过休眠
休眠刚体时,会将刚体所有的力和速度清空,使刚体停下来。
if (rigidBody.isAwake) {
rigidBody.sleep();
}
唤醒刚体时,刚体的力和速度将会恢复。
if (rigidBody.isSleeping) {
rigidBody.wakeUp();
}
注意:执行部分接口,例如施加力或冲量、改变速度、分组和掩码会尝试唤醒刚体。
通过阻尼
刚体组件提供了 linearDamping 线性阻尼和 angularDamping 旋转阻尼属性,可以通过 linearDamping 和 angularDamping 方法对其获取或设置。
阻尼参数的范围建议在 0 到 1 之间,0 意味着没有阻尼,1 意味着满阻尼。
if (rigidBody) {
rigidBody.linearDamping = 0.5;
let linearDamping = rigidBody.linearDamping;
rigidBody.angularDamping = 0.5;
let angularDamping = rigidBody.angularDamping;
}
通过因子
刚体组件提供了 linearFactor 线性速度因子和 angularFactor 旋转速度因子属性,可以通过 linearFactor 和 angularFactor 方法对其获取或设置。
因子是 Vec3 的类型,相应分量的数值用于缩放相应轴向的速度变化,默认值都为 1,表示缩放为 1 倍,即无缩放。
if (rigidBody) {
rigidBody.linearFactor = new math.Vec3(0, 0.5, 0);
let linearFactor = rigidBody.linearFactor;
rigidBody.angularFactor = new math.Vec3(0, 0.5, 0);
let angularFactor = rigidBody.angularFactor;
}
注意:
将因子某分量值设置为 0,可以固定某个轴向的移动或旋转。
在使用 cannon.js 或 Bullet (ammo.js) 物理引擎情况下,因子作用的物理量不同,使用 cannon.js 时作用于速度,使用 Bullet (ammo.js) 时作用于力。
本帖子属于以下条目()
NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.