> 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-pt/scenes-sdk7/ui-2d/onscreen-ui.md).

# UI na Tela

Aprenda como criar uma UI para players na sua scene. Isso é útil, por exemplo, para exibir informações relacionadas ao jogo.

Você pode criar uma UI para a sua scene, para ser exibida no espaço 2D fixo da tela, em vez do espaço 3D do mundo.

Os elementos de UI só ficam visíveis quando o player está dentro dos parcels de LAND da scene, já que scenes vizinhas podem ter sua própria UI para exibir. Partes da UI também podem ser acionadas para abrir quando certos eventos ocorrem no world-space, por exemplo, se o player clicar em um lugar específico.

Crie uma UI definindo uma estrutura de `UiEntity` aninhadas em JSX. A sintaxe usada para UIs é muito parecida com a do [React](https://reactjs.org/) (uma biblioteca baseada em JavaScript muito popular para criar UIs web).

{% hint style="warning" %}
**📔 Nota**: Você só pode definir a sintaxe de UI em arquivos que tenham uma `.tsx` extensão. `.tsx` arquivos suportam tudo o que os arquivos `.ts` suportam, além da sintaxe de UI. Recomendamos criar um `ui.tsx` arquivo e definir sua UI ali. Lembre-se de chamar seu método de renderização da UI a partir de `index.ts` com `ReactEcsRenderer.setUiRenderer(yourUiMethodName)`, veja o exemplo abaixo.
{% endhint %}

Uma UI simples com elementos estáticos pode parecer muito com HTML, mas quando você adiciona elementos dinâmicos que respondem a uma mudança de estado, você pode fazer coisas muito mais poderosas.

A UI padrão do Explorer do Decentraland inclui um widget de chat, um mapa e outros elementos. Esses elementos de UI são sempre exibidos na camada superior, acima de qualquer UI específica da scene. Então, se a sua scene tiver elementos de UI que ocupem o mesmo espaço de tela que esses, eles serão ocultados.

Veja [diretrizes de UX](/creator/content-creator-pt/scenes-sdk7/desenhando-a-experiencia/ux-ui-guide.md) para dicas sobre como projetar a aparência e a sensação da sua UI.

{% hint style="info" %}
**📱 Projetando para mobile**: Os dispositivos reservam espaço na tela para o notch, a barra de status, o indicador inicial e os cantos arredondados, e o client desenha seus próprios controles sobre parte do canvas. Você não mede nenhum dos dois — escolha a área em que sua UI será colocada com [`screenInset`](#screen-inset-area) abaixo. Ele usa como padrão a área segura do dispositivo, então as margens de hardware são evitadas sem nenhum trabalho do seu lado. Antes de publicar, revise a [Área segura para mobile](/creator/content-creator-pt/criar-para-dispositivos-moveis/desenvolver/safe-area.md) e as [melhores práticas de UI para mobile](/creator/content-creator-pt/criar-para-dispositivos-moveis/desenvolver/ui-best-practices.md).
{% endhint %}

Quando o player clica no botão *fechar UI* , no canto inferior direito da tela, todos os elementos de UI são ocultados.

## Renderizar uma UI

Para exibir uma UI na sua scene, use a `ReactEcsRenderer.setUiRenderer()` função, passando a ela uma estrutura válida de entities, descrita em um `.tsx` arquivo.

Cada entity é definida como um nó semelhante a HTML, com propriedades para cada um de seus componentes.

***arquivo ui.tsx:***

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

export const uiMenu = () => (
  <UiEntity
    uiTransform={{
      width: 700,
      height: 400,
      margin: { top: '35px', left: '500px' },
    }}
    uiBackground={{ color: Color4.Red() }}
  />
)
```

***arquivo index.ts:***

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

export function main() {
    ReactEcsRenderer.setUiRenderer(uiMenu, { virtualWidth: 1920, virtualHeight: 1080 })
}
```

Você também pode definir uma estrutura de entity e renderizá-la, tudo em um único comando em um `.tsx` arquivo.

***arquivo ui.tsx:***

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

export function setupUI() {
  ReactEcsRenderer.setUiRenderer(() => (
    <UiEntity
      uiTransform={{
        width: 700,
        height: 400,
        margin: { top: '35px', left: '500px' },
      }}
      uiBackground={{ color: Color4.Red() }}
    />
  ), { virtualWidth: 1920, virtualHeight: 1080 })
}
```

***arquivo index.ts:***

```ts
import { setupUI } from './ui'

export function main() {
    setupUI()
}
```

{% hint style="warning" %}
**📔 Nota**: Todos os seus elementos de UI precisam estar aninhados na mesma estrutura e ter um único pai na raiz da estrutura. Você só pode chamar `ReactEcsRenderer.setUiRenderer()` uma vez na scene.
{% endhint %}

## Entities de UI

Cada elemento na UI precisa ser definido como uma `UiEntity`, seja uma imagem, texto, background, uma caixa de alinhamento invisível, etc. Assim como no espaço 3D da scene, cada `UiEntity` tem seus próprios componentes para lhe dar posição, cor etc.

A sintaxe semelhante à do React permite que você especifique cada componente como uma propriedade dentro da `UiEntity`, isso torna o código mais curto e mais legível.

Os componentes usados em uma `UiEntity` são diferentes daqueles usados em entities regulares. Você não pode aplicar um componente de UI a uma entity regular, nem um componente regular a uma UI entity.

Os seguintes componentes estão disponíveis para uso em uma `UiEntity`:

* `uiTransform`
* `uiBackground`
* `uiText`
* `onMouseDown`
* `onMouseUp`
* `onMouseEnter`
* `onMouseLeave`
* [`uiInputBinding`](/creator/content-creator-pt/scenes-sdk7/ui-2d/ui_input_binding.md) — mantenha as ações de input enquanto o elemento estiver pressionado, para criar controles personalizados

Assim como com tags HTML, você pode definir componentes como autoencerrados ou aninhar um dentro do outro.

{% hint style="danger" %}
**Aviso:** Mantenha os wrappers de layout em tela cheia livres de handlers de pointer. Adicionar qualquer um dos `onMouse` handlers, ou `pointerFilter: 'block'`, a um `UiEntity` dimensionado `100%` por `100%` faz com que ele capture cada clique na tela, deixando toda a sua outra UI e todo o mundo 3D inacessíveis ao clique. Coloque os handlers no panel ou button que precisa deles. Veja [Bloqueio de pointer](/creator/content-creator-pt/scenes-sdk7/ui-2d/ui_button_events.md#pointer-blocking).
{% endhint %}

***arquivo ui.tsx:***

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

export const uiMenu = () => (
  // entity pai
  <UiEntity
    uiTransform={{
      width: 200,
      height: 200,
      margin: { top: '250px', left: '500px' },
    }}
    uiBackground={{ color: Color4.Blue() }}
  >
    {/* entity filha autoencerrada */}
    <UiEntity
      uiTransform={{
        width: 400,
        height: 400,
        margin: { top: '35px', left: '500px' },
      }}
      uiText={{ value: `Hello world!`, fontSize: 40 }}
    />
    {/* instrução de fechamento para a entity pai */}
  </UiEntity>
)
```

***arquivo index.ts:***

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

export function main() {
    ReactEcsRenderer.setUiRenderer(uiMenu, { virtualWidth: 1920, virtualHeight: 1080 })
}
```

Uma definição de um módulo de UI só pode ter uma entity no nível pai. Você pode definir quantas outras entities quiser, mas elas todas precisam caber dentro de uma estrutura com um único pai no topo.

## Escala virtual da tela

Defina uma largura e uma altura virtuais para a UI. Isso garante que sua UI tenha a mesma aparência em diferentes tamanhos de tela, independentemente do tamanho real da tela em pixels.

```ts
export function setupUi() {
    ReactEcsRenderer.setUiRenderer(uiComponent, { virtualWidth: 1920, virtualHeight: 1080 })
}
```

Se você definir uma largura virtual de 1920 e uma altura virtual de 1080, a UI será escalada para caber no tamanho da tela. Se a tela for 1920x1080, a UI será exibida no mesmo tamanho que o tamanho virtual. Se a tela for maior ou menor, quaisquer valores em pixels serão escalados para caber no tamanho virtual. Por exemplo, se a tela for 3840x2160, um item definido como 100 pixels de largura será exibido em 200 pixels reais.

O cálculo real do Ui Scale Factor que é multiplicado nos valores em pixels é [`Math.min(realWidth / virtualWidth, realHeight / virtualHeight)`](https://github.com/decentraland/js-sdk-toolchain/blob/main/packages/%40dcl/react-ecs/src/system.ts).

### Tamanho virtual padrão

O tamanho virtual é opcional, mas suas duas dimensões vêm juntas: passe as duas ou nenhuma. Quando você não passa uma, um padrão da plataforma é aplicado:

| Plataforma    | Tamanho virtual padrão |
| ------------- | ---------------------- |
| Mobile        | `1600x720`             |
| Desktop e Web | `1920x1080`            |

Isso significa que os valores em pixels na sua UI são sempre escalados em relação a uma resolução de referência, mesmo quando você não passa nenhuma opção. Isso também se aplica quando a scene usa apenas `addUiRenderer()` e nunca chama `setUiRenderer()`.

Três casos especiais:

* **Optar por não escalar**: passe um tamanho inválido — qualquer valor que seja `0` ou menor — para desativar a tela virtual por completo. Os valores em pixels passam a ser usados como pixels crus do canvas, sem nenhuma escala. Esta é a forma documentada de desativar a tela virtual, então nada é registrado.

  ```ts
  ReactEcsRenderer.setUiRenderer(uiComponent, { virtualWidth: 0, virtualHeight: 0 })
  ```
* **Tamanhos incompletos**: informar apenas uma das duas dimensões também é inválido, então isso desativa a tela virtual exatamente como no caso acima — o padrão da plataforma não **não** intervém. Ao contrário da opção de desativação acima, este caso é reportado: um tamanho informado pela metade é um erro, e não uma escolha deliberada, então o SDK registra `Tamanho de tela virtual incompleto (…): ambas as dimensões são necessárias, então a tela virtual é desativada e nenhuma escala de UI é aplicada.` uma vez por tamanho. Passe as duas dimensões ou nenhuma.

  ```ts
  // Não faça isso — nenhuma escala é aplicada
  ReactEcsRenderer.setUiRenderer(uiComponent, { virtualWidth: 1920 })
  ```

  Vale a pena verificar isso duas vezes no renderer principal, porque um tamanho incompleto ali também é um switch válido para toda a scene: uma `setUiRenderer()` chamada que menciona *qualquer uma* dimensão vence sobre qualquer `addUiRenderer()`chamada, então o exemplo acima desativa a tela virtual para a scene inteira e descarta um tamanho válido passado a um renderer adicional.
* **Tamanhos 16:9 no mobile**: as telas de telefone são muito mais largas do que 16:9, então um canvas virtual 16:9 colocaria barras na UI. Se você passar um tamanho 16:9 (`1920x1080`, `1280x720`, …) e a scene estiver rodando no mobile, ele será substituído por `1600x720`1600x720

{% hint style="info" %}
**📔 Nota**: Os `vw` e `vh` unidades são independentes da tela virtual: `1vw` é 1% da largura do canvas e `1vh` é 1% da altura do canvas, exatamente como em CSS. Elas também ignoram o [`screenInset`](#screen-inset-area), então dentro do inset padrão `'device'` um `width: '100vw'` é mais largo do que um `width: '100%'` — o primeiro ocupa a tela inteira, o segundo preenche a área com inset.
{% endhint %}

{% hint style="info" %}
**📱 Nota**: A detecção da plataforma é resolvida de forma assíncrona. Durante os primeiros frames o SDK ainda não sabe que está rodando no mobile, então a tela virtual começa em `1920x1080` 1920x1080 `1600x720` 1600x720
{% endhint %}

{% hint style="warning" %}
**📔 O que mudou para scenes escritas antes desta versão do SDK**

Três mudanças afetam as scenes existentes. Nenhuma delas é opcional, então uma scene que não for tocada de forma alguma ainda parecerá diferente assim que atualizar a versão do seu SDK:

1. **Uma tela virtual agora se aplica por padrão.** Uma scene que não passava opções costumava dispor os valores em pixels como pixels crus do canvas. Agora ela é escalada em relação a `1920x1080` (`1600x720` no mobile). Para recuperar o comportamento anterior, desative explicitamente a tela virtual com `setUiRenderer(ui, { virtualWidth: 0, virtualHeight: 0 })`.
2. **`screenInset` usa como padrão `'device'`.** Sua UI agora é posicionada dentro da área segura do dispositivo, então no mobile ela se move para dentro, e um `100%` de nível raiz não ocupa mais a tela inteira — fundos em tela cheia, dimmers e overlays param antes do notch e do indicador inicial. Para recuperar o comportamento anterior, passe `setUiRenderer(ui, { screenInset: 'none' })`. Veja [Área de inset da tela](#screen-inset-area).
3. **`devicePixelRatio` não participa do layout da UI.** A UI dimensionada em pixels agora fica até 2–3 vezes maior em telas de alta densidade (retina e mobile) do que antes. **Não há como desativar isso** — verifique novamente quaisquer tamanhos que foram ajustados manualmente e remova qualquer fator de escala que sua scene tenha calculado por conta própria.
   {% endhint %}

## Área de inset da tela

As telas não são totalmente utilizáveis: um telefone reserva espaço para o notch, a barra de status, o indicador inicial e os cantos arredondados, e todo Explorer desenha seu próprio HUD (minimapa, chat, …) sobre parte do canvas. A `screenInset` propriedade opcional das opções do renderer seleciona em qual área da tela sua UI é posicionada:

| Valor                 | Área em que a UI é colocada                                                                                                                                                                                                           |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `'device'` *(padrão)* | A área segura do dispositivo, excluindo o notch, a barra de status e os cantos arredondados. Lida de `UiCanvasInformation.screenInsetArea`.                                                                                           |
| `'interactable'`      | A área que o Explorer reporta como livre do seu próprio HUD (minimapa, chat, …). Lida de `UiCanvasInformation.interactableArea`. O que ela cobre fica a cargo de cada Explorer — verifique nas plataformas que você pretende atingir. |
| `'none'`              | Toda a tela, com `0,0` no canto superior esquerdo.                                                                                                                                                                                    |

```ts
// A UI é mantida afastada do notch, da barra de status e dos cantos arredondados — este é o padrão
ReactEcsRenderer.setUiRenderer(uiComponent, { virtualWidth: 1920, virtualHeight: 1080 })

// A UI é mantida afastada do próprio HUD do Explorer
ReactEcsRenderer.setUiRenderer(uiComponent, { screenInset: 'interactable' })

// A UI cobre a tela inteira, você cuida das margens sozinho
ReactEcsRenderer.setUiRenderer(uiComponent, { screenInset: 'none' })
```

No desktop, os insets do dispositivo são zero, então `'device'` coloca a UI sobre a tela inteira ali — o mesmo resultado de `'none'`. A área é relida a cada tick, então a UI acompanha os insets quando eles mudam, por exemplo na rotação ou quando as barras do sistema aparecem e desaparecem.

{% hint style="warning" %}
**📔 `'interactable'` não é um efeito nulo no desktop.** Ao contrário dos insets do dispositivo, a área interativa é *não* zero no client desktop: ele reserva aproximadamente os 25% esquerdos da tela para sua própria UI, então `screenInset: 'interactable'` coloca sua UI nos 75% restantes ali. Esse é o objetivo da opção, mas isso também significa que ela altera seu layout no desktop — faça branch com [`isMobile()`](/creator/content-creator-pt/criar-para-dispositivos-moveis/desenvolver/detect-platform.md) se você quiser isso apenas em celulares.

**Suporte do client**: `'interactable'` precisa de um Explorer que reporte a área. Ele é suportado no desktop e, no mobile, a partir da versão do client `1.12.1` em diante — em clients mobile mais antigos, o valor é reportado como zero, e a UI volta a cobrir a tela inteira. A mesma `1.12.1` versão também normaliza a `'device'` área entre Android e iOS, então trate-a como a base para qualquer layout que dependa de qualquer um dos dois insets. `'none'` comporta-se da mesma forma em todos os lugares.
{% endhint %}

{% hint style="warning" %}
**📔 Nota**: Não envolva sua UI nos [`ScreenInsetArea` ou `InteractableArea`](/creator/content-creator-pt/criar-para-dispositivos-moveis/desenvolver/safe-area.md#wrap-part-of-your-ui-instead) componentes ao mesmo tempo em que deixa o correspondente `screenInset` valor no renderer — o inset seria aplicado duas vezes, empurrando a UI para dentro com o dobro da margem. Ou você depende de `screenInset`, ou defina-o como `'none'` e coloque o wrapper você mesmo.
{% endhint %}

### As três áreas em um dispositivo real

As capturas abaixo são da mesma scene no mesmo telefone, renderizada três vezes com apenas o `screenInset` valor alterado. O retângulo magenta é a própria UI; os contornos são as áreas que o Explorer reporta — ciano é o canvas completo, âmbar é `screenInsetArea`, verde é `interactableArea`.

<figure><img src="https://2402076176-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-78aa0fa3423a3ed51b5889f0150484a354b2dd30%2Fscreeninset-none.png?alt=media" alt="Scene UI covering the whole phone screen, including the notch strip and the areas under the client controls"><figcaption><p><code>screenInset: 'none'</code> — a UI cobre todo o canvas. Seus cantos ficam sob o notch e atrás dos próprios controles do client.</p></figcaption></figure>

<figure><img src="https://2402076176-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-94c4b28274282d30cda22c389b375fa30c78dc64%2Fscreeninset-device.png?alt=media" alt="Scene UI inset to the device safe area, clear of the notch"><figcaption><p><code>screenInset: 'device'</code> (o padrão) — a UI é puxada para a área segura do dispositivo, afastando-se do notch e dos cantos arredondados. Ela ainda se sobrepõe aos controles do client, que não fazem parte dessa área.</p></figcaption></figure>

<figure><img src="https://2402076176-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 client reports as free of its own HUD"><figcaption><p><code>screenInset: 'interactable'</code> — a UI é colocada dentro do retângulo que o client designa para a UI da scene. No client mobile <code>1.12.1</code>, capturado aqui, isso exclui a coluna da esquerda (perfil, chat, joystick); os botões de ação no canto inferior direito são desenhados sobre a área de propósito.</p></figcaption></figure>

{% hint style="info" %}
**💡 Dica**: `'interactable'` lhe dá a área que cada Explorer designa para a UI da scene. Isso deliberadamente não é o mesmo que "todo controle do client fica fora dela" — como a terceira captura mostra, os botões de ação no mobile são desenhados sobre a área de propósito. Tudo o que você colocar sob eles ainda estará acessível, mas competirá pelos mesmos toques, então mantenha os [cantos apertados](/creator/content-creator-pt/criar-para-dispositivos-moveis/desenvolver/safe-area.md#where-the-client-controls-live) em mente e verifique as plataformas que você pretende atingir: o que a área cobre fica a cargo de cada Explorer e pode mudar entre versões.
{% endhint %}

Cada renderer respeita o seu próprio `screenInset`, então a UI principal e qualquer UI adicionada com `addUiRenderer()` podem usar áreas diferentes ao mesmo tempo. Ao contrário do tamanho virtual, esse valor nunca é compartilhado entre renderers.

## Múltiplos módulos de UI

Se sua scene contiver vários systems ou modules que cada um define sua própria UI, você pode renderizar cada módulo de UI com `ReactEcsRenderer.addUiRenderer()`. Isso é especialmente útil ao trabalhar em uma scene complexa com vários componentes de UI, ou ao definir UIs para um [smart item](https://github.com/decentraland/docs/tree/main/creator/sdk7/smart-items/smart-items.md), que deve ser utilizável independentemente do que estiver no código do restante da scene.

A `ReactEcsRenderer.addUiRenderer()` função exige que você forneça uma entity como proprietária da UI. Isso pode ser qualquer entity, até mesmo uma dummy entity criada apenas para ser usada como proprietária da UI.

```ts
export function setupUi() {

    // Crie uma dummy entity para ser a proprietária da UI
    const dummyEntity = engine.addEntity()

    // Defina o módulo de UI como uma função que retorna um array de módulos de UI
    const uiComponent = () => [
      // Função que retorna um módulo de UI,
      // Função que retorna um módulo de UI
      // ...
    ]

    // Renderize o módulo de UI com a dummy entity como proprietária
    ReactEcsRenderer.addUiRenderer(dummyEntity, uiComponent)
}
```

Este trecho pode existir independentemente de qualquer outro código de UI na scene. O restante da scene pode incluir uma `ReactEcsRenderer.setUiRenderer()`UI principal, ou nenhuma, e a UI ainda será renderizada.

Uma `addUiRenderer()` chamada também pode incluir uma largura e uma altura virtuais, assim como `setUiRenderer()`setUiRenderer(). `setUiRenderer()` chamada que também define uma largura e uma altura virtuais, a largura e a altura virtuais da `addUiRenderer()` chamada

```tsx
ReactEcsRenderer.addUiRenderer(dummyEntity, uiComponent, { virtualWidth: 1920, virtualHeight: 1080 })
```

O tamanho virtual é um único valor válido para toda a scene, resolvido da seguinte forma: o tamanho em `setUiRenderer()` vence; caso contrário, a primeira `addUiRenderer()` chamada que forneceu um vence; e, se nenhum renderer forneceu um, o [padrão da plataforma](#default-virtual-size) se aplica. As opções que carregam apenas um `screenInset` não contam como um tamanho fornecido.

A [`screenInset`](#screen-inset-area) funciona ao contrário — é por renderer, então cada módulo de UI pode ficar em uma área diferente da tela:

```tsx
// Este widget fica afastado do HUD do Explorer, independentemente do que a UI principal use
ReactEcsRenderer.addUiRenderer(dummyEntity, uiComponent, { screenInset: 'interactable' })
```

Essa UI pode ser removida com `ReactEcsRenderer.removeUiRenderer(dummyEntity)` , além disso, se a entity que possui a UI for destruída, a UI também será removida. Se `ReactEcsRenderer.addUiRenderer()` for chamada novamente para a mesma entity, mas com um UiRenderer diferente, o anterior é limpo e o novo o substitui, mantendo seu lugar na ordem de empilhamento. Chamar novamente também é como você altera as opções de um módulo de UI que já foi renderizado, por exemplo seu `zIndex`.

### Ordem de empilhamento entre módulos de UI

Por padrão, os módulos de UI se empilham na ordem em que aparecem pela primeira vez, com os posteriores na frente. Módulos que aparecem pela primeira vez no mesmo frame — normalmente tudo o que é registrado antes do primeiro frame da scene — são desenhados com a UI principal de `setUiRenderer()` atrás, seguida pelos outros módulos na ordem em que foram adicionados. Para controlar isso explicitamente, passe um `zIndex` nas opções do renderer: módulos com um `zIndex` maior renderizam na frente daqueles com um menor, independentemente da ordem em que apareceram. Módulos deixados em `0` mantêm a ordem padrão. A opção funciona da mesma forma no `setUiRenderer()`, então a UI principal também pode ser colocada na frente dos outros módulos.

```tsx
// Registrado primeiro, mas sempre na frente dos outros módulos de UI
ReactEcsRenderer.addUiRenderer(dummyEntity, uiComponent, { zIndex: 10 })

// A UI principal fica atrás de todo módulo que não defina um valor menor
ReactEcsRenderer.setUiRenderer(mainUi, { zIndex: -10 })
```

Este é um ajuste diferente do `zIndex` de um `UiEntity`, que ordena apenas [irmãos dentro de um módulo de UI](/creator/content-creator-pt/scenes-sdk7/ui-2d/ui-positioning.md#z-index). A opção do renderer ordena módulos inteiros entre si, e os elementos dentro de cada módulo mantêm seu próprio `zIndex`.

### Partilhando uma única instrução setUiRenderer

Em vez de chamar `ReactEcsRenderer.addUiRenderer()` para cada módulo de UI, você pode chamar `ReactEcsRenderer.setUiRenderer()` uma vez com uma matriz de módulos de UI, que podem estar em ficheiros diferentes.

```ts
const uiComponent = () => [
  // Função que retorna um módulo de UI,
  // Função que retorna um módulo de UI
  // ...
]

ReactEcsRenderer.setUiRenderer(uiComponent, { virtualWidth: 1920, virtualHeight: 1080 })
```

Abaixo está um exemplo mais completo:

***arquivo ui.tsx:***

```ts
export function UIModule1() {
  return (
    <UiEntity
      uiTransform={{
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'space-between',
        positionType: 'absolute',
        position: { right: '3%', bottom: '3%' },
      }}
    >
      <Label value="Olá, Mundo!" fontSize={18} textAlign="middle-center" />
    </UiEntity>
  )
}

export function UIModule2() {
  return (
    <UiEntity
      uiTransform={{
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'space-between',
        positionType: 'absolute',
        position: { right: '3%', top: '3%' },
      }}
    >
      <Label
        value="Aqui está mais UI!"
        fontSize={18}
        textAlign="middle-center"
      />
    </UiEntity>
  )
}
```

***arquivo index.ts:***

```ts
import { ReactEcsRenderer } from '@dcl/sdk/react-ecs'
import { UIModule1, UIModule2 } from './ui'

export function main() {
    ReactEcsRenderer.setUiRenderer(() => [
      UIModule1(),
      UIModule2(),
      // ...
      // A linha abaixo é para usar a biblioteca DCL UI Toolkit
      // https://github.com/decentraland-scenes/dcl-ui-toolkit
      ui.render(),
    , { virtualWidth: 1920, virtualHeight: 1080 })
}
```


---

# 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-pt/scenes-sdk7/ui-2d/onscreen-ui.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.
