> 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/fundamentos-de-conteudo-3d/entity-positioning.md).

# Posicionamento de Entity

Como definir a posição, rotação e escala de uma Entity numa cena

Você pode definir o *position*, *rotation* e *scale* de qualquer entidade usando o `Transform` componente. Isso pode ser usado em qualquer entidade no espaço 3D, afetando onde a entidade é renderizada. Isso inclui formas primitivas (cubo, esfera, plano etc.), formas de texto 3D, formas NFT e modelos 3D (`GltfContainer`).

## Use o Scene Editor no Creator Hub

Ao adicionar um item à sua cena por meio do Scene Editor, ele inclui implicitamente um **Transform** componente Transform. Em seguida, você altera os valores no componente Transform da entidade implicitamente alterando a posição, rotação ou escala de uma entidade. Você também pode usar a UI do Scene Editor para fornecer valores numericamente para maior precisão.

## Essenciais do código

![](https://2402076176-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-417a02dcf0fd40f5032551a0c6996becac7e7166%2Fecs-simple-components-new.png?alt=media\&token=181a73c9-363a-4328-9874-6fed49447dc3)

```ts
// Criar uma nova entidade
const ball = engine.addEntity()

// Dar a esta entidade uma forma, para torná-la visível
MeshRenderer.setSphere(ball)

// Dar a esta entidade um componente Transform
Transform.create(ball, {
	position: Vector3.create(5, 1, 5),
	scale: Vector3.create(1, 1, 1),
	rotation: Quaternion.Identity(),
})
```

Para mover, girar ou redimensionar uma entidade em sua cena ao longo de um período de tempo, altere os valores neste componente incrementalmente, quadro a quadro. Veja [Mover entities](/creator/content-creator-pt/scenes-sdk7/fundamentos-de-conteudo-3d/move-entities.md) para mais detalhes e práticas recomendadas.

{% hint style="warning" %}
**📔 Observação**: `Vector3` e `Quaternion` devem ser importados via

> `import { Vector3, Quaternion } from "@dcl/sdk/math"`

Veja [Imports](/creator/content-creator-pt/scenes-sdk7/primeiros-passos/coding-scenes.md#imports) para saber como lidar com isso facilmente.
{% endhint %}

## Posição

`position` é um *vetor 3D*, ele define a posição do centro da entidade em todos os três eixos, *x*, *y*, e *z*. Veja [Tipos de geometria](/creator/content-creator-pt/scenes-sdk7/fundamentos-de-conteudo-3d/special-types.md) para mais detalhes.

```ts
// Criar uma nova entidade
const ball = engine.addEntity()

// Criar transform com uma posição predefinida
Transform.create(ball, {
	  position: Vector3.create(5, 1, 5)
})

// Obter uma versão mutável do transform
const mutableTransform = Transform.getMutable(ball)

// Definir a posição com um objeto
mutableTransform.position = { x: 5, y: 1, z: 5 }

// Definir a posição com um objeto (sintaxe alternativa)
mutableTransform.position = Vector3.create(2, 1, 4)

// Definir cada eixo individualmente
mutableTransform.position.x = 3
mutableTransform.position.y = 1
mutableTransform.position.z = 3
```

Ao definir uma posição, tenha em mente as seguintes considerações:

* Os números em um vetor de posição representam *metros* (a menos que a entidade seja filha de uma entidade escalada).
* Uma cena composta por um único parcel mede 16 m x 16 m. O centro da cena (ao nível do chão) está em `x:8, y:0, z:8`. Se a cena for composta por vários parcels, então o centro variará dependendo da sua disposição.
* `x:0, y:0, z:0` se refere ao *canto sudoeste* do parcel base da cena, ao nível do chão.

  > Dica: Ao visualizar uma prévia da cena, aparece uma bússola no ponto (0,0,0) da cena com rótulos para cada eixo como referência.

  > Nota: Você pode alterar o parcel base de uma cena editando o `atributo base` de *scene.json*.
* Para se orientar melhor, use sua *left* mão:
  * seu dedo indicador (apontando para a frente) é o *z* eixo
  * seu dedo médio (apontando para o lado) é o *x* eixo
  * seu polegar (apontando para cima) é o *y* eixo.
* Se uma entidade é filha de outra, então `x:0, y:0, z:0` se refere ao centro da entidade pai, onde quer que ela esteja na cena.
* Toda entidade na sua cena deve estar posicionada dentro dos limites dos parcels que ocupa o tempo todo. Se uma entidade sair desses limites, isso gerará um erro.

  > Dica: Ao visualizar uma cena no modo de prévia, entidades que estão fora dos limites são destacadas em *vermelho*.
* Sua cena também é limitada em altura. A altura máxima é de 330 metros para cada cena, independentemente de quantos parcels ela ocupe. Entidades colocadas acima de 200 metros podem sofrer problemas de sincronização em multiplayer. Veja [limitações da scene](/creator/content-creator-pt/scenes-sdk7/otimizacao/scene-limitations.md) para mais detalhes.

## Rotação

`rotation` é armazenado como um [*quaternion*](https://en.wikipedia.org/wiki/Quaternion), um sistema de quatro números, *x*, *y*, *z* e *w*. Cada um desses números varia de -1 a 1. Veja [Tipos de geometria](/creator/content-creator-pt/scenes-sdk7/fundamentos-de-conteudo-3d/special-types.md) para mais detalhes.

```ts
// Criar uma nova entidade
const cube = engine.addEntity()

// Criar transform com uma rotação predefinida de 0
Transform.create(cube, {
	  rotation: Quaternion.Identity()
})

// Obter uma versão mutável do transform
const mutableTransform = Transform.getMutable(cube)

// Definir a rotação com um objeto, a partir de ângulos de Euler
mutableTransform.rotation = Quaternion.fromEulerDegrees(0, 90, 0)

// Definir a rotação com um objeto
mutableTransform.rotation = { x: 0.1, y: 0.5, z: 0.5, w: 0 }

// Definir cada eixo individualmente
mutableTransform.rotation.x = 0
mutableTransform.rotation.y = 1
mutableTransform.rotation.z = 0.3
mutableTransform.rotation.w = 0
```

Você também pode definir o campo de rotação com [*Euler* ângulos](https://en.wikipedia.org/wiki/Euler_angles), a mais comum *x*, *y* e *z* notação com números que variam de 0 a 360 com a qual a maioria das pessoas está familiarizada. Para usar ângulos de Euler, use uma das seguintes notações:

```ts
// Criar transform com uma rotação predefinida em ângulos de Euler
Transform.create(cube, {
	  rotation: Quaternion.fromEulerDegrees(0, 90, 0)
})

// Obter uma versão mutável do transform
const mutableTransform = Transform.getMutable(cube)

// Definir a rotação com um objeto, a partir de ângulos de Euler
mutableTransform.rotation = Quaternion.fromEulerDegrees(0, 90, 0)
```

Ao usar um *vetor 3D* para representar ângulos de Euler, *x*, *y* e *z* representa a rotação nesse eixo, medida em graus. Uma volta completa requer 360 graus.

Ao obter a rotação de uma entidade, por padrão ela retorna um quaternion. Para obter a rotação expressa em ângulos de Euler, use `Quaternion.toEulerAngles()`:

```ts
// Obter uma versão somente leitura do transform
const transform = Transform.get(cube)

// Obter a rotação expressa em ângulos de Euler
const eulerAngle = Quaternion.toEulerAngles(transform.rotation)
```

## Obtendo a posição global e a rotação global de uma Entidade

O `getWorldPosition` e `getWorldRotation` funções retornam a posição global e a rotação global de uma entidade. Isso significa que elas retornam a posição ou rotação percebida em que o jogador verá o item, ignorando quaisquer hierarquias de parentesco.

* `getWorldPosition(engine, entity: Entity): Vector3Type`: Esta função retorna a posição global de uma entidade, considerando todas as posições das entidades pai, caso a própria entidade tenha alguma, retornando `{x: 0, y: 0, z: 0}` se a entidade não tiver Transform.

```ts
const worldPos = getWorldPosition(engine, childEntity)
console.log(`Posição global: ${worldPos.x}, ${worldPos.y}, ${worldPos.z}`)
```

* `getWorldRotation(engine, entity: Entity): QuaternionType`: Esta função retorna a rotação global de uma entidade, considerando todas as rotações das entidades pai, caso a própria entidade tenha alguma. Ela retorna um `Quaternion` tipo, retornando o quaternion identidade `{x: 0, y: 0, z: 0, w: 1}` se a entidade não tiver Transform.

```ts
const worldRot = getWorldRotation(engine, childEntity)
console.log(`Rotação global: ${worldRot.x}, ${worldRot.y}, ${worldRot.z}, ${worldRot.w}`)
```

{% hint style="info" %}
**Observação:** A posição global e a rotação global são relativas às coordenadas dentro da cena e não à Genesis City.
{% endhint %}

## Encare o jogador

Adicione um *Billboard* componente em uma entidade para que ela sempre gire para encarar o jogador.

Billboards eram uma técnica comum usada em jogos 3D dos anos 90, em que a maioria das entidades eram planos 2D que sempre encaravam o jogador. A mesma ideia também pode ser usada para girar um modelo 3D.

```ts
// Criar uma nova entidade
const cube = engine.addEntity()

// Dar à entidade uma forma visível
MeshRenderer.setBox(cube)

// Criar transform com uma posição predefinida
Transform.create(cube, {
	  position: Vector3.create(5, 1, 5)
})

// Dar à entidade um componente Billboard
Billboard.create(cube, {})
```

Você pode configurar como o Billboard se comporta com os seguintes parâmetros:

* `billboardMode`: Usa um valor de `BillboardMode` para definir quais eixos de rotação giram automaticamente para encarar o jogador:
  * `BillboardMode.BM_ALL`: A entidade gira para encarar o jogador em todos os seus eixos de rotação. Se o jogador estiver muito acima da entidade, a entidade ficará voltada para cima.
  * `BillboardMode.BM_NONE`: A entidade não girará em absoluto.
  * `BillboardMode.BM_X`: A entidade gira apenas no seu *x* eixo de rotação.
  * `BillboardMode.BM_Y`: A entidade gira apenas no seu *y* eixo de rotação. Ela gira apenas para a esquerda e para a direita, não para cima e para baixo. Permanece perpendicular ao chão se o jogador estiver acima ou abaixo da entidade.
  * `BillboardMode.BM_Z`: A entidade gira apenas no seu *z* eixo de rotação.
* `targetEntity`: (opcional) Uma entidade para a qual o billboard gira para encarar, em vez da câmera do jogador. Se a entidade referenciada não existir (por exemplo, ainda não tiver sido criada ou tiver sido removida), o billboard para de girar e mantém sua última orientação até que a entidade volte a existir. Definir isso como `engine.CameraEntity` é equivalente a deixá-lo sem definição.

```ts
// billboard plano
const perpendicularPlane = engine.addEntity()

Transform.create(perpendicularPlane, {
	position: Vector3.create(8, 1, 8),
})

MeshRenderer.setPlane(perpendicularPlane)

Billboard.create(perpendicularPlane, {
	billboardMode: BillboardMode.BM_Y,
})

// rótulo de texto
const textLabel = engine.addEntity()

Transform.create(textLabel, {
	position: Vector3.create(6, 1, 6),
})

TextShape.create(textLabel, {
	text: 'Este texto está sempre legível',
})

Billboard.create(textLabel)

// placa que encara outra entidade em vez do jogador
const sphere = engine.addEntity()

Transform.create(sphere, {
	position: Vector3.create(4, 2, 4),
})

MeshRenderer.setSphere(sphere)

const sign = engine.addEntity()

Transform.create(sign, {
	position: Vector3.create(8, 1, 8),
})

TextShape.create(sign, {
	text: 'Observando a esfera',
})

Billboard.create(sign, {
	targetEntity: sphere,
})
```

{% hint style="info" %}
**💡 Dica**: Billboards são muito úteis para adicionar a *text* entidades, já que isso as torna sempre legíveis.
{% endhint %}

O `rotation` valor do `Transform` componente da entidade não muda à medida que o Billboard segue os jogadores.

Se uma entidade tiver tanto um `Billboard` component e `Transform` componente com `rotation` valores, os jogadores verão a entidade girando como um billboard. Se o billboard não afetar todos os eixos, o eixo restante será girado de acordo com os `Transform` component.

{% hint style="warning" %}
**📔 Observação**: Se houver vários jogadores presentes ao mesmo tempo, cada um verá as entidades com o modo billboard voltadas para si. As rotações do Billboard são calculadas localmente para cada jogador e não afetam o que os outros veem. Isso não se aplica a billboards com um `targetEntity`: como a posição do alvo faz parte da cena, todos os jogadores veem esses billboards voltados da mesma maneira.
{% endhint %}

## Encarar um conjunto de coordenadas

Para a entidade A olhar para a entidade B:

```
1) Subtraia a posição da entidade A da entidade B para obter um vetor que descreve a distância entre elas.
2) Normalize esse vetor, para que ele tenha comprimento 1, mantendo sua direção.
3) Use `Quaternion.lookRotation` para obter uma rotação Quaternion que descreve girar nessa direção.
4) Defina esse Quaternion como a rotação da entidade A
```

```ts
export function turn(entity: Entity, target: Vector3.ReadonlyVector3) {
	const transform = Transform.getMutable(entity)
	const difference = Vector3.subtract(target, transform.position)
	const normalizedDifference = Vector3.normalize(difference)
	transform.rotation = Quaternion.lookRotation(normalizedDifference)
}
```

## Escala

`scale` também é um *vetor 3D*, armazenada como um `Vector3` objeto, incluindo o fator de escala no *x*, *y* e *z* eixo. A forma da entidade é escalada de acordo, seja ela um primitivo ou um modelo 3D.

A escala padrão é 1, então atribua um valor maior que 1 para esticar uma entidade ou menor que 1 para encolhê-la.

```ts
// Criar uma nova entidade
const ball = engine.addEntity()

// Criar transform com uma posição predefinida
Transform.create(ball, {
	  scale: Vector3.create(5, 5, 5)
})

// Obter uma versão mutável do transform
const mutableTransform = Transform.getMutable(ball)

// Definir a escala com um Vector3

mutableTransform.scale = Vector3.create(2, 2, 2)

// Definir a posição com um objeto
mutableTransform.scale = { x: 5, y: 1, z: 5 }

// Definir cada eixo individualmente
mutableTransform.scale.x = 3
mutableTransform.scale.y = 3
mutableTransform.scale.z = 2
```

## Herdar transformações do pai

Quando uma entidade está aninhada dentro de outra, as entidades filhas herdam componentes dos pais. Isso significa que, se uma entidade pai for posicionada, escalada ou rotacionada, suas filhas também serão afetadas. Os valores de posição, rotação e escala das entidades filhas não substituem os dos pais; em vez disso, eles são combinados.

Você atribui uma entidade para ser pai de outra definindo o `parent` campo no `Transform` component.

Se uma entidade pai for escalada, todos os valores de posição de suas filhas também são escalados.

```ts
// Criar entidades
const parentEntity = engine.addEntity()
const childEntity = engine.addEntity()

// Criar um transform para o pai
Transform.create(parentEntity, {
	position: Vector3.create(3, 1, 1),
	scale: Vector3.create(0.5, 0.5, 0.5),
})

// Criar um transform para a filha e atribuí-lo como filha
Transform.create(childEntity, {
	position: Vector3.create(0, 1, 0),
	parent: parentEntity,
})
```

Neste exemplo, a entidade filha será reduzida para 0,5, já que seu pai tem essa escala. A posição da entidade filha também será relativa ao seu pai. Precisamos somar a posição do pai à da filha. Neste caso, como o pai está escalado para metade do seu tamanho, a transformação da filha também é reduzida proporcionalmente. Em termos absolutos, a filha é posicionada em `{ x: 3, y: 1.5, z: 1 }`. Se o pai tivesse um `rotation`, isso também afetaria a posição final da filha, pois altera o eixo no qual a filha é deslocada.

Se uma entidade filha não tiver `position` em seu Transform, o padrão é `0,0,0`, o que a deixará posicionada na mesma posição que seu pai.

Você pode usar uma entidade invisível sem componente de forma como pai, para envolver um conjunto de outras entidades. Essa entidade não será visível na cena renderizada, mas pode ser usada para agrupar suas filhas e aplicar um transform a todas elas.

{% hint style="warning" %}
**📔 Observação**Evite criar um ciclo na hierarquia, onde uma entidade acaba sendo seu próprio ancestral. O SDK detecta esses ciclos e registra um aviso nomeando as entidades envolvidas. As entidades afetadas não são posicionadas corretamente até que você corrija o relacionamento pai-filho.
{% endhint %}

## Anexar um Entity a um avatar

Há três métodos para anexar uma entidade ao jogador:

* Torne-a filha da **Entidade Avatar**
* Torne-a filha da **Entidade da Câmera**
* Use o **componente AvatarAttach**

A maneira mais simples de anexar uma entidade ao avatar é definir o pai como a [entidade reservada](/creator/content-creator-pt/scenes-sdk7/arquitetura/entities-components.md#reserved-entities) `engine.PlayerEntity`. A entidade então se moverá junto com a posição do jogador.

```ts
let childEntity = engine.addEntity()

MeshRenderer.setCylinder(childEntity)

Transform.create(childEntity, {
	scale: Vector3.create(0.2, 0.2, 0.2),
	position: Vector3.create(0, 0.4, 0),
	parent: engine.PlayerEntity,
})
```

Você também pode definir uma entidade para a [entidade reservada](/creator/content-creator-pt/scenes-sdk7/arquitetura/entities-components.md#reserved-entities) `engine.CameraEntity`entidade da câmera. Ao usar a entidade da câmera em primeira pessoa, a entidade anexada seguirá os movimentos da câmera. Isso é ideal para manter algo sempre em vista, por exemplo, para manter o modelo 3D da arma sempre em vista, mesmo quando a câmera aponta para cima.

```ts
let childEntity = engine.addEntity()

MeshRenderer.setCylinder(childEntity)

Transform.create(childEntity, {
	scale: Vector3.create(0.2, 0.2, 0.2),
	position: Vector3.create(0, 0.4, 0),
	parent: engine.CameraEntity,
})
```

Para anexar um objeto a um dos ossos do avatar e fazê-lo se mover junto com as animações do avatar, adicione um `AvatarAttach` componente à entidade.

Você pode escolher diferentes pontos de ancoragem no avatar; a maioria desses pontos está ligada à armature do jogador e segue as animações do jogador. Por exemplo, ao usar o ponto de ancoragem da mão direita, a entidade anexada se moverá quando o avatar acenar ou balançar os braços enquanto corre, como se o jogador estivesse segurando a entidade na mão.

```ts
// Anexar ao jogador principal; se avatarId não estiver definido, engine.PlayerEntity é usado por padrão
AvatarAttach.create(myEntity, {
	anchorPointId: AvatarAnchorPointType.AAPT_NAME_TAG,
})

// Anexar a um jogador por ID
AvatarAttach.create(myEntity, {
	avatarId: '0xAAAAAAAAAAAAAAAAA',
	anchorPointId: AvatarAnchorPointType.AAPT_NAME_TAG,
})
```

Ao criar um `AvatarAttach` componente, passe um objeto com os seguintes dados:

* `avatarId`: *Opcional* O ID do jogador ao qual anexar. Isso é o mesmo que o endereço Ethereum do jogador, para aqueles jogadores conectados com uma carteira Ethereum. Se não for especificado, ele anexa a entidade ao avatar do jogador local.
* `anchorPointId`: Qual ponto de ancoragem no esqueleto do avatar para anexar a entidade, usando um valor do enum `AvatarAnchorPointType`.

{% hint style="warning" %}
**📔 Observação**: Se você quiser que todos os jogadores na cena vejam um objeto anexado ao mesmo jogador, por exemplo, para todos verem que o Jogador A pegou um objeto e o segura na mão esquerda, então você deve fornecer um valor para `avatarId`. Se não for especificado, então todos os jogadores verão o objeto anexado aos seus próprios avatares.
{% endhint %}

O exemplo a seguir coloca uma entidade anexada a um avatar específico, para que todos os outros jogadores a vejam anexada a esse mesmo avatar.

```ts
import { getPlayer } from '@dcl/sdk/src/players'
import { AvatarAnchorPointType, AvatarAttach, engine, Entity } from '@dcl/sdk/ecs'
import { syncEntity } from '@dcl/sdk/network'

async function attachToPlayer(){

 let userData = await getPlayer()
 console.log(userData)

 if (!userData || !userData.wearables) return

  let entity = engine.addEntity()

  AvatarAttach.create(entity, {
    avatarId: userData.userId,
    anchorPointId: AvatarAnchorPointType.AAPT_RIGHT_HAND,
  })

  // Outros componentes

  syncEntity(entity, [AvatarAttach.componentId])

}
```

Os seguintes pontos de ancoragem estão disponíveis no `AvatarAnchorPointType` enum:

* `AAPT_RIGHT_HAND`: Fixo na mão direita do jogador
* `AAPT_LEFT_HAND`: Fixo na mão esquerda do jogador
* `AAPT_HEAD`: Fixo ao centro da cabeça do jogador.
* `AAPT_NECK`: Fixo à base do pescoço do jogador.
* `AAPT_SPINE`: Fixo à seção superior da coluna.
* `AAPT_SPINE1`: Fixo à seção intermediária da coluna.
* `AAPT_SPINE2`: Fixo à seção inferior da coluna.
* `AAPT_HIP`: Fixo ao osso do quadril.
* `AAPT_LEFT_SHOULDER`: Fixo ao ombro esquerdo.
* `AAPT_LEFT_ARM`: Fixo ao primeiro osso do braço esquerdo, na altura do ombro.
* `AAPT_LEFT_FOREARM`: Fixo ao osso do antebraço esquerdo.
* `AAPT_LEFT_HAND_INDEX`: Fixo à ponta do dedo indicador esquerdo.
* `AAPT_RIGHT_SHOULDER`: Fixo ao ombro direito.
* `AAPT_RIGHT_ARM`: Fixo ao primeiro osso do braço direito, na altura do ombro.
* `AAPT_RIGHT_FOREARM`: Fixo ao osso do antebraço direito.
* `AAPT_RIGHT_HAND_INDEX`: Fixo à ponta do dedo indicador direito.
* `AAPT_LEFT_UP_LEG`: Fixo ao osso superior da perna esquerda.
* `AAPT_LEFT_LEG`: Fixo ao osso inferior da perna esquerda.
* `AAPT_LEFT_FOOT`: Fixo ao tornozelo da perna esquerda.
* `AAPT_LEFT_TOE_BASE`: Fixo à ponta do dedo do pé da perna esquerda.
* `AAPT_RIGHT_UP_LEG`: Fixo ao osso superior da perna direita.
* `AAPT_RIGHT_LEG`: Fixo ao osso inferior da perna direita.
* `AAPT_RIGHT_FOOT`: Fixo ao tornozelo da perna direita.
* `AAPT_RIGHT_TOE_BASE`: Fixo à ponta do dedo do pé da perna direita.
* `.AAPT_NAME_TAG`: Flutua logo acima da tag de nome do jogador, não é afetado pelas animações do jogador.

  > Nota: A altura da etiqueta de nome é ajustada dinamicamente com base na altura dos Wearables que o jogador tem colocados. Assim, um jogador a usar um chapéu alto terá a sua etiqueta de nome um pouco mais alta do que os outros.
* `AAPT_POSITION` *OBSOLETO*: A posição geral do jogador. Isto aparece a uma altura de 0,8 acima dos pés do jogador.

  >

{% hint style="warning" %}
\> \*\*📔 Nota\*\*: O \`AAPT\_POSITION\` está obsoleto. Para seguir a posição geral do jogador, o melhor é tornar a entity uma filha do Avatar Entity. Vê o início desta secção para um exemplo. >
{% endhint %}

{% hint style="info" %}
**💡 Dica**: Para usar estes valores, escreve `AvatarAnchorPointType.` e o VS Code mostrará a lista completa de opções num dropdown.
{% endhint %}

![](https://2402076176-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-206945bba419a58cd6fe54c557cc6e5d75e1bb86%2Favatar-attach-points.png?alt=media\&token=bd194d22-a304-4254-b739-b25cdf372497)

A renderização da entity é determinada localmente em cada instância da Scene. Anexar uma entity a um jogador não a torna visível para outros jogadores que estejam a ver esse jogador. Se uma entity estiver anexada ao jogador local predefinido, cada jogador irá experienciar a entity como anexada ao seu próprio avatar.

{% hint style="warning" %}
**📔 Observação**: As entities anexadas a um avatar têm de permanecer dentro dos limites da Scene para serem renderizadas. Se um jogador sair da tua Scene, quaisquer entities anexadas deixam de ser renderizadas até o jogador voltar a entrar. Smart wearables não têm esta limitação.
{% endhint %}

O `AvatarAttach` component substitui os valores no `Transform` component. Quaisquer valores que coloques no `Transform` component são substituídos pela posição relativa da entity em relação à do Transform do jogador; estes valores são atualizados frame a frame à medida que o jogador se move e anima.

Se precisares de posicionar uma entity com um offset em relação ao ponto de ancoragem no avatar, ou com uma rotação ou escala diferentes, faz isso através de uma entity pai.

1. Cria uma entity invisível apenas com um `Transform` e um `AvatarAttach` component. Os seus `Transform` valores serão substituídos à medida que o jogador se move
2. Define a entity que queres anexar como filha desta entity pai. Os seus `Transform` valores podem descrever o offset em relação ao ponto de ancoragem.

```ts
// Criar entity pai
const parentEntity = engine.addEntity()

// Anexar entity pai ao jogador
AvatarAttach.create(parentEntity, {
	anchorPointId: AvatarAnchorPointType.AAPT_NAME_TAG,
})

// Criar entity filha
let childEntity = engine.addEntity()

MeshRenderer.setCylinder(childEntity)

Transform.create(childEntity, {
	scale: Vector3.create(0.2, 0.2, 0.2),
	position: Vector3.create(0, 0.4, 0),
	parent: parentEntity,
})
```

{% hint style="warning" %}
**📔 Observação**: Se a entity anexada tiver colliders, estes colliders podem bloquear o movimento do jogador ou causar efeitos instáveis. Talvez queiras desativar a camada física dos colliders da entity anexada. Vê [Collision layers](/creator/content-creator-pt/scenes-sdk7/fundamentos-de-conteudo-3d/colliders.md#collision-layers)
{% endhint %}

{% hint style="warning" %}
**📔 Observação**: Se tiveres uma child entity e quiseres saber a Position e/ou Rotation global dela, podes usar as `getWorldPosition` e `getWorldRotation` functions. Podes verificá-las no [Obter Position e Rotation Globais](#getting-global-position-and-rotation-of-an-entity) seção.
{% endhint %}

### Anexar a outros jogadores

Você pode usar o `AvatarAttach` component para anexar uma entity a outro jogador. Para isso, deves conhecer o id do jogador.

Para anexar uma entity ao avatar de outro jogador, deves fornecer o ID do utilizador no campo `avatarId`. Há [várias formas](/creator/content-creator-pt/scenes-sdk7/interatividade/user-data.md#get-player-data) de obter estes dados.

{% hint style="warning" %}
**📔 Observação**: Para esses jogadores ligados com uma wallet Ethereum, o seu `userId` é o mesmo que o seu endereço Ethereum.
{% endhint %}

Obtém o `userId` para todos os outros jogadores próximos através de `getPlayer()`

```ts
executeTask(async () => {
	for (const [entity, data] of engine.getEntitiesWith(PlayerIdentityData)) {
		console.log('Player id: ', data.address)
	}
})
```

Usando-o em conjunto com `AvatarAttach`, poderias usar o seguinte código para adicionar um cubo a flutuar sobre a cabeça de cada outro jogador na Scene:

```ts
executeTask(async () => {
        for (const [entity, data] of engine.getEntitiesWith(PlayerIdentityData)) {
            const myEntity = engine.addEntity()
            MeshRenderer.setBox(myEntity)
            AvatarAttach.create(myEntity, {
                anchorPointId: AvatarAnchorPointType.AAPT_LEFT_HAND,
                avatarId: data.address,
            })
        }
    })
```

Vê outras formas de obter os IDs de outros utilizadores em [Obter Dados do Jogador](/creator/content-creator-pt/scenes-sdk7/interatividade/user-data.md#get-player-data).

## Limites da scene

Todas as entities na tua Scene devem caber dentro dos limites da Scene, pois o que está fora desses limites são parcels de terra pertencentes a outros jogadores.

Se alguma parte dos teus modelos se estender para além destes limites ao executar um Preview, essas partes excedentes serão cortadas e não renderizadas, tanto ao executar um Preview como na Scene publicada.

A posição das entities na tua Scene é verificada constantemente à medida que se movem; se uma entity sair da Scene e depois regressar, será removida e depois renderizada normalmente novamente.

Uma grelha no Ground da Scene mostra os limites da Scene, que por padrão vão de 0 a 16 no *x* e *z* eixo, e até 20 no *y* eixo. És livre para colocar entities no subsolo, abaixo de 0 no *y* eixo.

{% hint style="info" %}
**💡 Dica**: Se a tua Scene precisar de mais parcels, podes adicioná-las no projeto `scene.json` ficheiro. Vê [metadata da scene](/creator/content-creator-pt/scenes-sdk7/tipos-de-projetos/scene-metadata.md) para instruções. Depois de os adicionares, deverás ver a grelha expandir-se para cobrir os parcels adicionais.
{% 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-pt/scenes-sdk7/fundamentos-de-conteudo-3d/entity-positioning.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.
