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

点击事件

了解如何处理场景中的用户点击。

Decentraland 场景可以检测用于控制玩家化身的所有按钮所触发的输入操作。这些包括指针点击、若干操作按钮,以及用于移动化身的按键。按钮事件可以来自桌面客户端上的鼠标和键盘、来自 移动应用中上的屏幕控件、来自 VR 控制器,或来自其他输入设备——SDK 会将这些都以相同方式解释。

你可以检测针对某个实体的输入操作。这涉及在玩家的光标指向该实体的碰撞体时按下一个按钮。你也可以检测 global 输入事件,这类事件是在任何时候激活输入时发生的,不考虑指针当前瞄准的位置。

根据使用场景的不同,有几种不同的方式来处理输入操作。

  • 注册回调:为单个实体添加交互的最简单方式。写一条语句来设置回调函数和悬停反馈。

  • 基于系统的:非常适合处理多个具有相似行为的实体。使用系统遍历相似实体,并查询每个实体的输入操作,用相同的逻辑处理它们。悬停反馈需要单独设置。这种方法也适用于处理全局输入操作。

  • 高级:读取每个实体的原始响应数据,包括时间戳和输入事件历史记录。这对于定义自定义交互模式很有用。

在 Creator Hub 中使用 Scene Editor

处理实体上的点击事件最简单的方法是使用场景编辑器。使用无代码 点击时 或 在输入操作时 在项目上触发器,在点击时调用操作。或者使用 全局点击时, 全局主键时 或 全局次键时 触发器来响应全局按钮事件。参见 让任意项目变为智能项目.

简单示例

要检测实体上的点击,请使用 pointerEventsSystem.onPointerDown.

pointerEventsSystem.onPointerDown(
	{
		entity: myEntity,
		opts: { button: InputAction.IA_PRIMARY, hoverText: '点击' },
	},
	function () {
		console.log('已点击实体')
	}
)

参见 注册回调 以获取更多信息。

悬停反馈

让玩家知道某个实体可交互非常重要。否则,他们可能会完全错过你构建的体验。让玩家挨个点击每个对象,只期待其中一个有反应,这种体验并不好。

当你使用 注册回调 方法时,只要玩家将光标移到对象上方,就会显示两种反馈:

  • 实体边缘会被高亮显示(仅在 Decentraland 2.0 桌面客户端上)。如果实体足够近,可以点击,高亮为绿色;如果实体太远,高亮为红色。

  • 光标附近会出现一个带有 UI 文本的悬停提示,表明如果点击将会发生什么。

当使用 基于系统的 方法时,你可以通过添加一个 PointerEvents 组件到可点击实体上来达到相同效果。

实体高亮和悬停提示都可以通过这些方法和组件中的属性来禁用。

你也可以实现 高级自定义提示,例如你可以播放声音,让实体在被指向时变色、旋转或放大等。无论你做什么,都要确保它是一个清晰的提示标识。

障碍

按钮事件会发射射线,只与路径上订阅了指针事件碰撞层的第一个实体发生交互。只要实体处于其距离限制范围内,这一点就成立。如果实体同时为摄像机和化身定义了距离限制,那么两者中任意一个足够近就可以。

要让实体被指针事件的射线拦截,必须满足以下任一条件:

如果另一个实体的碰撞体挡在玩家想交互的实体前面,玩家就无法点击后面的实体,除非该实体没有碰撞体,或者这个碰撞体被配置为不响应指针事件碰撞层。

指针按钮

以下输入可由检测输入事件的任一方法来处理。

  • 的鼠标,以及一个鼠标用于: 鼠标左键 在电脑上, 交互按钮 在移动端。

  • InputAction.IA_PRIMARY: E 在电脑上的按键, E 按钮 在移动端。

  • 用于: F 在电脑上的按键, F 按钮 在移动端。

  • InputAction.IA_ACTION_3: 1 在电脑上的按键, 1 按钮 在移动端。 在移动端上不易触及——不建议用于移动端交互。

  • InputAction.IA_ACTION_4: 2 在电脑上的按键, 2 按钮 在移动端。 在移动端上不易触及——不建议用于移动端交互。

  • InputAction.IA_ACTION_5: 3 在电脑上的按键, 3 按钮 在移动端。 在移动端上不易触及——不建议用于移动端交互。

  • InputAction.IA_ACTION_6: 4 在电脑上的按键, 4 按钮 在移动端。 在移动端上不易触及——不建议用于移动端交互。

  • InputAction.IA_JUMP: 空格 在电脑上的按键, 跳跃按钮 在移动端。

  • InputAction.IA_FORWARD: W 在电脑上的按键。

  • InputAction.IA_LEFT: 一个 在电脑上的按键。

  • InputAction.IA_RIGHT: D 在电脑上的按键。

  • InputAction.IA_BACKWARD: S 在电脑上的按键。

  • InputAction.IA_WALK: 控制 在电脑上的按键。

  • InputAction.IA_MODIFIER: Shift 在电脑上的按键。

每个 InputAction 被从键盘上的字面输入中抽象出来,这样它就可以根据设备映射到不同的输入。出于同样的原因,键盘上的所有按钮都不能用于跟踪按钮事件,只有用于移动和交互的按钮可以。这个有意的限制可确保内容能跨桌面端、 移动客户端以及未来的设备(如 VR 控制器和其他游戏控制器)兼容。

指针事件类型

每种输入都可以产生以下类型的指针事件。下面每一项都是 PointerEventType 枚举。

  • PET_DOWN:玩家在光标指向实体的碰撞体时按下某个特定按钮。

  • PET_UP:玩家在光标指向实体的碰撞体时松开某个特定按钮。

  • PET_HOVER_ENTER:玩家的光标开始指向实体的碰撞体。

  • PET_HOVER_LEAVE:玩家的光标停止指向实体的碰撞体。

  • PET_PROXIMITY_ENTER:玩家走进实体的接近范围,无论他们在看什么。

  • PET_PROXIMITY_LEAVE:玩家离开实体的接近范围。

参见 近距离事件 了解如何使用基于接近距离的交互。

来自输入操作的数据

所有输入操作都包含事件数据,包括被激活的按钮以及当时指针指向的位置等信息。

可从任何输入事件中获得以下信息:

  • 模拟:可选数字,仅出现在来自模拟输入(如摇杆)的事件中,用于存储输入的模拟值。

  • 按钮连接您的钱包:按下的是哪个按钮 ID。该数字对应于 InputAction 枚举,其中列出了所有可用按钮。

  • state:指针事件类型,来自枚举 PointerEventType. 0 指的是 PointerEventType.PET_UP, 1 为 PointerEventType.PET_DOWN, 2 为 PointerEventType.PET_HOVER_ENTER, 3 为 PointerEventType.PET_HOVER_LEAVE, 4 为 PointerEventType.PET_PROXIMITY_ENTER, 5 为 PointerEventType.PET_PROXIMITY_LEAVE

  • 时间戳:一个 Lamport 时间戳 用于标识每个按钮事件。

    注意:此时间戳并不是基于当前时间编号的。可以将其视为一个从 0 开始、每发生一个事件就加 1 的计数器。

  • 命中:一个包含有关命中事件以下数据的对象:

    • entityId:被射线命中的实体的 ID 数字。

    • meshName: 字符串 ,包含被命中的 3D 模型中具体网格的内部名称。当一个 3D 模型由多个网格组成时,这很有用。

    • globalOrigin: Vector3 用于表示射线起点的位置(相对于场景)

    • 方向: Vector3 与射线的方向向量一起,位于全局坐标中

    • 位置: Vector3 用于表示射线与命中实体相交的位置(相对于场景)

    • length:射线从起点到命中实体发生位置的长度。

    • normalHit: Vector3 带有一个归一化方向向量,用于描述世界空间中命中法线的角度。

根据你使用的输入操作处理方式,这些数据的访问方法不同。

使用 注册回调 方法时,传入回调函数的第一个参数包含整个数据结构。

使用 基于系统的 方法时,请使用 inputSystem.getInputCommand() 来获取这些数据。

使用 高级 方法中, PointerEventsResult 包含一个该实体最近所有指针事件的历史列表。

锁定或解锁光标

💡 注意: PointerLock 是桌面客户端的概念(鼠标光标锁定 vs. 解锁)。它对 移动应用中没有影响,因为那里的输入基于触摸。

Decentraland 桌面客户端中的玩家可以用光标在两种不同的交互模式之间切换:

  • 锁定光标:移动鼠标会改变摄像机,点击事件会发生在屏幕中央的准星处

  • 解锁光标:光标可以独立于摄像机自由移动,玩家可以点击屏幕任意位置,与 3D 空间或 UI 进行交互

这些交互模式适用于不同类型的游戏机制,你可能希望让玩家根据你的场景需求采用其中一种。你也可能希望暂时确保玩家的光标处于解锁状态,以便他们与 UI 交互;这对不熟悉这一控制方式的新玩家尤其有帮助。

要更改玩家的光标状态,请使用 PointerLock 组件,作用于 engine.CameraEntity 实体,从玩家摄像机位置向前追踪一条射线。

你也可以通过读取 PointerLock 组件的状态来查询玩家的光标状态。

使用 .onChange 函数来响应指针状态的变化。下面的示例会强制光标始终处于解锁状态。

最后更新于