用户数据
在玩家与场景交互时获取他们的数据。
玩家位置和旋转
使用 PlayerEntity 以及 CameraEntity 通过检查它们的 Transform 组件,来了解玩家的位置和旋转。
function getPlayerPosition() {
if (!Transform.has(engine.PlayerEntity)) return
if (!Transform.has(engine.CameraEntity)) return
//玩家位置
const playerPos = Transform.get(engine.PlayerEntity).position
//玩家旋转
const playerRot = Transform.get(engine.PlayerEntity).rotation
//摄像机位置
const CameraPos = Transform.get(engine.CameraEntity).position
//摄像机旋转
const CameraRot = Transform.get(engine.CameraEntity).rotation
console.log('玩家位置: ', playerPos)
console.log('玩家旋转: ', playerRot)
console.log('摄像机位置: ', CameraPos)
console.log('摄像机旋转: ', CameraRot)
}
engine.addSystem(getPlayerPosition)PlayerEntity 位置: 头像的位置,位于胸部高度。大约在地面上方 0.88 米。
PlayerEntity 旋转: 头像面向的方向,以四元数表示。
CameraEntity 位置:
第一人称下:与头像位置相同,但位于眼睛高度。大约在地面上方 1.75 米。
第三人称下:可能会因摄像机移动而变化。
PlayerEntity 旋转:
第一人称下:与头像面向的方向相似,以四元数表示。可能会与玩家的旋转略有不同的舍入。
第三人称下:可能会因摄像机移动而变化。
📔 注意: 请避免在 engine.PlayerEntity 或 engine.CameraEntity 在初始场景加载时引用,因为如果实体尚未初始化,这可能会导致错误。为避免此问题,请在 main() 函数中使用这些引用,或者在由 main()间接调用的函数中使用。你也可以将该行为封装在一个异步 executeTask 块中.
另一个选择是在系统中引用这些实体。它们总是可用,因为系统的第一次执行会在场景已正确初始化后被调用。
获取所有玩家
场景中的所有玩家都有一个 Transform 组件。该组件在头像中为只读。要获取所有玩家的位置, 遍历所有具有 一个 PlayerIdentityData 组件的实体。
上面的代码会遍历所有具有 Transform 和一个 PlayerIdentityData 组件的实体,并记录它们的数据。你可以使用同样的方法获取所有玩家的任何可用数据。
参见 事件监听器 ,了解如何在新玩家加入场景时进行检测和响应。
获取玩家数据
使用 getPlayer() 来获取当前玩家或场景中任何其他玩家的数据。
getPlayer() 返回以下内容:
姓名: (字符串) 玩家的用户名,其他人在世界中看到的名称userId: (字符串) 用于标识玩家的字符串。对于使用钱包连接的玩家,这就是钱包地址,且为小写。对于访客账户,这是本地生成的标识符。isGuest: (布尔值) 指示玩家是否拥有公钥。 如果 玩家是没有公钥的访客账户,则为 True。position: (Vector3) 头像在场景中的位置。avatar: 一个嵌套对象,包含玩家基础头像和外观的数据。wearables: 一个数组,包含玩家当前穿戴的每件可穿戴物品的标识符。例如urn:decentraland:off-chain:base-avatars:green_hoodie。所有可穿戴物品都有类似的标识符,即使它们是 NFT。表情动作: 一个数组,包含玩家当前在快速访问轮盘中装备的每个表情动作的标识符。entity: 对玩家实体的引用。这在传递给其他函数,或为其添加自定义组件时很有用。
该 avatar 对象包含以下嵌套信息:
bodyShapeUrn: 头像整体体型的标识符。可以是urn:decentraland:off-chain:base-avatars:BaseFemale表示女性,或urn:decentraland:off-chain:base-avatars:BaseMale表示男性。skinColor: 玩家肤色,类型为Color3eyesColor: 玩家眼睛颜色,类型为Color3hairColor: 玩家头发颜色,类型为Color3姓名: 玩家的姓名。
📔 注意: 根据加载时间,玩家数据可能在场景的第一帧不可用。你应该验证数据是否已返回,否则在几毫秒后再次尝试。
要获取场景中某个特定玩家(不同于当前玩家)的数据,请运行 getPlayer() 带有一个 userId 属性的对象
上面的代码片段会遍历所有具有一个 PlayerIdentityData 组件的实体,也就是场景中所有头像实体。然后会为该实体运行 getPlayer() 。
getPlayer() 只能获取当前处于同一场景中的玩家数据;他们不一定必须在可视范围内,但应连接到同一个通讯岛。要在预览中试试这个功能,请打开第二个标签页并使用不同账户登录,然后让两个玩家都站在场景中。
📔 注意: 用户 ID 必须始终为小写。如果复制钱包地址,请确保所有字符都已设为小写。
任意玩家的数据
要获取任意玩家的信息,请向内容服务器发起一次 REST API 调用 。
这些信息可通过以下 URL 获取,只需在 URL 参数中附加玩家的用户 ID。
https://peer.decentraland.org/lambdas/profile/<player user id>
此 API 可获取以下信息:
displayName: (字符串) 玩家的用户名,其他人在世界中看到的名称userId: (字符串) 用于标识玩家的 UUID 字符串。如果玩家拥有公钥,此字段的值将与公钥相同。hasConnectedWeb3: (布尔值) 指示玩家是否拥有公钥。 如果 如果玩家拥有一个,则为 True。publicKey: (字符串) 玩家以太坊钱包的公钥。如果玩家以访客身份登录,没有关联钱包,则此字段为null.avatar: 一个嵌套对象,包含玩家外观的数据。version: (数字) 一个版本号,每当玩家更改任意设置时都会加一。如果遇到冲突数据,可使用它来判断哪个版本更新。
📔 注意: 对于与玩家相关的任何 Ethereum 交易,请始终使用 publicKey 字段,而不是 userId,以避免处理不存在的钱包。
该 avatar 对象包含以下嵌套信息:
wearables:WearableId[]一个数组,包含玩家当前穿戴的每件可穿戴物品的标识符。例如urn:decentraland:off-chain:base-avatars:green_hoodie。所有可穿戴物品都有类似的标识符,即使它们是 NFT。bodyShape: 头像整体体型的标识符。可以是urn:decentraland:off-chain:base-avatars:BaseFemale表示女性,或urn:decentraland:off-chain:base-avatars:BaseMale表示男性。skin: 一个带有color字段的对象,其中保存玩家肤色,类型为{ r, g, b, a }0 到 1 之间的数字。hair: 一个带有color字段,其中保存玩家头发颜色,类型为{ r, g, b, a }0 到 1 之间的数字。eyes: 一个带有color字段,其中保存玩家眼睛颜色,类型为{ r, g, b, a }0 到 1 之间的数字。snapshots: 一个嵌套对象,包含不同分辨率下玩家 .jpg 图像的 base64 表示。face256: 字符串 玩家脸部的 256x256 像素图像。body: 字符串 玩家站立姿势的全分辨率图像,尺寸为 512x1024 像素。
❗警告 头像的快照将在未来被弃用,并且将不再作为头像数据的一部分返回。建议改用 AvatarTexture ,参见 头像肖像.
不同于 getPlayer(),此选项不只限于当前处于同一场景中的玩家,甚至不局限于同一服务器。使用这种方法,你可以获取过去登录过服务器的任意玩家的数据。
如果你知道要查询的玩家连接到了哪个服务器,你可以通过向该特定服务器发送请求来获得更及时的数据。例如,如果玩家更换衣服,该信息会立即在玩家所在服务器中可用,但传播到 peer.decentraland.org 服务器通常需要几分钟。
https://<player server>/lambdas/profile/<player user id>
此示例结合了 myProfile.userId 和 getRealm() ,直接从玩家所在的服务器获取玩家数据:
玩家数据组件
不使用 getPlayer(),你可以直接从一系列组件中读取数据,这些组件将数据存储在每个玩家实体上。存在以下组件:
PlayerIdentityData: 存储玩家地址以及一个isGuest属性,用于标记访客账户。AvatarBase: 存储基础头像的数据,包括:姓名: 玩家的姓名。bodyShapeUrn: 对应男性或女性体型的 ID。skinColor: 玩家肤色,类型为Color3eyesColor: 玩家眼睛颜色,类型为Color3hairColor: 玩家头发颜色,类型为Color3
AvatarEquippedData: 已装备的可穿戴物品和表情动作列表。wearableUrns: 玩家当前已装备的可穿戴物品列表。emoteUrns: 玩家当前在快速访问轮盘中已装备的表情动作列表。
AvatarEmoteCommand: 关于玩家当前正在播放的表情动作的信息。它包括:emoteUrn: 自玩家进入场景以来所播放的最后一个表情动作的 URNloop: 如果该表情动作正在循环,则为 Truetimestamp: 触发该表情动作的时间
📔 注意:所有这些组件都是只读的。你无法在场景中更改它们的值。
获取可携带体验
可携带体验本质上是不受地块限制的场景。玩家可以在他们在 Decentraland 中前往的任何地方携带它们,为世界叠加一层新的内容。智能可穿戴物品就是可携带体验的例子。你可能想知道玩家是否穿戴了其中之一,因为智能可穿戴物品可能让玩家获得在竞技游戏中可被视为作弊的能力。例如,在平台游戏中,穿着喷气背包的玩家相对于其他玩家具有非常不公平的优势。
作为场景创建者,你可能希望限制穿戴可携带体验的玩家在你的场景中能做什么。使用 getPortableExperiencesLoaded() 来检查玩家当前是否激活了任何可携带体验。
getPortableExperiencesLoaded() 返回一个对象数组,其中每个对象都包含一个 id 属性。在可穿戴物品的情况下,id 就是该物品的 URN。
获取玩家可穿戴物品的详细信息
该 getPlayer() 函数只返回可穿戴物品 ID 的列表,而不包含每个物品的信息。也许你想检查某一特定类别的可穿戴物品(例如:帽子),或者某一特定稀有度的可穿戴物品(例如:神话级);为此你需要获取玩家可穿戴物品的更详细信息。
进行一个 REST API 调用 到以下 URL 的调用,以获取当前可用的所有可穿戴物品的完整更新列表,并附带每件物品的详细信息。
${playerRealm.realmInfo.baseUrl}/lambdas/collections/wearables-by-owner/${userData.userId}?includeDefinitions
📔 注意: 要构造这个 URL,你必须获取 realm(可能通过 getRealm())以及玩家的 ID(可能通过 getPlayer())
此功能可以与获取玩家信息结合使用,例如仅允许穿戴来自万圣节合集的任何可穿戴物品,或者任何稀有度为 传奇 的可穿戴物品的玩家进入某个地点。
检查玩家的摄像机模式
玩家在探索 Decentraland 时可以使用第一人称或第三人称摄像机。通过检查值 CameraMode 组件的 engine.CameraEntity 实体来判断玩家正在使用哪种模式。
📔 注意: 摄像机信息仅对运行该场景的当前玩家可用。你无法查询任何其他玩家的摄像机数据。
摄像机模式使用来自 CameraType 枚举的值。可能的值如下:
CameraType.CT_FIRST_PERSONCameraType.CT_THIRD_PERSON
该 CameraMode 组件的 engine.CameraEntity 是只读的,你不能通过它强制玩家更改摄像机模式。
了解摄像机模式对于微调场景机制非常有用,可以更好地适应该模式下更舒适的操作方式。例如,在第三人称模式下,小目标更难点击。
📔 注意: 请避免在 engine.CameraEntity 在初始场景加载时引用,因为如果实体尚未初始化,这可能会导致错误。为避免此问题,请在 main() 函数中使用这些引用,或者在由 main()间接调用的函数中使用。你也可以将该行为封装在一个异步 executeTask 块中.
另一个选择是在系统中引用这个实体。它总是可用,因为系统的第一次执行会在场景已正确初始化后被调用。
检查玩家是否锁定了光标
玩家可以在两种光标模式之间切换: 锁定光标 模式,用于控制摄像机,或 解锁光标 模式,用于在 UI 上自由移动光标。
玩家通过点击 鼠标右键 或按下 Esc 键,并通过在屏幕任意位置单击将光标重新锁定。
检查 PointerLock 场景的 相机实体 以了解当前光标模式。
参见 事件监听器 以了解如何轻松响应光标状态变化。
你也可以通过写入 isPointerLocked 字段来强制设置玩家的光标状态, PointerLock 组件中的 engine.CameraEntity。参见 锁定或解锁光标 示例。
📔 注意: 请避免在 engine.CameraEntity 在初始场景加载时引用,因为如果实体尚未初始化,这可能会导致错误。为避免此问题,请在 main() 函数中使用这些引用,或者在由 main()间接调用的函数中使用。你也可以将该行为封装在一个异步 executeTask 块中.
另一种方法是在系统内部引用该实体。它将始终可用,因为系统的第一次执行会在场景已正确初始化后才被调用。
检查玩家的光标位置
使用 PrimaryPointerInfo 组件中的 engine.RootEntity 以获取玩家的光标位置。这可用于拖放交互、滑动手势等机制。
📔 注意: 请避免在 engine.RootEntity 在场景初始加载时,因为如果实体尚未初始化,可能会导致错误。为避免此问题,请始终在系统内部引用该实体。它将始终可用,因为系统的第一次执行会在场景已正确初始化后才被调用。
该 PrimaryPointerInfo 组件会返回一个包含以下属性的对象:
screenCoordinates: (Vector2) 场景中光标的位置,以像素表示。原点位于屏幕左上角,其中y向下增大——与UiTransform和UiCanvasInformation相同的坐标空间。当光标被锁定时,这里显示屏幕中心。screenDelta: (Vector2) 自上一帧以来光标位置的变化量,以像素表示。参见 Mouse Movement 了解详情和示例。worldRayDirection: (Vector3) 一个表示从相机到光标的射线方向的向量。原点是相机位置。可用它来计算光标在世界中的位置。pointerType:0 表示无,1 表示鼠标
该 PrimaryPointerInfo 组件是只读的,你无法强制玩家更改光标位置。
以下示例展示了如何在 UI 元素上显示光标位置。
ui.tsx 文件:
index.ts 文件:
你可以使用 worldRayDirection 来设置 方向 射线投射的字段,以判断某个实体是否位于光标的视线中。参见 Raycasting 了解更多细节。
最后更新于