玩家物理
对玩家头像施加力和冲量
你可以在场景代码中对玩家的角色施加物理力。这使你可以创建诸如跳板、风区、击退效果、爆炸等游戏机制。
你可以施加两种力:
冲量: 一次性的瞬时推动。用于将玩家猛然弹向空中或将其击退等突发的离散效果。
持续力: 在其激活期间每个 tick 都会施加的持续推动。用于风区、水流或引力场等持续效果。
这两者都通过 Physics 辅助工具导入自 @dcl/sdk/ecs.
📔 注: 这些力只会影响本地玩家的角色。其他玩家会看到其他玩家位置的变化,但这些力本身不会在多人游戏中同步给其他玩家。每个玩家的物理运算都在自己的实例中本地运行。
施加冲量
使用 Physics.applyImpulseToPlayer() 来让玩家沿给定方向获得一次性推动。
向量: 方向和强度的组合——向量的长度表示冲量大小。
import { Physics } from '@dcl/sdk/ecs'
import { Vector3 } from '@dcl/sdk/math'
// 让玩家直接向上弹起
Physics.applyImpulseToPlayer(Vector3.create(0, 50, 0))你也可以分别传入方向和强度。在这种情况下,方向向量会自动归一化:
方向: 推动方向——在缩放前会自动归一化。强度: 冲量强度。
如果你调用 applyImpulseToPlayer() 在同一帧内多次调用,冲量会被累积——它们会相加,并作为一个合并后的单一冲量施加。
在玩家进入时触发冲量
一个常见模式是在玩家走进某个区域时触发冲量。使用触发区域来检测玩家何时进入:
施加击退冲量
使用 Physics.applyKnockbackToPlayer() 通过一次冲量将玩家从某个点推开。这非常适合爆炸、冲击效果以及其他一次性的定向爆发。方向会自动根据源点与玩家当前位置计算出来。
你可以使用 半径来限制作用范围,并使用 KnockbackFalloff 选项来控制强度随距离的衰减方式:
fromPosition: 击退的世界空间原点(爆炸中心、敌人位置等)。强度: 基础冲量强度。半径: 最大作用距离(默认:Infinity).衰减: 强度如何随距离减弱(默认:CONSTANT).
该 KnockbackFalloff 枚举控制力如何随距离减弱:
KnockbackFalloff.CONSTANT—— 在半径内任意距离都保持相同强度(默认)KnockbackFalloff.LINEAR—— 平滑线性减弱,在半径边缘降为 0KnockbackFalloff.INVERSE_SQUARE—— 急剧的、符合物理的衰减
如果玩家正好位于源位置,玩家会被直接向上推开。负强度则会将玩家拉向该点,而不是把他们推开。
相同的 KnockbackFalloff 值也适用于 applyRepulsionForceToPlayer().
施加持续力
使用 Physics.applyForceToPlayer() 来对玩家施加持续的力。与冲量不同,只要该力处于激活状态,它就会在每个 tick 施加。
源: 用于标识该力来源的实体——可用它在之后更新或移除该力。向量: 方向和强度的组合——向量的长度表示力的大小。
源实体的位置并不重要——它仅用作标识符。
力向量始终处于 世界空间。如果你需要相对于旋转实体的方向,请使用 Transform.localToWorldDirection() 先将其转换——参见 将本地方向转换为世界空间.
与 applyImpulseToPlayer()一样,你也可以传入一个 方向 和 强度 分别传入——参见 施加冲量:
如果你调用 applyForceToPlayer() 再次使用相同的源实体调用时,会替换该源之前施加的力。如果累积了多个力源,它们的向量会在每个 tick 求和。
移除持续力
要停止施加某个力,请调用 Physics.removeForceFromPlayer() 并传入用于创建该力的源实体引用。如果该实体当前没有在施加力,则此调用会被安全忽略。
源: 施加该力时使用的实体。
在限定时长内施加力
使用 Physics.applyForceToPlayerForDuration() 来在指定时间内施加力。持续时间以秒为单位。时间到后该力会自动移除。再次使用相同的源实体调用会重置计时器。
源: 用于标识该力来源的实体。持续时间: 力持续的时长,单位为秒。向量: 方向和强度的组合——向量的长度表示力的大小。
该 方向 + 强度 也提供重载版本——参见 施加冲量:
风区示例
此示例会创建一个风洞,在玩家进入时将其推动,离开时停止:
施加排斥力
使用 Physics.applyRepulsionForceToPlayer() 来持续将玩家推离空间中的一个固定点。这适用于磁力排斥场、力场屏障,或让玩家保持距离的悬浮物体等效果。不同于 applyKnockbackToPlayer(),这种力会随着玩家移动在每个 tick 重新计算。其强度会根据半径和衰减方式随距离减弱——参见 施加击退冲量 有关 KnockbackFalloff 选项。负强度会反转效果,像旋涡或引力井一样持续将玩家拉向该点。
📔 注: 排斥源点是 fromPosition 你传入的向量—— 而不是 该 源 实体的位置。该 源 实体仅用作标识符,以便你之后更新或移除该力。它的位置、旋转和缩放都会被完全忽略。
源: 用作该力标识符的实体——其位置不会被使用。fromPosition: 玩家被推离的世界空间点。强度: 基础力强度。负值会产生吸引而不是排斥。半径: 最大作用距离(默认:Infinity).衰减: 强度如何随距离减弱(默认:CONSTANT).
滑翔时的力
当玩家处于滑翔状态时,持续力的表现会有所不同:
持续力——来自
applyForceToPlayer(),applyForceToPlayerForDuration(),或applyRepulsionForceToPlayer()—— 强 1.5 倍,因为展开的滑翔器会捕捉气流。风区和水流对滑翔中的玩家会更有响应。持续力的向上分量可以 抬升 滑翔中的玩家。滑翔器的下落速度上限只会限制玩家下降的速度,并不会抵消向上运动,因此倾斜或垂直的风流会沿着力的完整方向推动玩家。
一次性冲量——来自 applyImpulseToPlayer() 或 applyKnockbackToPlayer() ——不受滑翔影响。无论滑翔器是打开还是关闭,它们的表现都相同。
你可以结合这些行为来构建诸如热上升气流之类的机制,把滑翔中的玩家向上托起;或者构建在滑翔器展开时更容易通过的风道。要调整滑翔器的下落速度或前进速度,请使用 AvatarLocomotionSettings 组件,参见 移动设置.
将本地方向转换为世界空间
使用 Transform.localToWorldDirection() 将方向向量从实体的本地坐标空间转换到世界空间,并考虑完整的父级层级。当需要相对于旋转实体施加力时,这很有用——例如,将玩家从旋转障碍物的某个特定面推开。
实体: 定义该方向的源实体,其本地空间决定方向。本地方向: 实体本地坐标中的方向向量。
返回世界坐标中的方向向量。
这只适用于 旋转 ——不考虑平移或缩放——因此非常适合直接传递给力和冲量函数的方向向量。
最后更新于