> 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/runtime-data.md).

# 运行时数据

从场景运行所在的上下文以及场景本身获取数据。

## 获取 Decentraland 时间

Decentraland 遵循昼夜循环，完整完成一次需要 2 小时，因此每天共有 12 个完整循环。玩家也可以更改设置以体验某个固定的时刻，例如始终看到晚上 10 点的夜空版 Decentraland。因此，不同玩家看到的 Decentraland 时间可能不同。

使用 `getWorldTime()` 用于获取玩家在 Decentraland 中所处的时刻。

```ts
import { getWorldTime } from '~system/Runtime'

executeTask(async () => {
  let time = await getWorldTime({})
  console.log(time.seconds)
})
```

{% hint style="info" %}
**💡 提示**：该 `getWorldTime()` 函数是异步的。参见 [异步函数](/creator/content-creator-zh/chang-jing-sdk7/bian-cheng-mo-shi/async-functions.md) 如果你不熟悉这些。
{% endhint %}

`getWorldTime()` 会返回一个带有 `seconds` 属性表示自一天开始以来已经过去了多少秒（按 Decentraland 时间计算），假设完整循环持续 24 小时。将 seconds 值除以 60 可得到分钟，再除以 60 可得到自当天开始以来的小时数。例如，如果 `seconds` 值为 *36000*，则对应于 *上午 10 点*.

在 Decentraland 时间中，太阳总是在 6:15 升起，19:50 落下。

你可以利用这些信息相应地调整场景，例如在白天播放鸟叫声、在天黑时播放蟋蟀声，或者在天黑时打开路灯的自发光材质。

```ts
import { getWorldTime } from '~system/Runtime'

executeTask(async () => {
  let time = await getWorldTime({})
  console.log(time.seconds)
  if (time.seconds < 6.25 * 60 * 60 || time.seconds > 19.85 * 60 * 60) {
    // 夜间
    console.log('播放蟋蟀声')
  } else {
    // 白天
    console.log('播放鸟叫声')
  }
})
```

## 获取 Realm 数据

Decentraland 中的玩家分布在多个彼此分离的 *领域*。不同 Realm 中的玩家无法互相看见、互动或聊天，即使他们站在同一地块上也不行。这样划分玩家使 Decentraland 能够处理无限数量的玩家而不会遇到任何限制。它还会将彼此接近区域中的玩家配对，以确保互动玩家之间的 ping 时间可接受。

如果你的场景向一个 [第三方服务器](/creator/content-creator-zh/chang-jing-sdk7/lian-wang/third-party-servers.md) 用于在玩家之间实时同步变化，那么通常很重要的是，这些变化只在同一 Realm 的玩家之间同步。你应将属于某个 Realm 的所有变化与属于其他 Realm 的变化分开处理。否则，玩家会看到事物以一种诡异的方式变化，而没人实际做出这些更改。

```ts
import { getRealm } from '~system/Runtime'

executeTask(async () => {
  const { realmInfo } = await getRealm({})
  if (!realmInfo) return
  console.log(`你所在的 realm: `, realmInfo.realmName)
})
```

{% hint style="info" %}
**💡 提示**：该 `getRealm()` 函数是异步的。参见 [异步函数](/creator/content-creator-zh/chang-jing-sdk7/bian-cheng-mo-shi/async-functions.md) 如果你不熟悉这些。
{% endhint %}

Decentraland 通过一个去中心化的通信服务器网络来处理玩家之间的通信（包括玩家位置、聊天、messageBus 消息以及智能物品状态更改），其中每一台服务器称为一个 **Realm**。这些服务器中的每一台都可以支持多个独立的 **房间** （也称为 **岛屿**），每个房间会将 Decentraland 地图上彼此接近的一组不同玩家分在一起。

该 `getRealm()` 函数返回以下信息：

* `baseUrl`: *（字符串）* realm 服务器的域名
* `realmName`: *（字符串）* realm 服务器的名称
* `networkId`: *（数字）* 以太坊网络
* `commsAdapter`: *（字符串）* 通信适配器，会移除所有查询参数（凭证）
* `isPreview`: *（布尔值）* 如果场景作为本地预览运行，而不是发布在 Decentraland 中，则为 True。
* `isConnectedSceneRoom`: *（布尔值）* 如果用户已连接到场景房间，则为 True。

{% hint style="warning" %}
**📔 注意**：该 `layer` 该属性已弃用，应避免使用。
{% endhint %}

随着玩家在地图中移动，他们可能会切换房间，以便与现在离他们最近的玩家分到一起。房间边界也会动态调整，以容纳一个可管理的人群，因此即使玩家站着不动，随着其他玩家进入和离开世界，该玩家也可能发现自己被分到了另一个房间。同一个 `room` 会进行通信，并且即使彼此远到看不见，也会通过 MessageBus 共享消息。同一服务器但处于不同房间的玩家目前不会通信，但随着他们在地图中移动并更换房间，他们可能会建立通信。

要响应与玩家的 realm 或房间相关的变化，请使用 `onChange` 在……上的函数 `RealmInfo` 组件，运行时会将其添加到 `engine.RootEntity`。该组件包含与 `getRealm()`.

```ts
import { engine, RealmInfo } from '@dcl/sdk/ecs'

export function main() {
	RealmInfo.onChange(engine.RootEntity, (realmInfo) => {
		if (!realmInfo) return
		console.log('Realm 已更改：', realmInfo.realmName)
	})
}
```

{% hint style="warning" %}
**📔 注意**：当场景首次加载时，可能还没有为玩家分配房间。Explorer 最终会为玩家分配一个房间，但这有时会在场景加载后几秒钟才发生。
{% endhint %}

## 获取玩家平台

玩家可以通过各种平台访问 Decentraland，包括官方桌面应用、已弃用的网页和桌面版本，以及 [其他实验性客户端](https://github.com/decentraland/protocol-squad) ，以及为其他引擎构建的客户端。

使用 `getExplorerInformation()` 以了解当前玩家正在通过哪个平台运行 Decentraland。

```ts
import { getExplorerInformation } from '~system/Runtime';

executeTask(async () => {
  let data = await getExplorerInformation({})
  console.log("平台: ", data.platform, " 代理: ", data.agent)
})
```

使用官方 Decentraland 桌面应用时，此函数应返回以下数据：

```
{
    agent: unity-explorer,
    platform: desktop
}
```

使用官方 Decentraland 桌面应用的玩家通常会比浏览器中的玩家体验更流畅得多，因为浏览器会限制浏览器标签页可使用的机器处理能力。它们还会缺少许多功能，例如摄像机控制、动态光照、冻结玩家移动、UI 增强等。

## EngineInfo 组件

该 `EngineInfo`组件会跟踪有关场景生命周期的数据，这有时可用于判断某个事件相对于场景初始化是在何时发生的。

该组件会被添加到 `engine.RootEntity`.

```ts
engine.addSystem((deltaTime) => {
  const engineInfo = EngineInfo.getOrNull(engine.RootEntity)
  if (!engineInfo) return

  console.log(
    '--------------' +
      '\nframeNumber: ' +
      engineInfo.frameNumber +
      '\ntickNumber: ' +
      engineInfo.tickNumber +
      '\ntotalRuntime: ' +
      engineInfo.totalRuntime +
      '\nsceneHidden: ' +
      engineInfo.sceneHidden +
      '\n--------------'
  )
})
```

你可以使用 `sceneHidden` 用于在场景不可见时暂停资源密集型工作：

```ts
engine.addSystem((deltaTime) => {
  const engineInfo = EngineInfo.getOrNull(engine.RootEntity)
  if (engineInfo?.sceneHidden) return

  // 正常的游戏逻辑仅在场景可见时运行
})
```

该 `EngineInfo` 组件包含以下数据：

* `frameNumber`：引擎的帧计数器。
* `totalRuntime`：该场景的总运行时间，单位为秒。
* `tickNumber`：场景的 tick 计数器，依据 [ADR-148](https://adr.decentraland.org/adr/ADR-148).
* `sceneHidden`: `true` 当场景被 Explorer 的全屏 UI 遮挡时。包括加载界面，以及地图、背包和设置菜单。可用它在玩家看不到场景时静音音频并暂停高负载工作。

{% hint style="warning" %}
**📔 注意**：该 `EngineInfo` 组件必须通过以下方式导入：

> `import { EngineInfo } from "@dcl/sdk/ecs"`

参见 [导入](/creator/content-creator-zh/chang-jing-sdk7/ru-men/coding-scenes.md#imports) ，了解如何轻松处理这些内容。
{% endhint %}

### 响应加载界面淡出

该 `scene_hidden` 字段会告诉你玩家是否真的能看到你的场景，或者它是否被 Explorer 的全屏 UI 覆盖。在加载界面显示期间， `sceneHidden` 为 `true`。当加载界面淡出、玩家首次看到世界的那一刻，它会变为 `false`.

它会变为 `true` ，之后当全屏 Explorer UI 再次遮挡场景时也会如此，例如地图、背包或设置菜单。这使它成为静音的好时机 [音频](/creator/content-creator-zh/chang-jing-sdk7/3d-nei-rong-ji-chu/sounds.md) 并暂停耗资源的系统，然后在它恢复为 `false`.

这是场景得知首次露出发生的唯一方式。可用它来延后任何原本会在加载界面后方播放、从而被玩家错过的内容：开场过场动画、欢迎音效、只有被观看时才看得懂的 tween、开场 UI，或只应在玩家真正进入后才计数的分析事件。

```ts
import { engine, EngineInfo } from '@dcl/sdk/ecs'

function onSceneRevealed() {
  // 玩家现在正在看场景，在这里开始开场
  console.log('加载界面刚刚淡出')
}

engine.addSystem(function waitForSceneRevealed() {
  const engineInfo = EngineInfo.getOrNull(engine.RootEntity)
  if (!engineInfo || engineInfo.sceneHidden) return

  // 仅运行一次
  engine.removeSystem(waitForSceneRevealed)
  onSceneRevealed()
})
```

{% hint style="warning" %}
**📔 注意**：你的场景在 `sceneHidden` 为 `true`期间会继续正常运行，

`scene_hidden` 需要最新的 `@dcl/sdk` 以及较新版本的 Decentraland Explorer。对于旧客户端，该字段会保持其默认值 `false`，因此等待它的场景仍会运行——只是不会与加载界面的淡出同步。
{% endhint %}


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
