> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/content-creator-zh/chang-jing-sdk7/jiao-hu-xing/user-data.md).

# 用户数据

在玩家与你的场景交互时获取其数据。

## 玩家位置和旋转

使用 `PlayerEntity` 和 `CameraEntity` 要了解玩家的位置和旋转，可以通过检查他们的 `Transform` 组件的实体，其效果相同。

```ts
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 旋转**:
  * 第一人称：与头像面向的方向类似，以四元数表示。可能与玩家的旋转略有不同。
  * 第三人称：可能会因摄像机移动而变化。

{% hint style="warning" %}
**📔 注意**：请避免在 `engine.PlayerEntity` 或 `engine.CameraEntity` 在初始场景加载时，因为如果实体尚未初始化，这可能会导致错误。为避免此问题，请在以下位置内使用这些内容： `main()` 函数中，或在由其间接调用的函数中 `main()`。你也可以将该行为封装在一个异步 [`executeTask` 拦截](/creator/content-creator-zh/chang-jing-sdk7/bian-cheng-mo-shi/async-functions.md#the-executetask-function).

另一种选择是在系统内部引用这些实体。它们总是可用，因为系统的首次执行是在场景已经正确初始化之后触发的。
{% endhint %}

## 获取所有玩家

场景中的所有玩家都有一个 `Transform` 组件。该组件在头像中为只读。要获取所有玩家的位置， [遍历所有具有](/creator/content-creator-zh/chang-jing-sdk7/jiao-hu-xing/user-data.md) a `PlayerIdentityData` 组件。

```ts
import { PlayerIdentityData } from '@dcl/sdk/ecs'

for (const [entity, data, transform] of engine.getEntitiesWith(
	PlayerIdentityData,
	Transform
)) {
	console.log('玩家数据: ', { entity, data, transform })
}
```

上述代码会遍历所有具有一个 `Transform` 和一个 `PlayerIdentityData` 组件的实体，并记录它们的数据。你可以使用同样的方法获取所有玩家的任何可用数据。

参见 [事件监听器](/creator/content-creator-zh/chang-jing-sdk7/jiao-hu-xing/event-listeners.md#player-locks-or-unlocks-cursor) 了解如何在新玩家加入场景时进行检测和响应。

## 获取玩家数据

使用 `getPlayer()` 用于获取当前玩家或场景中其他任何玩家的数据。

```ts
import { getPlayer } from '@dcl/sdk/src/players'

export function main() {
	createCube(5, 1, 5)

	let myPlayer = getPlayer()

	if (myPlayer) {
		console.log('名称：', myPlayer.name)
		console.log('用户 ID：', myPlayer.userId)
	}
}
```

`getPlayer()` 返回如下内容：

* `名称`: *(string)* 玩家在世界中向其他人显示的用户名
* `userId`: *(string)* 标识玩家的字符串。对于通过钱包连接的玩家，这就是钱包地址，且以小写形式显示。对于访客账户，则是本地生成的标识符。
* `isGuest`: *(boolean)* 指示玩家是否拥有公钥。 *是* 如果玩家是没有公钥的访客账户。
* `位置`: *(Vector3)* 头像在场景中的位置。
* `化身`：一个嵌套对象，包含玩家基础头像和外观的数据。
* `wearables`：一个数组，包含玩家当前佩戴的每件穿戴物的标识符。例如 `urn:decentraland:off-chain:base-avatars:green_hoodie`。所有穿戴物都有类似的标识符，即使它们是 NFT。
* `emotes`：一个数组，包含玩家当前在快捷栏中装备的每个表情动作的标识符。
* `实体`：对玩家实体的引用。这在传递给其他函数或为其添加自定义组件时很有用。

该 `化身` 对象包含以下嵌套信息：

* `bodyShapeUrn`：头像整体体型的标识符。可以是 `urn:decentraland:off-chain:base-avatars:BaseFemale` 表示女性，或 `urn:decentraland:off-chain:base-avatars:BaseMale` 表示男性。
* `skinColor`：玩家的肤色，以 `Color3`
* `eyesColor`：玩家的眼睛颜色，以 `Color3`
* `hairColor`：玩家的发色，以 `Color3`
* `名称`：玩家的名称。

{% hint style="warning" %}
**📔 注意**：根据加载时间不同，玩家数据可能不会在场景的第一帧可用。你应该先确认数据已返回，否则在几毫秒后再尝试。
{% endhint %}

```ts
import { getPlayer } from '@dcl/sdk/src/players'

export function main() {
	createCube(5, 1, 5)

	let myPlayer = getPlayer()

	if (myPlayer) {
		console.log('是否为访客：', myPlayer.isGuest)
		console.log('名称：', myPlayer.name)
		console.log('用户 ID：', myPlayer.userId)
		console.log('头像形状：', myPlayer.position)
		console.log('头像形状：', myPlayer.avatar?.bodyShapeUrn)
		console.log('头像眼睛颜色：', myPlayer.avatar?.eyesColor)
		console.log('头像头发颜色：', myPlayer.avatar?.hairColor)
		console.log('穿戴物：', myPlayer.wearables)
		console.log('可用表情动作：', myPlayer.emotes)
	}
}
```

要获取场景中某个特定玩家（不同于当前玩家）的数据，请运行 `getPlayer()` 使用一个包含 `userId` 属性。

```ts
import { getPlayer } from '@dcl/sdk/src/players'

for (const [entity, data, transform] of engine.getEntitiesWith(
	PlayerIdentityData,
	Transform
)) {
	let player = getPlayer({ userId: data.address })
	console.log('玩家：', player?.name)
}
```

上述代码片段会遍历所有具有一个 `PlayerIdentityData` 组件，这意味着场景中的所有头像实体。然后它会对该实体运行 `getPlayer()` 针对该实体。

`getPlayer()` 只能获取当前站在同一场景中的玩家数据；他们不一定要在可视范围内，但应连接到同一个通信岛。要在预览中试试这一点，请打开第二个标签页并使用不同账户登录，然后让两个玩家都站在场景内。

{% hint style="warning" %}
**📔 注意**：用户 ID 必须始终为小写。如果复制钱包地址，请确保所有字符都为小写。
{% endhint %}

## 来自任意玩家的数据

要获取任意玩家的信息，请发起一次 [REST API 调用](/creator/content-creator-zh/chang-jing-sdk7/wang-luo/network-connections.md#call-a-rest-api) 到内容服务器。

这些信息通过以下 URL 暴露，在 URL 参数后追加玩家的用户 ID。

`https://peer.decentraland.org/lambdas/profile/<player user id>`

{% hint style="info" %}
**💡 提示**：在浏览器中试试这个 URL，看看响应的结构。
{% endhint %}

此 API 提供以下信息：

* `displayName`: *(string)* 玩家在世界中向其他人显示的用户名
* `userId`: *(string)* 标识玩家的 UUID 字符串。如果玩家有公钥，这个字段的值将与公钥相同。
* `hasConnectedWeb3`: *(boolean)* 指示玩家是否拥有公钥。 *是* 如果玩家有公钥。
* `publicKey`: *(string)* 玩家以太坊钱包的公钥。如果玩家以访客身份登录且没有绑定钱包，则此字段将为 `null`.
* `化身`：一个嵌套对象，包含玩家外观的数据。
* `version`: *(number)* 一个版本号，玩家每次更改任何设置时都会加 1。如果遇到冲突数据，请使用它来判断哪个版本更新。

{% hint style="warning" %}
**📔 注意**：对于与该玩家相关的任何以太坊交易，始终使用 `publicKey` 字段，而不是 `userId`，以避免处理不存在的钱包。
{% endhint %}

该 `化身` 对象包含以下嵌套信息：

* `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`：一个包含 `颜色` 字段，其中保存玩家肤色，格式为 `{ r, g, b, a }` 0 到 1 之间的数值。
* `hair`：一个包含 `颜色` 字段，其中保存玩家头发颜色，格式为 `{ r, g, b, a }` 0 到 1 之间的数值。
* `eyes`：一个包含 `颜色` 字段，其中保存玩家眼睛颜色，格式为 `{ r, g, b, a }` 0 到 1 之间的数值。
* `snapshots`：一个嵌套对象，包含玩家不同分辨率 .jpg 图像的 base64 表示。
  * `face256`: *字符串* 玩家面部的 256x256 像素图像。
  * `body`: *字符串* 玩家正面站立的全分辨率图像，尺寸为 512x1024 像素。

{% hint style="danger" %}
**❗警告** 头像快照将在未来被弃用，并且不再作为头像数据的一部分返回。推荐使用 `AvatarTexture` 来替代，参见 [头像肖像](/creator/content-creator-zh/chang-jing-sdk7/3d-nei-rong-ji-chu/materials.md#avatar-portraits).
{% endhint %}

不同于 `getPlayer()`，此选项不局限于当前在同一场景中的玩家，甚至不局限于同一服务器中的玩家。通过这种方式，你可以获取过去曾登录过服务器的任何玩家的数据。

如果你知道要查询的玩家连接到了哪个服务器，你可以通过向该特定服务器发送请求来获得更实时的数据。例如，如果玩家换了衣服，这些信息会立即出现在玩家所在的服务器中，但传播到 `peer.decentraland.org` 服务器可能需要几分钟。

`https://<player server>/lambdas/profile/<player user id>`

{% hint style="info" %}
**💡 提示**：你可以通过调用 `getRealm()` 并读取其 `realmInfo.baseUrl` 字段。
{% endhint %}

这个示例结合了 `myProfile.userId` 和 `getRealm()` 直接从玩家所在的服务器获取玩家数据：

```ts
import { getRealm } from '~system/Runtime'
import { myProfile } from '@dcl/sdk/network'

async function fetchPlayerData() {
	const { realmInfo } = await getRealm({})
	if (!realmInfo) return

	const url = `${realmInfo.baseUrl}/lambdas/profile/${myProfile.userId}`
	console.log('使用 URL：', url)

	try {
		const response = await fetch(url)
		const json = await response.json()

		console.log('完整响应：', json)
		console.log('玩家正在佩戴：', json.avatars[0].avatar.wearables)
	} catch {
		console.log('获取玩家数据时发生错误')
	}
}

fetchPlayerData()
```

## 玩家数据组件

不使用 `getPlayer()`，你可以直接从一系列存储在各个玩家实体上的组件中读取数据。存在以下组件：

* `PlayerIdentityData`：存储玩家地址以及一个 `isGuest` 用于标记访客账户的属性。
* `AvatarBase`：存储基础头像数据，包括：
  * `名称`：玩家的名称。
  * `bodyShapeUrn`：对应男性或女性体型的 ID。
  * `skinColor`：玩家的肤色，以 `Color3`
  * `eyesColor`：玩家的眼睛颜色，以 `Color3`
  * `hairColor`：玩家的发色，以 `Color3`
* `AvatarEquippedData`：已装备的穿戴物和表情动作列表。
  * `wearableUrns`：玩家当前已装备的可穿戴物品列表。
  * `emoteUrns`：玩家当前在快捷轮中装备的表情动作列表。
* `AvatarEmoteCommand`：关于玩家当前正在播放的表情动作的信息。包括：
  * `emoteUrn`：玩家自进入场景以来最后播放的表情动作的 URN
  * `loop`：如果该表情动作正在循环，则为真
  * `时间戳`：触发表情动作的时间

```ts
for (const [entity, data, base, attach, transform] of engine.getEntitiesWith(
	PlayerIdentityData,
	AvatarBase,
	AvatarEquippedData,
	Transform
)) {
	console.log('玩家数据：', { entity, data, transform, base, attach })
}
```

{% hint style="warning" %}
**📔 注意**：所有这些组件都是只读的。你无法在场景中更改它们的值。
{% endhint %}

## 获取便携体验

便携体验本质上是不受地块限制的场景。玩家可以将它们带到 Decentraland 的任何地方，在世界之上增加一层新的内容。智能穿戴物就是便携体验的示例。你可能想知道玩家是否佩戴了其中之一，因为智能穿戴物可能赋予玩家在竞技游戏中可被视为作弊的能力。例如，在平台游戏中，穿着喷气背包的玩家会比其他人有非常不公平的优势。

作为场景创建者，你可能希望限制佩戴便携体验的玩家在你的场景中能做什么。使用 `getPortableExperiencesLoaded()` 来检查玩家当前是否激活了任何便携体验。

```ts
import { getPortableExperiencesLoaded } from '~system/PortableExperiences'

executeTask(async () => {
	let portableExperiences = await getPortableExperiencesLoaded({})
	console.log(portableExperiences.loaded)
})
```

`getPortableExperiencesLoaded()` 返回一个对象数组，其中每个对象都包含一个 `id` 属性。在穿戴物的情况下，id 是该穿戴物的 URN。

## 获取玩家穿戴物的详细信息

该 `getPlayer()` 函数只返回穿戴物 ID 列表，不包含每个穿戴物的信息。也许你想检查某个特定类别的穿戴物（例如帽子），或者某种特定稀有度的穿戴物（例如神话级），为此你需要获取玩家穿戴物的更详细信息。

向 [REST API 调用](/creator/content-creator-zh/chang-jing-sdk7/wang-luo/network-connections.md#call-a-rest-api) 以下 URL 发起请求，以获取当前可用的所有穿戴物的完整更新列表，并包含每件的详细信息。

`${playerRealm.realmInfo.baseUrl}/lambdas/collections/wearables-by-owner/${userData.userId}?includeDefinitions`

{% hint style="warning" %}
**📔 注意**：要构造此 URL，你必须获取 realm（可能通过 `getRealm()`）以及玩家 ID（可能通过 `getPlayer()`)
{% endhint %}

这个功能可以与获取玩家信息结合使用，例如仅当玩家佩戴了万圣节系列中的任意穿戴物，或任何属于 *传奇* 稀有度时，才允许玩家进入某个地点。

{% hint style="info" %}
**💡 提示**：在浏览器中试试这个 URL，看看响应的结构。
{% endhint %}

```ts
import { getPlayer } from '@dcl/sdk/src/players'
import { getRealm } from '~system/Runtime'

async function fetchWearablesData() {
	try {
		let userData = getPlayer()
		const realm = await getRealm({})
		if (!userData || !realm.realmInfo) return

		const url =
			`${realm.realmInfo?.baseUrl}/lambdas/collections/wearables-by-owner/${userData.userId}?includeDefinitions`.toString()
		console.log('使用 URL：', url)

		let response = await fetch(url)
		let json = await response.json()

		console.log('完整响应：', json)
	} catch {
		console.log('获取穿戴物数据时发生错误')
	}
}

executeTask(fetchWearablesData)
```

{% hint style="info" %}
**💡 提示**：你还可以从以下 [API 获取关于特定穿戴物的更多信息](https://decentraland.github.io/catalyst-api-specs/#tag/Lambdas/operation/searchWearables).
{% endhint %}

## 检查玩家的摄像机模式

玩家在探索 Decentraland 时可能使用第一人称或第三人称摄像机。通过检查该值来确认玩家正在使用哪一种 `CameraMode` 组件中的旋转值。 `engine.CameraEntity` 实体，从玩家摄像机位置向前追踪一条射线。

```ts
function checkCameraMode() {
	if (!CameraMode.has(engine.CameraEntity)) return

	let cameraEntity = CameraMode.get(engine.CameraEntity)

	if (cameraEntity.mode == CameraType.CT_THIRD_PERSON) {
		console.log('玩家正在使用第三人称摄像机')
	} else {
		console.log('玩家正在使用第一人称摄像机')
	}
}

engine.addSystem(checkCameraMode)
```

{% hint style="warning" %}
**📔 注意**：摄像机信息只对正在运行场景的当前玩家可用。你无法查询其他玩家的摄像机数据。
{% endhint %}

摄像机模式使用来自 `CameraType` 枚举中的值。可能的取值如下：

* `CameraType.CT_FIRST_PERSON`
* `CameraType.CT_THIRD_PERSON`

该 `CameraMode` 组件中的旋转值。 `engine.CameraEntity` 是只读的，你不能通过它强制玩家更改摄像机模式。

{% hint style="info" %}
**💡 提示**：要更改玩家的摄像机模式，请使用一个 [摄像机修正区域](/creator/content-creator-zh/chang-jing-sdk7/3d-nei-rong-ji-chu/camera.md#1st-and-3rd-person-camera-modes).
{% endhint %}

了解摄像机模式对于微调场景机制非常有用，可以更好地适配该模式下更舒适的操作。例如，在第三人称下，小目标更难点击。

{% hint style="warning" %}
**📔 注意**：请避免在 `engine.CameraEntity` 在初始场景加载时，因为如果实体尚未初始化，这可能会导致错误。为避免此问题，请在以下位置内使用这些内容： `main()` 函数中，或在由其间接调用的函数中 `main()`。你也可以将该行为封装在一个异步 [`executeTask` 拦截](/creator/content-creator-zh/chang-jing-sdk7/bian-cheng-mo-shi/async-functions.md#the-executetask-function).

另一种选择是在系统内部引用该实体。它总是可用，因为系统的首次执行是在场景已经正确初始化后才调用的。
{% endhint %}

## 检查玩家是否已锁定光标

玩家可以在两种光标模式之间切换： *锁定光标* 模式，用于控制相机，或 *解锁光标* 模式，用于在 UI 上自由移动光标。

玩家可通过单击 *鼠标右键* 或按下 *Esc* 键来解锁光标，并通过单击屏幕任意位置重新锁定光标。

查看 `PointerLock` 场景的 [摄像机实体](/creator/content-creator-zh/chang-jing-sdk7/jia-gou/entities-components.md#reserved-entities) 来查看当前的光标模式是什么。

```ts
export function main() {
	const isLocked = PointerLock.get(engine.CameraEntity).isPointerLocked
	console.log(isLocked)
}
```

参见 [事件监听器](/creator/content-creator-zh/chang-jing-sdk7/jiao-hu-xing/event-listeners.md#player-locks-or-unlocks-cursor) 了解如何轻松响应光标状态变化。

你也可以通过写入 `isPointerLocked` 字段设为 `PointerLock` 组件上的 `engine.CameraEntity`。见 [锁定或解锁光标](/creator/content-creator-zh/chang-jing-sdk7/jiao-hu-xing/an-niu-shi-jian/click-events.md#lock-or-unlock-the-cursor) 以强制更改玩家的光标状态，示例见

{% hint style="warning" %}
**📔 注意**：请避免在 `engine.CameraEntity` 在初始场景加载时，因为如果实体尚未初始化，这可能会导致错误。为避免此问题，请在以下位置内使用这些内容： `main()` 函数中，或在由其间接调用的函数中 `main()`。你也可以将该行为封装在一个异步 [`executeTask` 拦截](/creator/content-creator-zh/chang-jing-sdk7/bian-cheng-mo-shi/async-functions.md#the-executetask-function).

另一种选择是在系统内部引用该实体。它总是可用，因为系统的首次执行是在场景已经正确初始化后才调用的。
{% endhint %}

## 检查玩家的光标位置

使用 `PrimaryPointerInfo` 组件在 `engine.RootEntity` 用于获取玩家的光标位置。这可用于拖放交互、滑动手势等机制。

```ts
import { PrimaryPointerInfo } from '@dcl/sdk/ecs'

function CursorSystem() {
	const pointerInfo = PrimaryPointerInfo.get(engine.RootEntity)
	console.log(pointerInfo)
}

engine.addSystem(CursorSystem)
```

{% hint style="warning" %}
**📔 注意**：请避免在 `engine.RootEntity` 初始场景加载时引用
{% endhint %}

该 `PrimaryPointerInfo` 组件返回一个包含以下属性的对象：

* `screenCoordinates`: *(Vector2)* 光标在场景中的位置，以像素表示。原点位于屏幕左下角。当光标被锁定时，此值表示屏幕中心。
* `screenDelta`: *(Vector2)* 光标自上一帧以来位置的变化，以像素表示。参见 [鼠标移动](/creator/content-creator-zh/chang-jing-sdk7/jiao-hu-xing/mouse-movement.md) 了解详细信息和示例。
* `worldRayDirection`: *(Vector3)* 一个向量，表示从摄像机到光标的射线方向。原点是摄像机位置。可用它来计算光标在世界中的位置。
* `pointerType`：0 表示 `无`，1 表示 `鼠标`

{% hint style="info" %}
**💡 提示**：与其他属性不同， `screenDelta` 即使光标处于 [锁定](/creator/content-creator-zh/chang-jing-sdk7/jiao-hu-xing/an-niu-shi-jian/click-events.md#lock-or-unlock-the-cursor)状态，它仍会继续报告鼠标移动。这使它非常适合拖拽手势和自定义摄像机控制等实时交互，参见 [鼠标移动](/creator/content-creator-zh/chang-jing-sdk7/jiao-hu-xing/mouse-movement.md).
{% endhint %}

{% hint style="info" %}
**提示：** 要响应 UI 元素上的简单悬停事件，你可能会发现使用 `onMouseEnter` 和 `onMouseLeave` 事件更容易，参见 [UI 按钮事件](/creator/content-creator-zh/chang-jing-sdk7/2d-ui/ui_button_events.md#hover-feedback).
{% endhint %}

该 `PrimaryPointerInfo` 组件是只读的，你不能强制玩家更改光标位置。

以下示例展示了如何在 UI 元素上显示光标位置。

***ui.tsx 文件：***

```tsx
import { UiEntity, ReactEcs } from '@dcl/sdk/react-ecs'
import { Color4 } from '@dcl/sdk/math'
import {cursorXpos, cursorYpos} from './index'

export const uiMenu = () => (
  <UiEntity
    uiTransform={{
			width: '100%',
			height: '100px',
			justifyContent: 'center',
			alignItems: 'center',
    }}
    uiText={{ value: `光标位置：`+  cursorXpos + `,` + cursorYpos, fontSize: 40 }}
    uiBackground={{ color: Color4.create(0.5, 0.8, 0.1, 0.6) }}
  />
)
```

***index.ts 文件：***

```ts
import { engine, PrimaryPointerInfo } from '@dcl/sdk/ecs'
import { ReactEcsRenderer } from '@dcl/sdk/react-ecs'
import { uiMenu } from './ui'

export function main() {
  ReactEcsRenderer.setUiRenderer(uiMenu)
}

export let cursorXpos: number | undefined = undefined
export let cursorYpos: number | undefined = undefined

function CursorSystem() {
  const pointerInfo = PrimaryPointerInfo.get(engine.RootEntity)
  console.log(pointerInfo)

  cursorXpos = pointerInfo.screenCoordinates?.x
  cursorYpos = pointerInfo.screenCoordinates?.y
}

engine.addSystem(CursorSystem)
```

你可以使用 `worldRayDirection` 用于设置 `方向` 字段，以判断实体是否位于光标的视线中。参见 [光线投射](/creator/content-creator-zh/chang-jing-sdk7/jiao-hu-xing/raycasting.md) 了解更多详情。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.decentraland.org/creator/content-creator-zh/chang-jing-sdk7/jiao-hu-xing/user-data.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
