For the complete documentation index, see llms.txt. This page is also available as Markdown.

玩家物理

对玩家头像施加力和冲量

你可以在场景代码中对玩家的角色施加物理力。这使你可以创建诸如跳板、风区、击退效果、爆炸等游戏机制。

你可以施加两种力:

  • 冲量: 一次性的瞬时推动。用于将玩家猛然弹向空中或将其击退等突发的离散效果。

  • 持续力: 在其激活期间每个 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 —— 平滑线性减弱,在半径边缘降为 0

  • KnockbackFalloff.INVERSE_SQUARE —— 急剧的、符合物理的衰减

如果玩家正好位于源位置,玩家会被直接向上推开。负强度则会将玩家拉向该点,而不是把他们推开。

相同的 KnockbackFalloff 值也适用于 applyRepulsionForceToPlayer().

施加持续力

使用 Physics.applyForceToPlayer() 来对玩家施加持续的力。与冲量不同,只要该力处于激活状态,它就会在每个 tick 施加。

  • 源: 用于标识该力来源的实体——可用它在之后更新或移除该力。

  • 向量: 方向和强度的组合——向量的长度表示力的大小。

源实体的位置并不重要——它仅用作标识符。

力向量始终处于 世界空间。如果你需要相对于旋转实体的方向,请使用 Transform.localToWorldDirection() 先将其转换——参见 将本地方向转换为世界空间.

与 applyImpulseToPlayer()一样,你也可以传入一个 方向 和 强度 分别传入——参见 施加冲量:

如果你调用 applyForceToPlayer() 再次使用相同的源实体调用时,会替换该源之前施加的力。如果累积了多个力源,它们的向量会在每个 tick 求和。

移除持续力

要停止施加某个力,请调用 Physics.removeForceFromPlayer() 并传入用于创建该力的源实体引用。如果该实体当前没有在施加力,则此调用会被安全忽略。

  • 源: 施加该力时使用的实体。

在限定时长内施加力

使用 Physics.applyForceToPlayerForDuration() 来在指定时间内施加力。持续时间以秒为单位。时间到后该力会自动移除。再次使用相同的源实体调用会重置计时器。

  • 源: 用于标识该力来源的实体。

  • 持续时间: 力持续的时长,单位为秒。

  • 向量: 方向和强度的组合——向量的长度表示力的大小。

该 方向 + 强度 也提供重载版本——参见 施加冲量:

风区示例

此示例会创建一个风洞,在玩家进入时将其推动,离开时停止:

施加排斥力

使用 Physics.applyRepulsionForceToPlayer() 来持续将玩家推离空间中的一个固定点。这适用于磁力排斥场、力场屏障,或让玩家保持距离的悬浮物体等效果。不同于 applyKnockbackToPlayer(),这种力会随着玩家移动在每个 tick 重新计算。其强度会根据半径和衰减方式随距离减弱——参见 施加击退冲量 有关 KnockbackFalloff 选项。负强度会反转效果,像旋涡或引力井一样持续将玩家拉向该点。

  • 源: 用作该力标识符的实体——其位置不会被使用。

  • fromPosition: 玩家被推离的世界空间点。

  • 强度: 基础力强度。负值会产生吸引而不是排斥。

  • 半径: 最大作用距离(默认: Infinity).

  • 衰减: 强度如何随距离减弱(默认: CONSTANT).

滑翔时的力

当玩家处于滑翔状态时,持续力的表现会有所不同:

  • 持续力——来自 applyForceToPlayer(), applyForceToPlayerForDuration(),或 applyRepulsionForceToPlayer() —— 强 1.5 倍,因为展开的滑翔器会捕捉气流。风区和水流对滑翔中的玩家会更有响应。

  • 持续力的向上分量可以 抬升 滑翔中的玩家。滑翔器的下落速度上限只会限制玩家下降的速度,并不会抵消向上运动,因此倾斜或垂直的风流会沿着力的完整方向推动玩家。

一次性冲量——来自 applyImpulseToPlayer() 或 applyKnockbackToPlayer() ——不受滑翔影响。无论滑翔器是打开还是关闭,它们的表现都相同。

你可以结合这些行为来构建诸如热上升气流之类的机制,把滑翔中的玩家向上托起;或者构建在滑翔器展开时更容易通过的风道。要调整滑翔器的下落速度或前进速度,请使用 AvatarLocomotionSettings 组件,参见 移动设置.

将本地方向转换为世界空间

使用 Transform.localToWorldDirection() 将方向向量从实体的本地坐标空间转换到世界空间,并考虑完整的父级层级。当需要相对于旋转实体施加力时,这很有用——例如,将玩家从旋转障碍物的某个特定面推开。

  • 实体: 定义该方向的源实体,其本地空间决定方向。

  • 本地方向: 实体本地坐标中的方向向量。

返回世界坐标中的方向向量。

这只适用于 旋转 ——不考虑平移或缩放——因此非常适合直接传递给力和冲量函数的方向向量。

最后更新于