> 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-es/scenes-sdk7/fundamentos-del-contenido-3d/entity-positioning.md).

# Posicionamiento de entidades

Cómo establecer la posición, rotación y escala de una entidad en una escena

Puedes establecer el *posición*, *rotación* y *escala* de cualquier entity usando el `Transform` component. Esto se puede usar en cualquier entity en el espacio 3D, afectando dónde se renderiza la entity. Esto incluye formas primitivas (cube, sphere, plane, etc), formas de texto 3D, formas NFT y modelos 3D (`GltfContainer`).

## Usa el Scene Editor en Creator Hub

Al agregar un elemento a tu scene mediante el Scene Editor, incluye implícitamente un **Transform** component. Luego cambias implícitamente los valores del component Transform de la entity al cambiar la position, rotation o scale de una entity. También puedes usar la UI del Scene Editor para proporcionar valores numéricos con mayor precisión.

## Conceptos básicos del código

![](https://1216664193-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
// Crear una nueva entity
const ball = engine.addEntity()

// Dar a esta entity una forma para hacerla visible
MeshRenderer.setSphere(ball)

// Dar a esta entity un component Transform
Transform.create(ball, {
	position: Vector3.create(5, 1, 5),
	scale: Vector3.create(1, 1, 1),
	rotation: Quaternion.Identity(),
})
```

Para mover, rotar o redimensionar una entity en tu scene a lo largo del tiempo, cambia los valores de este component de forma incremental, fotograma a fotograma. Consulta [Mover Entities](/creator/content-creator-es/scenes-sdk7/fundamentos-del-contenido-3d/move-entities.md) para más detalles y buenas prácticas.

{% hint style="warning" %}
**📔 Nota**: `Vector3` y `Quaternion` deben importarse mediante

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

Consulta [Imports](/creator/content-creator-es/scenes-sdk7/primeros-pasos/coding-scenes.md#imports) para ver cómo manejarlos fácilmente.
{% endhint %}

## Posición

`posición` es un *vector 3D*, establece la position del centro de la entity en los tres axes, *x*, *y*, y *z*. Consulta [Tipos de geometría](/creator/content-creator-es/scenes-sdk7/fundamentos-del-contenido-3d/special-types.md) para más detalles.

```ts
// Crear una nueva entity
const ball = engine.addEntity()

// Crear un transform con una position predefinida
Transform.create(ball, {
	  position: Vector3.create(5, 1, 5)
})

// Obtener una versión mutable del transform
const mutableTransform = Transform.getMutable(ball)

// Establecer la position con un objeto
mutableTransform.position = { x: 5, y: 1, z: 5 }

// Establecer la position con un objeto (sintaxis alternativa)
mutableTransform.position = Vector3.create(2, 1, 4)

// Establecer cada eje por separado
mutableTransform.position.x = 3
mutableTransform.position.y = 1
mutableTransform.position.z = 3
```

Al establecer una position, ten en cuenta las siguientes consideraciones:

* Los números de un vector de position representan *metros* (a menos que la entity sea hija de una entity escalada).
* Una scene compuesta por un solo parcel mide 16 m x 16 m. El centro de la scene (a nivel del suelo) está en `x:8, y:0, z:8`. Si la scene está compuesta por múltiples parcels, entonces el centro variará según su disposición.
* `x:0, y:0, z:0` se refiere a la *Suroeste* esquina del parcel base de la scene, a nivel del suelo.

  > Consejo: al ver una vista previa de una scene, aparece una brújula en el punto (0,0,0) de la scene con etiquetas para cada eje como referencia.

  > Nota: puedes cambiar el parcel base de una scene editando el `base` atributo de *scene.json*.
* Para orientarte mejor, usa tu *left* mano:
  * tu dedo índice (apuntando hacia adelante) es el *z* eje
  * tu dedo medio (apuntando hacia un lado) es el *x* eje
  * tu pulgar (apuntando hacia arriba) es el *y* eje.
* Si una entity es hija de otra, entonces `x:0, y:0, z:0` se refiere al centro de su entity padre, dondequiera que esté en la scene.
* Toda entity de tu scene debe estar posicionada dentro de los límites de los parcels que ocupa en todo momento. Si una entity sale de estos límites, se producirá un error.

  > Consejo: al ver una scene en modo preview, las entities que están fuera de los límites se resaltan en *rojo*.
* Tu scene también tiene un límite de altura. La altura máxima es de 330 metros para cada scene, independientemente de cuántos parcels ocupe. Las entities colocadas por encima de 200 metros pueden sufrir problemas de sincronización en multiplayer. Consulta [limitaciones de la escena](/creator/content-creator-es/scenes-sdk7/optimizacion/scene-limitations.md) para más detalles.

## Rotation

`rotación` se almacena como un [*quaternion*](https://en.wikipedia.org/wiki/Quaternion), un sistema de cuatro números, *x*, *y*, *z* y *w*. Cada uno de estos números va de -1 a 1. Consulta [Tipos de geometría](/creator/content-creator-es/scenes-sdk7/fundamentos-del-contenido-3d/special-types.md) para más detalles.

```ts
// Crear una nueva entity
const cube = engine.addEntity()

// Crear un transform con una rotation predefinida de 0
Transform.create(cube, {
	  rotation: Quaternion.Identity()
})

// Obtener una versión mutable del transform
const mutableTransform = Transform.getMutable(cube)

// Establecer la rotation con un objeto, a partir de angles Euler
mutableTransform.rotation = Quaternion.fromEulerDegrees(0, 90, 0)

// Establecer la rotation con un objeto
mutableTransform.rotation = { x: 0.1, y: 0.5, z: 0.5, w: 0 }

// Establecer cada eje por separado
mutableTransform.rotation.x = 0
mutableTransform.rotation.y = 1
mutableTransform.rotation.z = 0.3
mutableTransform.rotation.w = 0
```

También puedes establecer el campo rotation con [*Euler* ángulos](https://en.wikipedia.org/wiki/Euler_angles), la notación más común *x*, *y* y *z* con números que van de 0 a 360 con la que la mayoría de la gente está familiarizada. Para usar ángulos Euler, utiliza una de las siguientes notaciones:

```ts
// Crear un transform con una rotation predefinida en ángulos Euler
Transform.create(cube, {
	  rotation: Quaternion.fromEulerDegrees(0, 90, 0)
})

// Obtener una versión mutable del transform
const mutableTransform = Transform.getMutable(cube)

// Establecer la rotation con un objeto, a partir de angles Euler
mutableTransform.rotation = Quaternion.fromEulerDegrees(0, 90, 0)
```

Al usar un *vector 3D* para representar ángulos Euler, *x*, *y* y *z* representa la rotation en ese eje, medida en grados. Una vuelta completa requiere 360 grados.

Cuando recuperas la rotation de una entity, devuelve un quaternion de forma predeterminada. Para obtener la rotation expresada en ángulos Euler, usa `Quaternion.toEulerAngles()`:

```ts
// Obtener una versión de solo lectura del transform
const transform = Transform.get(cube)

// Obtener la rotation expresada en ángulos Euler
const eulerAngle = Quaternion.toEulerAngles(transform.rotation)
```

## Obtención de la posición global y la rotación de una Entity

El `getWorldPosition` y `getWorldRotation` functions devuelven la posición global y la rotation de una entity. Eso significa que devuelve la posición o rotation percibida en la que el player verá el item, ignorando cualquier jerarquía padre.

* `getWorldPosition(engine, entity: Entity): Vector3Type`: Esta función devuelve la posición World de una entity, teniendo en consideración todas las posiciones de las parent entities, si la entity misma tiene alguna, devolviendo `{x: 0, y: 0, z: 0}` si la entity no tiene Transform.

```ts
const worldPos = getWorldPosition(engine, childEntity)
console.log(`World position: ${worldPos.x}, ${worldPos.y}, ${worldPos.z}`)
```

* `getWorldRotation(engine, entity: Entity): QuaternionType`: Esta función devuelve la rotation World de una entity, teniendo en consideración todas las rotaciones de las parent entities, si la entity misma tiene alguna. Devuelve un `Quaternion` tipo, devolviendo un quaternion identidad `{x: 0, y: 0, z: 0, w: 1}` si la entity no tiene Transform.

```ts
const worldRot = getWorldRotation(engine, childEntity)
console.log(`World rotation: ${worldRot.x}, ${worldRot.y}, ${worldRot.z}, ${worldRot.w}`)
```

{% hint style="info" %}
**Nota:** La posición global y la rotation global son relativas a las coordenadas dentro de la scene y no a Genesis City.
{% endhint %}

## Haz que mire al player

Añade un *Billboard* component a una entity para que siempre rote para mirar al player.

Los Billboards eran una técnica común usada en juegos 3D de los 90, en los que la mayoría de las entities eran planos 2D que siempre miraban al player. La misma idea también puede usarse para rotar un modelo 3D.

```ts
// Crear una nueva entity
const cube = engine.addEntity()

// Dar a la entity una forma visible
MeshRenderer.setBox(cube)

// Crear un transform con una position predefinida
Transform.create(cube, {
	  position: Vector3.create(5, 1, 5)
})

// Dar a la entity un component Billboard
Billboard.create(cube, {})
```

Puedes configurar cómo se comporta el billboard con los siguientes parámetros:

* `billboardMode`: Usa un valor de `BillboardMode` para establecer qué axes de rotation rotan automáticamente para mirar al player:
  * `BillboardMode.BM_ALL`: La entity rota para mirar al player en todos sus axes de rotation. Si el player está muy por encima de la entity, la entity mirará hacia arriba.
  * `BillboardMode.BM_NONE`: La entity no rotará en absoluto.
  * `BillboardMode.BM_X`: La entity solo rota en su *x* eje de rotation.
  * `BillboardMode.BM_Y`: La entity solo rota en su *y* eje de rotation. Solo rota a la izquierda y a la derecha, no hacia arriba ni hacia abajo. Permanece perpendicular al suelo si el player está por encima o por debajo de la entity.
  * `BillboardMode.BM_Z`: La entity solo rota en su *z* eje de rotation.
* `targetEntity`: (opcional) Una entity hacia la que gira el billboard para mirar, en lugar de la camera del player. Si la entity referenciada no existe (por ejemplo, aún no se ha creado o se eliminó), el billboard deja de rotar y conserva su última orientación hasta que la entity vuelva a existir. Establecer esto en `engine.CameraEntity` es equivalente a dejarlo sin establecer.

```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,
})

// etiqueta de texto
const textLabel = engine.addEntity()

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

TextShape.create(textLabel, {
	text: 'Este texto siempre es legible',
})

Billboard.create(textLabel)

// señal que mira hacia otra entity en lugar del player
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: 'Mirando la sphere',
})

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

{% hint style="info" %}
**💡 Consejo**: Los Billboards son muy útiles para añadir a *text* entities, ya que hace que siempre sean legibles.
{% endhint %}

El `rotación` valor del component de la entity `Transform` no cambia mientras el billboard sigue a los players a su alrededor.

Si una entity tiene tanto un `Billboard` componente y `Transform` componente con `rotación` values, los players verán la entity rotando como un billboard. Si el billboard no afecta a todos los axes, el axis restante se rotará de acuerdo con el `Transform` componente.

{% hint style="warning" %}
**📔 Nota**: Si hay varios players presentes al mismo tiempo, cada uno verá las entities con modo billboard orientadas hacia ellos. Las rotaciones de los billboards se calculan localmente para cada player y no afectan lo que ven los demás. Esto no se aplica a los billboards con un `targetEntity`: ya que la posición del target forma parte de la scene, todos los players ven esos billboards mirando de la misma manera.
{% endhint %}

## Mirar hacia un conjunto de coordenadas

Para que la entity A mire a la entity B:

```
1) Resta la position de la entity A a la de la entity B para obtener un vector que describa la distancia entre ellas.
2) Normaliza ese vector, para que tenga una longitud de 1, manteniendo su dirección.
3) Usa `Quaternion.lookRotation` para obtener una rotation Quaternion que describa una rotación en esa dirección.
4) Establece ese Quaternion como la rotation de la entity 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)
}
```

## Scale

`escala` también es un *vector 3D*, almacenado como un `Vector3` objeto, incluido el factor de scale en el *x*, *y* y *z* axis. La forma de la entity se escala en consecuencia, ya sea un primitive o un modelo 3D.

La scale predeterminada es 1, así que asigna un valor mayor que 1 para estirar una entity o menor que 1 para encogerla.

```ts
// Crear una nueva entity
const ball = engine.addEntity()

// Crear un transform con una position predefinida
Transform.create(ball, {
	  scale: Vector3.create(5, 5, 5)
})

// Obtener una versión mutable del transform
const mutableTransform = Transform.getMutable(ball)

// Establecer la scale con un Vector3

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

// Establecer la position con un objeto
mutableTransform.scale = { x: 5, y: 1, z: 5 }

// Establecer cada eje por separado
mutableTransform.scale.x = 3
mutableTransform.scale.y = 3
mutableTransform.scale.z = 2
```

## Heredar transformaciones del parent

Cuando una entity está anidada dentro de otra, las child entities heredan components de las parents. Esto significa que si una parent entity está posicionada, escalada o rotada, sus children también se ven afectadas. Los valores de position, rotation y scale de las child entities no anulan los de los parents, sino que se combinan.

Asignas una entity para que sea parent de otra estableciendo el `parent` field en el child entity's `Transform` componente.

Si una parent entity se escala, todos los valores de position de sus children también se escalan.

```ts
// Crear entities
const parentEntity = engine.addEntity()
const childEntity = engine.addEntity()

// Crear un transform para el parent
Transform.create(parentEntity, {
	position: Vector3.create(3, 1, 1),
	scale: Vector3.create(0.5, 0.5, 0.5),
})

// Crear un transform para el child y asignarlo como child
Transform.create(childEntity, {
	position: Vector3.create(0, 1, 0),
	parent: parentEntity,
})
```

En este ejemplo, la child entity se reducirá a 0.5, ya que su parent tiene ese scale. La position de la child entity también será relativa a su parent. Tenemos que sumar la position del parent más la del child. En este caso, como el parent está escalado a la mitad de su tamaño, la transformation del child también se escala proporcionalmente. En términos absolutos, la child está posicionada en `{ x: 3, y: 1.5, z: 1 }`. Si el parent tuviera un `rotación`, esto también afectaría la posición final del child, ya que cambia el axis en el que se desplaza el child.

Si una child entity no tiene `posición` en su Transform, el valor predeterminado es `0,0,0`, lo que la dejará posicionada en la misma position que su parent.

Puedes usar una entity invisible sin un shape component como parent para envolver un conjunto de otras entities. Esta entity no será visible en la scene renderizada, pero puede usarse para agrupar a sus children y aplicar un transform a todas ellas.

{% hint style="warning" %}
**📔 Nota**: Evita crear un bucle en la jerarquía, donde una entity termina siendo su propio ancestro. El SDK detecta estos bucles y registra una advertencia nombrando a las entities involucradas. Las entities afectadas no se posicionan correctamente hasta que corrijas la relación parent.
{% endhint %}

## Adjuntar un Entity a un Avatar

Hay tres métodos para adjuntar una entity al player:

* Hazla child del **Avatar Entity**
* Hazla child del **Camera Entity**
* Usa el **component AvatarAttach**

La forma más simple de adjuntar una entity al avatar es establecer el parent como la [reserved entity](/creator/content-creator-es/scenes-sdk7/arquitectura/entities-components.md#reserved-entities) `engine.PlayerEntity`. La entity entonces se moverá junto con la position del player.

```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,
})
```

También puedes establecer una entity para la [reserved entity](/creator/content-creator-es/scenes-sdk7/arquitectura/entities-components.md#reserved-entities) `engine.CameraEntity`. Al usar la camera entity en primera persona, la entity adjunta seguirá los movimientos de la camera. Esto es ideal para mantener algo siempre a la vista, por ejemplo para mantener el modelo 3D de la arma siempre a la vista, incluso cuando la camera apunta hacia arriba.

```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 adjuntar un objeto a uno de los bones del avatar y hacer que se mueva junto con las animations del avatar, añade un `AvatarAttach` component a la entity.

Puedes elegir diferentes anchor points en el avatar; la mayoría de estos puntos están vinculados a la armature del player y siguen las animations del player. Por ejemplo, al usar el anchor point de la right hand, la entity adjunta se moverá cuando el avatar salude o balancee sus brazos mientras corre, como si el player estuviera sosteniendo la entity en su hand.

```ts
// Adjuntar al player principal; si avatarId no está configurado, engine.PlayerEntity se usa de forma predeterminada
AvatarAttach.create(myEntity, {
	anchorPointId: AvatarAnchorPointType.AAPT_NAME_TAG,
})

// Adjuntar a un player por ID
AvatarAttach.create(myEntity, {
	avatarId: '0xAAAAAAAAAAAAAAAAA',
	anchorPointId: AvatarAnchorPointType.AAPT_NAME_TAG,
})
```

Al crear un `AvatarAttach` component, pasa un objeto con los siguientes datos:

* `avatarId`: *Opcional* El ID del player al que adjuntar. Es el mismo que la dirección Ethereum del player, para aquellos players conectados con un wallet Ethereum. Si no se especifica, adjunta la entity al avatar del player local.
* `anchorPointId`: Qué anchor point del esqueleto del avatar usar para adjuntar la entity, usando un valor del enum `AvatarAnchorPointType`.

{% hint style="warning" %}
**📔 Nota**: Si quieres que todos los players de la scene vean un objeto adjunto al mismo player, por ejemplo que todos vean que Player A recogió un objeto y lo sostiene en su left hand, entonces debes proporcionar un valor a `avatarId`. Si no se especifica, todos los players verán el objeto adjunto a sus propios avatars.
{% endhint %}

El siguiente ejemplo coloca una entity adjunta a un avatar particular, para que todos los demás players la vean adjunta a ese mismo avatar.

```ts
import { getPlayer } from '@dcl/sdk/src/players'
import { AvatarAnchorPointType, AvatarAttach, engine, Entity } de '@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,
  })

  // Otros components

  syncEntity(entity, [AvatarAttach.componentId])

}
```

Los siguientes anchor points están disponibles en el `AvatarAnchorPointType` enum:

* `AAPT_RIGHT_HAND`: Fijo en la right hand del player
* `AAPT_LEFT_HAND`: Fijo en la left hand del player
* `AAPT_HEAD`: Fijo al centro de la cabeza del player.
* `AAPT_NECK`: Fijo a la base del cuello del player.
* `AAPT_SPINE`: Fijo a la sección superior de la columna vertebral.
* `AAPT_SPINE1`: Fijo a la sección media de la columna vertebral.
* `AAPT_SPINE2`: Fijo a la sección inferior de la columna vertebral.
* `AAPT_HIP`: Fijo al hueso de la cadera.
* `AAPT_LEFT_SHOULDER`: Fijo al hombro izquierdo.
* `AAPT_LEFT_ARM`: Fijo al primer hueso del brazo izquierdo, a la altura del hombro.
* `AAPT_LEFT_FOREARM`: Fijo al hueso del antebrazo izquierdo.
* `AAPT_LEFT_HAND_INDEX`: Fijo a la punta del dedo índice izquierdo.
* `AAPT_RIGHT_SHOULDER`: Fijo al hombro derecho.
* `AAPT_RIGHT_ARM`: Fijo al primer hueso del brazo derecho, a la altura del hombro.
* `AAPT_RIGHT_FOREARM`: Fijo al hueso del antebrazo derecho.
* `AAPT_RIGHT_HAND_INDEX`: Fijo a la punta del dedo índice derecho.
* `AAPT_LEFT_UP_LEG`: Fijo al hueso superior de la pierna izquierda.
* `AAPT_LEFT_LEG`: Fijo al hueso inferior de la pierna izquierda.
* `AAPT_LEFT_FOOT`: Fijo al tobillo de la pierna izquierda.
* `AAPT_LEFT_TOE_BASE`: Fijo a la punta del dedo del pie de la pierna izquierda.
* `AAPT_RIGHT_UP_LEG`: Fijo al hueso superior de la pierna derecha.
* `AAPT_RIGHT_LEG`: Fijo al hueso inferior de la pierna derecha.
* `AAPT_RIGHT_FOOT`: Fijo al tobillo de la pierna derecha.
* `AAPT_RIGHT_TOE_BASE`: Fijo a la punta del dedo del pie de la pierna derecha.
* `.AAPT_NAME_TAG`: Flota justo encima de la name tag del player, y no se ve afectado por las animations del player.

  > Nota: La altura de la etiqueta de nombre se ajusta dinámicamente según la altura de los wearables que lleva puestos el jugador. Así, un jugador que lleve un sombrero alto tendrá su etiqueta de nombre un poco más alta que la de los demás.
* `AAPT_POSITION` *OBSOLETO*: La posición general del jugador. Esto aparece a una altura de 0.8 por encima de los pies del jugador.

  >

{% hint style="warning" %}
\> \*\*📔 Nota\*\*: \`AAPT\_POSITION\` está obsoleto. Para seguir la posición general del jugador, lo mejor es hacer que el Entity sea hijo del Avatar Entity. Consulta el inicio de esta sección para ver un ejemplo. >
{% endhint %}

{% hint style="info" %}
**💡 Consejo**: Para usar estos valores, escribe `AvatarAnchorPointType.` y VS Code mostrará la lista completa de opciones en un desplegable.
{% endhint %}

![](https://1216664193-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)

El renderizado del Entity se determina localmente en cada instancia de la escena. Adjuntar un Entity a un jugador no lo hace visible para otros jugadores que estén viendo a ese jugador. Si un Entity se adjunta al jugador local predeterminado, cada jugador experimentará el Entity como adjunto a su propio avatar.

{% hint style="warning" %}
**📔 Nota**: Los Entities adjuntos a un avatar deben permanecer dentro de los límites de la escena para ser renderizados. Si un jugador sale de tu escena, cualquier Entity adjunto deja de renderizarse hasta que el jugador vuelva a entrar. Los smart wearables no tienen esta limitación.
{% endhint %}

El `AvatarAttach` component sobrescribe los valores del `Transform` component. Cualquier valor que pongas en el `Transform` component se reemplaza por la posición relativa del Entity respecto al Transform del jugador; estos valores se actualizan fotograma a fotograma a medida que el jugador se mueve y se anima.

Si necesitas posicionar un Entity con un desplazamiento desde el punto de anclaje en el avatar, o con una rotación o escala diferente, hazlo mediante un Entity padre.

1. Crea un Entity invisible con solo un `Transform` y un `AvatarAttach` component. Su `Transform` valor será sobrescrito a medida que el jugador se mueva
2. Establece el Entity que quieres adjuntar como hijo de este padre. Sus `Transform` valores pueden describir el desplazamiento desde el punto de anclaje.

```ts
// Crear Entity padre
const parentEntity = engine.addEntity()

// Adjuntar Entity padre al jugador
AvatarAttach.create(parentEntity, {
	anchorPointId: AvatarAnchorPointType.AAPT_NAME_TAG,
})

// Crear Entity hijo
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" %}
**📔 Nota**: Si el Entity adjunto tiene colliders, estos colliders podrían bloquear el movimiento del jugador o causar efectos temblorosos. Puede que quieras desactivar la physics layer de los colliders del Entity adjunto. Consulta [capas de colisión](/creator/content-creator-es/scenes-sdk7/fundamentos-del-contenido-3d/colliders.md#collision-layers)
{% endhint %}

{% hint style="warning" %}
**📔 Nota**: Si tienes un Entity hijo y quieres conocer su Position y/o Rotation global, puedes usar las `getWorldPosition` y `getWorldRotation` functions. Puedes comprobarlas en [Getting Global Position and Rotation](#getting-global-position-and-rotation-of-an-entity) sección.
{% endhint %}

### Adjuntar a otros jugadores

Puedes usar la `AvatarAttach` component para adjuntar un Entity a otro jugador. Para hacerlo, debes conocer el id del jugador.

Para adjuntar un Entity al avatar de otro jugador, debes proporcionar el ID del usuario en el campo `avatarId`. Hay [varias formas](/creator/content-creator-es/scenes-sdk7/interactividad/user-data.md#get-player-data) de obtener estos datos.

{% hint style="warning" %}
**📔 Nota**: Para aquellos jugadores conectados con un wallet de Ethereum, su `userId` es la misma que su dirección de Ethereum.
{% endhint %}

Obtén el `userId` de todos los demás jugadores cercanos mediante `getPlayer()`

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

Usándolo junto con `AvatarAttach`, podrías usar el siguiente código para añadir un cubo flotando sobre la cabeza de cada otro jugador en la escena:

```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,
            })
        }
    })
```

Consulta otras formas de obtener los ID de otros usuarios en [Obtener datos del jugador](/creator/content-creator-es/scenes-sdk7/interactividad/user-data.md#get-player-data).

## Límites de la escena

Todos los Entities en tu escena deben caber dentro de los límites de la escena, ya que lo que está fuera de esos límites son parcelas de terreno que pertenecen a otros jugadores.

Si alguna parte de tus modelos se extiende más allá de estos límites al ejecutar una preview, esas partes que sobresalgan se recortarán y no se renderizarán, tanto al ejecutar una preview como en la escena publicada.

La posición de los Entities en tu escena se comprueba constantemente a medida que se mueven; si un Entity sale de la escena y luego vuelve, se eliminará y luego se volverá a renderizar normalmente.

Una cuadrícula en el suelo de la escena muestra los límites de la escena, que de forma predeterminada van de 0 a 16 en el *x* y *z* eje, y hasta 20 en el *y* eje. Eres libre de colocar Entities bajo tierra, por debajo de 0 en el *y* eje.

{% hint style="info" %}
**💡 Consejo**: Si tu escena necesita más parcelas, puedes añadirlas en el `scene.json` archivo del proyecto. Consulta [Metadatos de la scene](/creator/content-creator-es/scenes-sdk7/tipos-de-proyectos/scene-metadata.md) para obtener instrucciones. Una vez añadidas, deberías ver que la cuadrícula se extiende para cubrir las parcelas adicionales.
{% 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-es/scenes-sdk7/fundamentos-del-contenido-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.
