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

触发区域

了解如何在场景中使用触发区域

触发区域可让你对玩家进入或离开某个区域,或任何其他实体进入或离开某个区域的事件作出响应。这是创建交互式场景的基础工具。你可以用它们来实现诸如玩家靠近时打开门,或在球进入球门时得分之类的功能。

使用触发区域

要使用触发区域,你需要向一个 TriggerArea 组件添加到一个实体,然后使用 triggerAreaEventsSystem 来响应这些事件。

import { engine, Transform, TriggerArea, triggerAreaEventsSystem } from '@dcl/sdk/ecs'

// 创建实体
const triggerEntity = engine.addEntity()

// 设置 Transform
Transform.create(triggerEntity, {
  position: Vector3.create(8, 0, 8)
  })

// 触发区域
TriggerArea.setBox(triggerEntity)

// 触发区域激活时的事件
triggerAreaEventsSystem.onTriggerEnter(triggerEntity, function(result) {
  if (result.trigger?.entity !== engine.PlayerEntity) return;
  console.log('玩家进入了触发区域!')
})

默认情况下, TriggerArea 组件会对 任何 玩家走入区域的事件作出响应。上面的代码添加了 if (result.trigger?.entity !== engine.PlayerEntity) return 以检查引发该事件的实体是否是当前玩家,而不是别人的化身

触发区域形状

触发区域可以是盒形或球形。

💡 提示:球形是引擎最容易计算的形状,因为它只需检查球心到边界的距离即可实现。如果不确定,就用球形。

要改变触发区域的大小,你可以使用 缩放 组件的 Transform 组件,位于持有该 TriggerArea.

调试

要调试场景并查看触发区域覆盖的范围,你可以添加一个 MeshRenderer 组件到带有触发区域的实体上,并将形状设置为你想要调试的形状。默认网格的尺寸将与触发区域的尺寸一致。

触发区域事件

你可以使用 triggerAreaEventsSystem 来响应触发区域的不同事件:

  • onTriggerEnter:当实体进入触发区域时触发。

  • onTriggerExit:当实体离开触发区域时触发。

  • onTriggerStay:当实体处于触发区域内时,每一帧都会触发。

触发事件响应

当触发区域事件被触发时,你可以使用 result 参数来获取被触发实体和触发该事件的实体的信息。

以下属性可在 result 参数中获取:

  • triggeredEntity:被触发实体的 ID(拥有触发区域的实体)

  • triggeredEntityPosition:被触发实体的位置

  • triggeredEntityRotation:被触发实体的旋转

  • eventType:触发事件的类型(ENTER、EXIT、STAY)

  • 时间戳:触发事件的时间戳

  • 触发器:包含以下字段的对象:

    • 实体:触发该触发器的实体的 ID(进入触发区域的实体)

    • layers:触发该触发器的实体的碰撞层

    • 位置:触发该触发器的实体的位置

    • 旋转:触发该触发器的实体的旋转

    • 缩放:触发该触发器的实体的缩放

检测玩家进入区域

触发区域最常见的用途是响应玩家的进出。两种碰撞层可用于检测化身,使用哪一种取决于场景需要对谁作出响应:

  • ColliderLayer.CL_MAIN_PLAYER:检测 仅本地机器上的玩家。当响应只针对该玩家时使用,例如将其传送、为其播放声音,或跟踪其任务进度。这也是性能开销最低的选项。

  • ColliderLayer.CL_PLAYER:检测 所有化身,包括本地玩家以及场景中渲染的其他所有玩家。当前面的人是谁都重要时使用,例如有人靠近就打开的门,或统计房间里有多少人。如果未指定,这是默认层。

以下示例仅对本地玩家作出响应:

当使用 CL_PLAYER时,所有化身都会激活触发区域。要判断触发它的化身是否为本地玩家,将 result 中的实体与 engine.PlayerEntity:

在大多数情况下,与其尝试检测所有玩家,理想做法是只检测当前玩家(通过 CL_MAIN_PLAYER)然后在所有玩家之间同步该触发器的效果。例如,滑动门只会为你的化身打开,但该门的开启状态会共享给其他所有玩家。

💡 提示:仅包含化身层(CL_PLAYER, CL_MAIN_PLAYER,或两者)的触发区域已优化:引擎会将其放在仅限化身的物理层上,因此与非化身的任何对象发生的重叠都会在到达场景代码之前被物理引擎丢弃。掩码恰好等于 CL_MAIN_PLAYER 会进一步优化:它会在到达处理器之前短路任何与非本地玩家碰撞体的重叠,因此只检测本地玩家几乎是零成本的。

触发区域层

使用……的可选第二个参数 TriggerArea 组件来设置可激活触发区域的层。默认情况下,触发区域只会被图层 ColliderLayer.CL_PLAYER以无代码方式触发声音播放,参见 检测玩家进入区域.

你可以通过将其作为……的第二个参数传入,来更改碰撞层以检测任何其他实体 TriggerArea 组件。

允许的值与 MeshCollider 组件遍历所有玩家。详见 碰撞层 了解更多详情。

  • ColliderLayer.CL_PLAYER:任何化身(本地 + 远程)

  • ColliderLayer.CL_MAIN_PLAYER:仅本地玩家

  • ColliderLayer.CL_PHYSICS

  • ColliderLayer.CL_POINTER

  • ColliderLayer.CL_CUSTOM1 到 CL_CUSTOM8

  • ColliderLayer.CL_NONE

💡 提示:这些层 CL_CUSTOM1 到 CL_CUSTOM8 本身没有任何特殊行为,你可以按最适合场景的方式使用它们。

你也可以设置触发区域一次检测多个层。

这会在任何具有以下层的实体进入触发区域时激活它 CL_CUSTOM1 或 CL_CUSTOM2 。

💡 提示:如需查看一个可运行的示例,演示 TriggerArea 端到端地使用,可查看 75,-9-trigger-areas 测试场景,其中涵盖 ENTER/EXIT 线协议以及 SDK 的逐 tick onTriggerStay 合成、旋转区域、在自定义碰撞层上移动的触发器,以及附着在下落实体上的区域。若要查看碰撞层本身的行为,请参见 5,5-collider-layers.

最后更新于