> 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/mian-xiang-yi-dong-duan-gou-jian/kai-fa/safe-area.md).

# 移动端安全区域

场景 UI 在移动端可以安全显示的区域——避开设备硬件边距和客户端自身控制。

在手机上，有两件互不相关的东西会占用你的 UI 可以安全使用的屏幕空间：

* **设备的硬件边距** ——刘海或摄像头开孔、状态栏、Home 指示条，以及圆角。绘制在它们下面的 UI 会部分被遮挡，或很难点击。
* **Decentraland 客户端自身的控件** ——摇杆、聊天、个人资料、相机控制、操作按钮。放在它们下方的场景 UI 在视觉上会冲突，并争夺同样的点击。

你不需要测量这两者。客户端会在运行时报告这两个区域，SDK 会把你的 UI 放在你选择的那个区域内，并使用 [`screenInset`](/creator/content-creator-zh/chang-jing-sdk7/2d-ui/onscreen-ui.md#screen-inset-area) 渲染器选项：

| 你想要的效果             | 要传入的值                                |
| ------------------ | ------------------------------------ |
| 避开硬件边距             | 什么都不传 — `screenInset: 'device'` 是默认值 |
| 避开硬件边距 **和** 客户端控件 | `screenInset: 'interactable'`        |
| 整个屏幕，边距由你自己处理      | `screenInset: 'none'`                |

```ts
// 建议用于不能与移动端控件冲突的场景 UI
ReactEcsRenderer.setUiRenderer(uiComponent, { screenInset: 'interactable' })
```

{% hint style="warning" %}
**客户端支持**: `'interactable'` 需要移动客户端 `1.12.1` 或更高版本。在较旧的客户端中，该区域会报告为零，UI 会回退为覆盖整个屏幕。同一版本还统一了 `'device'` Android 和 iOS 之间的该区域。

**它在桌面端并非无操作** ——桌面客户端大约会保留屏幕左侧 25% 给自己的 UI，所以 `'interactable'` 也会改变你的桌面布局。请使用以下分支： [`isMobile()`](/creator/content-creator-zh/mian-xiang-yi-dong-duan-gou-jian/kai-fa/detect-platform.md) 如果你只想在手机上使用该内边距。
{% endhint %}

参见 [屏幕内边距区域](/creator/content-creator-zh/chang-jing-sdk7/2d-ui/onscreen-ui.md#screen-inset-area) 完整参考：在真机上并排显示这三个区域、各渲染器的行为，以及它们如何与 [虚拟屏幕](/creator/content-creator-zh/chang-jing-sdk7/2d-ui/onscreen-ui.md#default-virtual-size).

## 客户端控件所在的位置

`'interactable'` 会给你这个区域 **每个浏览器为场景 UI 指定的** ——这并不意味着保证所有客户端控件都在其外部。在移动客户端中，它是设备安全区域减去左侧栏（聊天、个人资料、摇杆、表情）；右下角的操作按钮会绘制在该区域上方 **这是有意为之**.

<figure><img src="https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-c0c75a80bed756d6b2b1483a7cca0cadef26c77e%2Fscreeninset-interactable.png?alt=media" alt="Scene UI inset to the area the mobile client reports as free of its own HUD"><figcaption><p><code>screenInset: 'interactable'</code> 在移动客户端上 <code>1.12.1</code>。洋红色矩形是场景 UI，绿色轮廓是可交互区域。左侧栏被排除在外；右下角的操作按钮位于该区域之上。</p></figcaption></figure>

所以即使使用 `'interactable'`，也要把这些地方视为拥挤区域：

* **右下角** ——操作按钮和交互按钮会绘制在上层。你放在这里的任何内容仍然可达，但会争抢点击。
* **右上角** ——个人资料和相机控制位于该区域外侧，因此紧贴那个角落的 UI 会被视为客户端 HUD 的一部分。

该区域覆盖哪些内容由各个浏览器自行决定，并且可能在不同版本之间变化。请在运行时读取，切勿硬编码，并在你目标的平台上进行检查。

## 场景 UI 应放在哪里

* **屏幕中央** ——可操作的对话框，以及玩家需要阅读并回应的任何内容。
* **顶部居中** ——不可操作的消息、状态和通知。
* **底部居中，位于交互按钮上方** ——上下文相关提示。
* **不要放在右下角** ——即使在可交互区域内，它也属于操作按钮。

## 改为将你的部分 UI 包起来

如果你通过 `screenInset: 'none'` 并且只想保护部分 UI，请将其包裹在 `ScreenInsetArea` 或者 `InteractableArea` 组件中。每个组件都会读取其对应区域，并将其应用到子元素。请从以下位置导入它们： `@dcl/sdk/react-ecs`:

```tsx
import ReactEcs, { ReactEcsRenderer, UiEntity, ScreenInsetArea } from '@dcl/sdk/react-ecs'
import { Color4 } from '@dcl/sdk/math'

export function setupUi() {
  ReactEcsRenderer.setUiRenderer(() => (
    <ScreenInsetArea>
      {/* 一个尺寸为 100% × 100% 的子元素会正好填满安全内边距区域 */}
      <UiEntity
        uiTransform={{ width: '100%', height: '100%' }}
        uiBackground={{ color: Color4.create(0, 0, 0, 0.5) }}
      />
    </ScreenInsetArea>
  ), { screenInset: 'none' })
}
```

这两个组件都会使用客户端报告的值进行绝对定位，因此 `positionType` 和 `位置` 它们的 `uiTransform` 字段被保留——你为它们设置的任何值都会被忽略。所有其他 `uiTransform` 属性（`padding`, `flexDirection`, `alignItems`，…）以及 UI 组件（`uiBackground`, `onMouseDown`，…）都会像往常一样工作。当区域变化时，例如在旋转或系统栏出现/隐藏时，它们会自动响应，并会补偿 [UI 缩放因子](/creator/content-creator-zh/chang-jing-sdk7/2d-ui/onscreen-ui.md#screen-virtual-scale)，因此无论你的虚拟屏幕尺寸如何，边距都会正确落位。

{% hint style="warning" %}
**📔 不要重复应用内边距：** 该 `screenInset: 'none'` 上面的片段很重要。若在渲染器已经应用了匹配的内边距时，又把你的 UI 包在一个组件里，会使 UI 向内偏移双倍边距。二者择一即可。
{% endhint %}

{% hint style="info" %}
**📱 仅限移动端：** 设备内边距只有在 **移动客户端**。在 **桌面客户端** 它们是 `(0, 0, 0, 0)`，因此 `screenInset: 'device'` 和 `ScreenInsetArea` 这些组件在那里没有效果，你的 UI 会完全按未使用它们时的方式渲染。与设备内边距不同，可交互区域 *为* 在桌面端不是零。
{% endhint %}

## 为什么这很重要

与客户端控件重叠的场景 UI 会：

* 部分被摇杆、交互按钮或相机控制遮住。
* 与这些控件争夺点击——玩家可能会不小心触发其中一个。
* 让你的场景在移动端看起来像坏掉了一样，这会影响推荐和留存。

请始终使用 [预览二维码](/creator/content-creator-zh/mian-xiang-yi-dong-duan-gou-jian/kai-fa/preview-on-mobile.md).

## 相关

* [屏幕内边距区域](/creator/content-creator-zh/chang-jing-sdk7/2d-ui/onscreen-ui.md#screen-inset-area) ——完整的 `screenInset` 参考文档。
* [移动端 UI 最佳实践](/creator/content-creator-zh/mian-xiang-yi-dong-duan-gou-jian/kai-fa/ui-best-practices.md)
* [从代码中检测平台](/creator/content-creator-zh/mian-xiang-yi-dong-duan-gou-jian/kai-fa/detect-platform.md) ——使用 `isMobile()` 来切换布局。
* [屏幕上的 UI](/creator/content-creator-zh/chang-jing-sdk7/2d-ui/onscreen-ui.md)
* [UX 与 UI 指南](/creator/content-creator-zh/chang-jing-sdk7/ti-yan-she-ji/ux-ui-guide.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 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/mian-xiang-yi-dong-duan-gou-jian/kai-fa/safe-area.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.
