> 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/escenas-sdk7/interactividad/player-avatar.md).

# Avatar del jugador

Hay varias formas de controlar el avatar del jugador y cambiar la experiencia de juego para tus jugadores.

Para tratar con avatares que no son jugadores, consulta [Avatares NPC](/creator/content-creator-es/escenas-sdk7/interactividad/npc-avatars.md).

## Mover al jugador

{% hint style="info" %}
**💡 Consejo**: La forma más fácil de mover al jugador es usar el [Scene Editor en Creator Hub](/creator/content-creator-es/scene-editor/comenzar/about-editor.md). Usa la opción sin código **Mover al jugador** o la **Mover al jugador aquí** Acciones, consulta [Haz inteligente cualquier ítem](/creator/content-creator-es/scene-editor/interactividad/make-any-item-smart.md).
{% endhint %}

Para cambiar la posición del jugador en la escena, usa la `movePlayerTo()` función. Esta función toma un objeto con tres propiedades:

* `newRelativePosition`: Dónde colocar al jugador, expresado como un Vector3.
* `cameraTarget`: (opcional) La dirección hacia la que hacer que mire la cámara, expresada como un Vector3 que representa las coordenadas de un punto en el espacio al que mirar. Si no se proporciona ningún valor, la cámara mantendrá la misma rotación que antes de moverse.
* `avatarTarget`: (opcional) La dirección hacia la que hacer que mire el avatar, expresada como un Vector3 que representa las coordenadas de un punto en el espacio al que mirar. Si no se proporciona ningún valor, el avatar mantendrá la misma rotación que antes de moverse. Si el jugador está en modo de cámara en primera persona, la rotación de la cámara y del avatar es la misma.
* `duration`: (opcional) Cuánto tiempo debe durar la transición, en segundos. Si no se proporciona ningún valor, la transición ocurrirá instantáneamente. Si se proporciona una duration, el avatar caminará o correrá hasta esta nueva posición.

{% hint style="warning" %}
**📔 Nota**: Durante la transición, el avatar no se ve afectado por los colliders, así que puede atravesar objetos.
{% endhint %}

```ts
import { movePlayerTo } from '~system/RestrictedActions'

// crear entity
const myEntity = engine.addEntity()
MeshRenderer.setBox(myEntity)
MeshCollider.setBox(myEntity)

Transform.create(myEntity, {
	position: { x: 4, y: 1, z: 4 },
})

// dar comportamiento a la entity
pointerEventsSystem.onPointerDown(
	{
		entity: myEntity,
		opts: { button: InputAction.IA_POINTER, hoverText: 'Clic' },
	},
	function () {
		// reaparecer al jugador
		movePlayerTo({
			newRelativePosition: Vector3.create(1, 0, 1),
			cameraTarget: Vector3.create(8, 1, 8),
			avatarTarget: Vector3.create(8, 1, 8),
		})
	}
)
```

El movimiento del jugador ocurre al instante, sin pantallas de confirmación ni transiciones de cámara.

{% hint style="warning" %}
**📔 Nota**: Los jugadores solo se pueden mover si ya están dentro de los límites de la escena, y solo se los puede mover a lugares que estén dentro de los límites de la escena. No puedes usar `movePlayerTo()` para transportar a un jugador a otra escena. Para mover a un jugador a otra escena, consulta [Teleports](/creator/content-creator-es/escenas-sdk7/interactividad/external-links.md#teleports).
{% endhint %}

La `movePlayerTo()` función admite await, así que si el movimiento tiene una duración, puedes usar `await` para esperar a que el jugador llegue a su destino.

```ts
import { movePlayerTo } from '~system/RestrictedActions'

pointerEventsSystem.onPointerDown(
	{
		entity: myEntity,
		opts: { button: InputAction.IA_POINTER, hoverText: 'Clic' },
	},
	async function () {
		await movePlayerTo({
			newRelativePosition: Vector3.create(1, 0, 1),
			cameraTarget: Vector3.create(8, 1, 8),
			avatarTarget: Vector3.create(8, 1, 8),
			duration: 2,
		})
	}
)
```

Si el jugador intenta moverse durante la duración de su transición, la transición se interrumpirá y la `movePlayerTo` función nunca se resolverá. Puedes evitar este comportamiento deshabilitando todas las inputs mientras la transición está en progreso usando el `InputModifier` component, consulta [Restringir la locomotion](#restrict-locomotion).

```ts
import { movePlayerTo } from '~system/RestrictedActions'
import {InputModifier, engine} from '@dcl/sdk/ecs'

pointerEventsSystem.onPointerDown(
	{
		entity: myEntity,
		opts: { button: InputAction.IA_POINTER, hoverText: 'Clic' },
	},
	async function () {

		// deshabilitar todas las inputs
		InputModifier.create(engine.PlayerEntity, {
			mode: InputModifier.Mode.Standard({
				disableAll: true,
			}),
		})

		// mover al jugador
		await movePlayerTo({
			newRelativePosition: Vector3.create(1, 0, 1),
			cameraTarget: Vector3.create(8, 1, 8),
			avatarTarget: Vector3.create(8, 1, 8),
			duration: 2,
		})

		// habilitar todas las inputs
		InputModifier.deleteFrom(engine.PlayerEntity)
	}
)
```

{% hint style="warning" %}
**📔 Nota**: Además, el resultado del await se puede almacenar para evaluar su `success` propiedad para saber si el movimiento fue interrumpido (por ejemplo, por movimiento de input) o completado con éxito.
{% endhint %}

## Reproducir animaciones

Puedes hacer que el jugador realice una animación como parte del código de la escena. Esto puede ayudar a proporcionar más inmersión, y también puede ayudar a comunicar lo que están haciendo otros jugadores entre sí. Las animaciones del avatar se ven tanto por el jugador (en vista en tercera persona) como por cualquier otro jugador cercano.

Las animaciones controladas por el jugador que se ejecutan en todo el cuerpo son reemplazadas por las animaciones de locomotion predeterminadas, como caminar y saltar. Por eso, las animaciones de cuerpo completo reproducidas por la escena solo se reproducen mientras el jugador está quieto. Si el jugador camina o salta, cualquier animación de cuerpo completo se interrumpe. Las animaciones de la parte superior del cuerpo no se interrumpen por el movimiento.

{% hint style="warning" %}
**📔 Nota**: Los jugadores solo se pueden animar si ya están dentro de los límites de la escena, no si están en una escena vecina. Los Smart wearables pueden reproducir animaciones en cualquier lugar.

Mientras un jugador está realizando una animación, no se ve afectado por collisions, y sus movimientos no están limitados por la física de la escena. Además, ten en cuenta que si una animación desplaza al jugador desde su posición original (por ejemplo, si la animación incluye un salto), el component Transform del jugador no se verá afectado por este desplazamiento.
{% endhint %}

### Usa el Scene Editor

La forma más fácil de hacer que un jugador realice una animación es usar el Scene Editor. Usa la opción sin código **Reproducir Emote** para reproducir una animación predeterminada, o la **Reproducir Custom Emote** para reproducir una animación desde un archivo. Consulta [Haz inteligente cualquier ítem](/creator/content-creator-es/scene-editor/interactividad/make-any-item-smart.md).

### Animaciones predeterminadas

Usa la `triggerEmote()` función para ejecutar una de las animaciones predeterminadas que los jugadores pueden reproducir en cualquier parte de Decentraland. Esta función toma como argumento un objeto con las siguientes propiedades:

* `predefinedEmote`: Un string con el nombre de un emote existente.
* `mask`: (opcional) Reproducir la animación solo en una parte del cuerpo del avatar, usando un valor del `AvatarMask` enum. Por ejemplo, `AvatarMask.AM_UPPER_BODY` anima solo la parte superior del cuerpo del avatar. Consulta [Animar solo la parte superior del cuerpo](#animate-only-the-upper-body).

```ts
import { triggerEmote } from '~system/RestrictedActions'

const emoter = engine.addEntity()
Transform.create(emoter, { position: Vector3.create(8, 0, 8) })
MeshRenderer.setBox(emoter)
MeshCollider.setBox(emoter)
pointerEventsSystem.onPointerDown(
	{
		entity: emoter,
		opts: { button: InputAction.IA_POINTER, hoverText: 'Bailar' },
	},
	() => {
		triggerEmote({ predefinedEmote: 'robot' })
	}
)
```

Los siguientes emotes muestran retroalimentación sobre las acciones del jugador en tu escena; todos estos son valores válidos para el `predefinedEmote` field:

* `buttonDown`
* `buttonFront`
* `getHit`
* `knockOut`
* `lever`
* `openChest`
* `openDoor`
* `punch`
* `push`
* `swingWeaponOneHand`
* `swingWeaponTwoHands`
* `throw`
* `sittingChair1`
* `sittingChair2`
* `sittingGround1`
* `sittingGround2`

Estos emotes están disponibles para todos los jugadores en su rueda de emotes predeterminada, y también pueden usarse en cualquier escena.

* `wave`
* `fistpump`
* `robot`
* `raiseHand`
* `clap`
* `money`
* `kiss`
* `tik`
* `hammer`
* `tektonik`
* `dontsee`
* `handsair`
* `shrug`
* `disco`
* `dab`
* `headexplode`

{% hint style="info" %}
**💡 Consejo**: Si un jugador camina o salta mientras reproduce la animación, la interrumpirá. Si no quieres que eso sea posible, puedes congelar el avatar con [Input Modifiers](#freeze-the-player) durante la duración de la animación del avatar.
{% endhint %}

### Animaciones personalizadas

Usa la `triggerSceneEmote()` para hacer que el jugador realice una animación personalizada, almacenada como un archivo .glb como parte del asset de la escena.

{% hint style="warning" %}
**📔 Nota**: El nombre del archivo **debe** terminar en `_emote.glb` para funcionar como una animación del avatar.
{% endhint %}

Esta función toma un objeto con las siguientes propiedades:

* `src`: Un string con la ruta al archivo de emote.
* `loop`: Si es true, la animación se repetirá continuamente hasta que el jugador se mueva o la animación se detenga. False por defecto.
* `mask`: (opcional) Reproducir la animación solo en una parte del cuerpo del avatar, usando un valor del `AvatarMask` enum. Por ejemplo, `AvatarMask.AM_UPPER_BODY` anima solo la parte superior del cuerpo del avatar. Consulta [Animar solo la parte superior del cuerpo](#animate-only-the-upper-body).

```ts
import { triggerSceneEmote } from '~system/RestrictedActions'
import { AvatarMask } from '@dcl/sdk/ecs'

const emoter = engine.addEntity()
Transform.create(emoter, { position: Vector3.create(8, 0, 8) })
MeshRenderer.setBox(emoter)
MeshCollider.setBox(emoter)
pointerEventsSystem.onPointerDown(
	{
		entity: emoter,
		opts: { button: InputAction.IA_POINTER, hoverText: 'Hacer bola de nieve' },
	},
	() => {
		triggerSceneEmote({ src: 'animations/Snowball_Throw_emote.glb', loop: false, mask: AvatarMask.AM_UPPER_BODY })
	}
)
```

{% hint style="info" %}
**💡 Consejo**: Si un jugador camina o salta mientras reproduce la animación, la interrumpirá. Si no quieres que eso sea posible, puedes congelar el avatar con [Input Modifiers](#freeze-the-player) durante la duración de la animación del avatar.
{% endhint %}

### Animar solo la parte superior del cuerpo

Ambos `triggerEmote()` y `triggerSceneEmote()` aceptan una `mask` propiedad opcional, que limita la animación solo a una parte del cuerpo del avatar.

Normalmente, una animación se detiene en cuanto el jugador camina o salta, porque las animaciones de locomotion predeterminadas toman control de todo el cuerpo. Cuando estableces `mask` a `AvatarMask.AM_UPPER_BODY`, la animación solo controla al avatar desde la cintura hacia arriba, y las piernas siguen controladas por las animaciones de locomotion predeterminadas. Esto significa que el jugador puede seguir caminando o corriendo por la escena mientras la parte superior del cuerpo reproduce tu animación. Usa esto para acciones que no deberían interrumpir el movimiento, como llevar una caja, sostener una antorcha o hacer malabares.

```ts
import { triggerSceneEmote } from '~system/RestrictedActions'
import {
	engine,
	AvatarMask,
	InputAction,
	MeshCollider,
	MeshRenderer,
	pointerEventsSystem,
	Transform,
} from '@dcl/sdk/ecs'
import { Vector3 } from '@dcl/sdk/math'

const cheerButton = engine.addEntity()
Transform.create(cheerButton, { position: Vector3.create(8, 0, 8) })
MeshRenderer.setBox(cheerButton)
MeshCollider.setBox(cheerButton)
pointerEventsSystem.onPointerDown(
	{
		entity: cheerButton,
		opts: { button: InputAction.IA_POINTER, hoverText: 'Celebrar' },
	},
	() => {
		triggerSceneEmote({
			src: 'animations/Cheer_emote.glb',
			loop: true,
			mask: AvatarMask.AM_UPPER_BODY,
		})
	}
)
```

En este ejemplo, el jugador hace clic en un botón y empieza a celebrar con los brazos en alto, en una animación en bucle. Como solo se anima la parte superior del cuerpo, puede seguir corriendo por la escena mientras celebra, por ejemplo para seguir la acción en una carrera o un partido de fútbol.

Algunas cosas a tener en cuenta:

* `AvatarMask.AM_UPPER_BODY` es actualmente el único valor en el `AvatarMask` enum. Para reproducir una animación en todo el cuerpo, simplemente no establezcas la `mask` propiedad.
* La `loop` propiedad se comporta igual que con las animaciones de cuerpo completo: con `loop: false` la animación enmascarada se reproduce una vez y luego la parte superior del cuerpo vuelve a la locomotion normal, con `loop: true` se repite hasta detenerse.
* Para detener desde el código una animación enmascarada en bucle, llama a `stopEmote({})`, también importado de `~system/RestrictedActions`.

### Detectar cuándo termina un emote

Cada evento del ciclo de vida del emote se informa a través del `AvatarEmoteCommand` component en la entity del jugador. Cada nueva entrada lleva un `state` field, con un valor del `EmoteState` enum:

* `EmoteState.ES_STARTED`: El emote comenzó a reproducirse. Este es también el valor informado cuando el `state` field está ausente (entradas escritas por clientes más antiguos).
* `EmoteState.ES_FINISHED`: Un emote sin bucle se reprodujo hasta su final natural.
* `EmoteState.ES_INTERRUPTED`: El emote se interrumpió antes de tiempo: el jugador se movió o saltó, se teletransportó, comenzó otro emote, el emote se detuvo explícitamente o el jugador abandonó la escena.

Esto funciona para emotes activados por la escena (`triggerEmote()` y `triggerSceneEmote()`) así como para emotes que el jugador reproduce por sí mismo a través de la rueda de emotes, y también para emotes reproducidos por otros jugadores en la escena.

Usa la `onChange` función en el `AvatarEmoteCommand` component para reaccionar ante cada nueva entrada:

```ts
import { AvatarEmoteCommand, EmoteState } from '@dcl/sdk/ecs'

export function main() {
	AvatarEmoteCommand.onChange(engine.PlayerEntity, (emote) => {
		if (!emote) return

		switch (emote.state ?? EmoteState.ES_STARTED) {
			case EmoteState.ES_STARTED:
				console.log('emote iniciado: ', emote.emoteUrn)
				break
			case EmoteState.ES_FINISHED:
				console.log('emote finalizado de forma natural: ', emote.emoteUrn)
				break
			case EmoteState.ES_INTERRUPTED:
				console.log('el emote fue interrumpido: ', emote.emoteUrn)
				break
		}
	})
}
```

{% hint style="warning" %}
**📔 Nota**: Esta función solo es compatible con el cliente Desktop. Los emotes reproducidos con un `mask` (emotes de cuerpo parcial) en el jugador local actualmente no informan eventos del ciclo de vida.
{% endhint %}

## Restringir la locomotion

Puedes restringir qué acciones puede realizar el jugador en tu escena. Usa esto para congelar al jugador o para restringir formas específicas de locomotion, por ejemplo para impedir que el jugador salte o corra.

### Congelar al jugador

Puedes congelar al jugador para que ninguna de las teclas de input pueda mover el avatar. Esto puede ser útil para muchas mecánicas de juego. También es una buena práctica congelar a un jugador mientras realiza una animación importante que no debería interrumpirse por el movimiento, o mientras una [Virtual Camera](/creator/content-creator-es/escenas-sdk7/fundamentos-del-contenido-3d/camera.md) apunta lejos del avatar y no quieres que el jugador se mueva a ciegas.

Usa la `InputModifier` component en la `engine.PlayerEntity` para evitar que los inputs del jugador afecten la locomotion del avatar. El avatar permanecerá quieto, y el jugador solo podrá girar la cámara.

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

InputModifier.create(engine.PlayerEntity, {
	mode: InputModifier.Mode.Standard({
		disableAll: true,
	}),
})
```

Ten en cuenta las siguientes consideraciones:

* Mientras las interacciones del jugador están deshabilitadas, su avatar sigue viéndose afectado por fuerzas externas, como la gravedad o las plataformas móviles.
* La `InputModifier` component solo se puede usar con la `engine.PlayerEntity` entity. Solo puede afectar al jugador actual; no puede afectar a otros jugadores.
* Este component solo afecta al jugador mientras el avatar esté dentro de los límites de tu escena. Su locomotion deja de estar restringida en cuanto sale de la escena.
* Mientras las interacciones del jugador están deshabilitadas, el jugador no puede realizar emotes libremente, pero la escena puede activar animaciones en el avatar.
* Los inputs del jugador no afectan al avatar, pero los [eventos globales de input](/creator/content-creator-es/escenas-sdk7/interactividad/eventos-de-boton/system-based-events.md#global-input-events) todavía pueden ser escuchados por la escena. Podrías usarlos para controlar un vehículo, o usar un [Virtual Camera](/creator/content-creator-es/escenas-sdk7/fundamentos-del-contenido-3d/camera.md) para seguir a otra entity mientras se mueve, tratándola como un avatar alternativo.

### Restringir tipos específicos de locomotion

En lugar de congelar por completo al jugador, puedes restringir ciertas formas específicas de locomotion del jugador. Esto podría usarse por razones de gameplay, por ejemplo para preservar la dificultad de un juego de plataformas evitando el doble salto y el planeo. Estas habilidades incluso podrían activarse o desactivarse dinámicamente como mecánica de juego, por ejemplo dando al jugador una barra de resistencia y evitando que corra cuando se agote. También podría usarse para establecer el tono de una escena, por ejemplo impidiendo correr o saltar en un lugar que pretende ser sereno. El `InputModifier` incluye las siguientes opciones:

* `disableWalk`: El jugador no puede caminar despacio (presionando control). Si el jugador intenta caminar, trotará o correrá en su lugar, si se permite.
* `disableRun`: El jugador no puede correr (presionando shift). Si el jugador intenta correr, trotará en su lugar, si se permite.
* `disableJog`: El jugador no puede trotar (esta es la velocidad de movimiento predeterminada). Si el jugador intenta trotar, correrá o caminará en su lugar, si se permite.
* `disableJump`: El jugador no puede saltar.
* `disableEmote`: El jugador no puede realizar emotes voluntariamente. La escena puede activar animaciones en el avatar del jugador.
* `disableDoubleJump`: El jugador no puede realizar un doble salto.
* `disableGliding`: El jugador no puede planear.

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

InputModifier.create(engine.PlayerEntity, {
	mode: InputModifier.Mode.Standard({
		disableAll: false,
		disableWalk: false,
		disableRun: true,
		disableJog: true,
		disableJump: true,
		disableEmote: true,
		disableDoubleJump: true,
		disableGliding: true
	}),
})
```

### Sintaxis avanzada

Para usar el component sin ningún helper, puedes usar la siguiente sintaxis:

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

InputModifier.createOrReplace(engine.PlayerEntity, {
	mode: {
		$case: 'standard',
		standard: {
			disableAll: false,
			disableWalk: false,
			disableRun: true,
			disableJog: true,
			disableJump: true,
			disableEmote: true,
		},
	},
})
```

## Configuración de locomotion

Puedes afectar la locomotion del jugador, como su velocidad de carrera, altura de salto y más. Esto puede modificarse dinámicamente, por ejemplo para permitir que un jugador obtenga un aumento temporal de velocidad al interactuar con un ítem, o para deshabilitar la capacidad de saltar del jugador durante un breve período de tiempo.

Para hacer esto, añade un `AvatarLocomotionSettings` component a la `engine.PlayerEntity`.

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

AvatarLocomotionSettings.create(engine.PlayerEntity, {
	runSpeed: 10,
	jumpHeight: 2,
})
```

Las siguientes propiedades están disponibles:

* `walkSpeed`: La velocidad a la que camina el jugador, en metros por segundo. En el cliente desktop, los jugadores caminan presionando la tecla control.
* `jogSpeed`: La velocidad a la que trota el jugador, en metros por segundo. Esta es la forma predeterminada en que se mueve el jugador.
* `runSpeed`: La velocidad a la que corre el jugador, en metros por segundo. En el cliente desktop, los jugadores corren presionando la tecla shift.
* `jumpHeight`: La altura a la que salta el jugador, en metros.
* `runJumpHeight`: La altura a la que salta el jugador después de correr, en metros.
* `doubleJumpHeight`: La altura del segundo salto al hacer doble salto, en metros.
* `glidingSpeed`: La velocidad horizontal a la que se mueve el jugador mientras planea, en metros por segundo.
* `glidingFallingSpeed`: La velocidad máxima de caída del jugador mientras planea, en metros por segundo. Esto solo limita el descenso del jugador: el movimiento hacia arriba, como el impulso de una fuerza continua de la scene, no está limitado.
* `hardLandingCooldown`: El tiempo de espera después de un aterrizaje fuerte, en segundos. Es el tiempo que el jugador debe esperar antes de poder moverse de nuevo después de aterrizar tras una caída alta.

Como referencia, estos son los valores predeterminados de esas propiedades:

* `walkSpeed`: 1.5 m/s
* `jogSpeed`: 8 m/s
* `runSpeed`: 10 m/s
* `glidingSpeed`: 6 m/s
* `glidingFallingSpeed`: 1 m/s
* `jumpHeight`: 1 m
* `runJumpHeight`: 1.5 m
* `doubleJumpHeight`: 2 m
* `hardLandingCooldown`: 0.75 s

{% hint style="info" %}
**💡 Consejo**: Mientras planea, las fuerzas continuas aplicadas por la scene son 1.5 veces más fuertes, y las fuerzas hacia arriba pueden levantar al jugador. Consulta [Fuerzas mientras planea](/creator/content-creator-es/escenas-sdk7/interactividad/player-physics.md#forces-while-gliding).
{% endhint %}

{% hint style="info" %}
**💡 Consejo**: Ninguna de estas propiedades puede ser menor que 0. Si estableces una de ellas en un valor negativo, se limitará a 0. Establecer estos valores en cero tendrá el mismo efecto que usar el `InputModifier` para bloquear el uso de ciertas teclas.

Solo puedes afectar la locomoción del jugador si se encuentra dentro de los límites de la scene. Para afectar los avatares de otros jugadores, debes ejecutar el código que afecta su locomoción en su propia instancia.
{% endhint %}

Puedes crear un [smart wearable](/creator/content-creator-es/escenas-sdk7/tipos-de-proyectos/smart-wearables.md) que hace que el jugador siempre corra más rápido o salte más alto. Si la scene y un smart wearable definen valores diferentes para estos parámetros, siempre se usan los valores de la scene.

Para asegurarte de que nadie tenga ventajas injustas en una scene de parkour, puedes imponer los parámetros predeterminados añadiendo explícitamente sus valores predeterminados en tu scene:

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

AvatarLocomotionSettings.create(engine.PlayerEntity, {
	runSpeed: 10,
	walkSpeed: 1.5,
	jogSpeed: 8 ,
	jumpHeight: 1,
	runJumpHeight: 1.5,
	hardLandingCooldown: 0.75
})
```

## Áreas de modificador de Avatar

Los avatares se comportan y se ven de forma coherente en todo Decentraland mientras caminan por las scenes. Sin embargo, puedes añadir un `AvatarModifierArea` a una región de tu scene para afectar el comportamiento de los avatares de los jugadores cuando entren en esa área.

{% hint style="danger" %}
**❗Advertencia**\
Por favor, limita la cantidad de `AvatarModifierAreas` que usas en tu scene a solo un par. Si usas demasiados, puede tener un impacto significativo en el rendimiento.
{% endhint %}

### Colocación de áreas de modificador

Añade una entidad con un `AvatarModifierArea` component y posiciona esta entidad usando un `Transform` component.

```ts
const entity = engine.addEntity()

AvatarModifierArea.create(entity, {
	area: Vector3.create(4, 3, 4),
	modifiers: [AvatarModifierType.AMT_HIDE_AVATARS],
	excludeIds: []
})

Transform.create(entity, {
	position: Vector3.create(8, 0, 8),
})
```

Al crear un `AvatarModifierArea` component, debes proporcionar lo siguiente:

* `area`: Tamaño del área de modificador
* `modifiers`: Un array que enumera los modificadores que se implementarán en el área. Esta propiedad usa valores del `AvatarModifierType` enum.

Los modificadores compatibles son:

* `AvatarModifierType.AMT_HIDE_AVATARS`
* `AvatarModifierType.AMT_DISABLE_PASSPORTS`
* `AvatarModifierType.AMT_HIDE_NAMETAGS`

Todos los efectos de un `AvatarModifierArea` solo tienen lugar dentro de la región de su área. Los jugadores vuelven a la normalidad cuando salen del área.

Un `AvatarModifierArea` afecta solo a los jugadores que están dentro del área. Entrar en el área no afecta a cómo se percibe a otros jugadores fuera del área.

Los efectos de un `AvatarModifierArea` se calculan localmente para cada jugador. Puedes tener un `AvatarModifierArea` que solo esté presente en la scene para algunos jugadores y no para otros. Por ejemplo, podrías hacer un juego de "marco polo", donde solo un jugador en la scene tenga un área de modificador que oculte a todos los demás jugadores. Todos los demás jugadores que no tengan esta área de modificador en su versión local de la scene pueden verse entre sí con normalidad.

Si el área oculta avatares, entonces los jugadores que no tengan el área en su versión local de la scene verán todos los avatares con normalidad, incluso aquellos que se perciban a sí mismos como ocultos. Los jugadores que sí tengan el área se percibirán a sí mismos y a todos los demás avatares como afectados por el área cuando entren en ella.

{% hint style="warning" %}
**📔 Nota**: Las áreas de modificador de Avatar están afectadas por la *position* y *rotation* del component Transform de su entidad anfitriona, pero no están afectadas por la *scale*.
{% endhint %}

{% hint style="warning" %}
**📔 Nota**: El `AvatarModifierArea`component debe importarse a través de

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

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

### Ocultar avatares

Cuando un jugador entra en un `AvatarModifierArea` que tiene el `AvatarModifierType.AMT_HIDE_AVATARS` modifier, el avatar del jugador deja de renderizarse. Esto se aplica tanto al jugador en vista en tercera persona como cuando otros jugadores entran en el área.

```ts
const entity = engine.addEntity()

AvatarModifierArea.create(entity, {
	area: Vector3.create(4, 3, 4),
	modifiers: [AvatarModifierType.AMT_HIDE_AVATARS],
	excludeIds: []
})

Transform.create(entity, {
	position: Vector3.create(8, 0, 8),
})
```

Esto te permite reemplazar el avatar predeterminado de Decentraland con cualquier avatar personalizado que quieras mostrar en tu scene. Ten en cuenta que, si quieres ver a otros jugadores con avatares personalizados, debes encargarte tú mismo de la sincronización de las posiciones de los jugadores.

### Desactivar popup de Passport

Cuando un jugador entra en un `AvatarModifierArea` que tiene el `AvatarModifierType.AMT_DISABLE_PASSPORTS` modifier, al hacer clic en ellos ya no se abre la UI de Passport que muestra la biografía del jugador, el inventario, etc.

```ts
const entity = engine.addEntity()

AvatarModifierArea.create(entity, {
	area: Vector3.create(4, 3, 4),
	modifiers: [AvatarModifierType.AMT_DISABLE_PASSPORTS],
	excludeIds: []
})

Transform.create(entity, {
	position: Vector3.create(8, 0, 8),
})
```

Esto es especialmente útil en juegos en los que abrir accidentalmente esta UI podría interrumpir el flujo de un juego, por ejemplo en un juego de disparos multijugador.

### Ocultar etiquetas de nombre

Cuando un jugador entra en un `AvatarModifierArea` que tiene el `AvatarModifierType.AMT_HIDE_NAMETAGS` modifier, la etiqueta de nombre del jugador se oculta mientras el avatar en sí permanece visible.

```ts
const entity = engine.addEntity()

AvatarModifierArea.create(entity, {
	area: Vector3.create(4, 3, 4),
	modifiers: [AvatarModifierType.AMT_HIDE_NAMETAGS],
	excludeIds: []
})

Transform.create(entity, {
	position: Vector3.create(8, 0, 8),
})
```

Esto es útil para escenarios, presentaciones o escenas con guion donde quieras suprimir las etiquetas de nombre de los jugadores sin ocultar los avatares mismos. Por ejemplo, quizá quieras una experiencia visual limpia durante una actuación, donde los avatares sean visibles pero los nombres flotantes no distraigan a los espectadores.

{% hint style="info" %}
**💡 Consejo**: `AMT_HIDE_AVATARS` ya oculta las etiquetas de nombre junto con el avatar, así que no necesitas añadir `AMT_HIDE_NAMETAGS` cuando uses `AMT_HIDE_AVATARS`. Usa `AMT_HIDE_NAMETAGS` solo cuando quieras ocultar las etiquetas de nombre manteniendo visibles los avatares.
{% endhint %}

Puedes combinar `AMT_HIDE_NAMETAGS` con otros modificadores como `AMT_DISABLE_PASSPORTS` en la misma área:

```ts
const entity = engine.addEntity()

AvatarModifierArea.create(entity, {
	area: Vector3.create(4, 3, 4),
	modifiers: [AvatarModifierType.AMT_HIDE_NAMETAGS, AvatarModifierType.AMT_DISABLE_PASSPORTS],
	excludeIds: []
})

Transform.create(entity, {
	position: Vector3.create(8, 0, 8),
})
```

{% hint style="info" %}
**💡 Consejo**: La etiqueta de nombre solo se oculta mientras la cabeza o el torso del jugador estén dentro del área. Si el área es demasiado baja y el jugador hace doble salto por encima, la etiqueta de nombre reaparecerá brevemente. Haz que el área sea lo bastante alta para cubrir el rango de movimiento esperado.
{% endhint %}

### Excluir avatares

Puedes excluir una lista de jugadores para que un área de modificador no los afecte añadiendo sus IDs de jugador a un array en la `excludeIds` property of the modifier area.

Este ejemplo oculta todos los avatares en un área, excepto los de jugadores con IDs específicos. Podrías usarlo, por ejemplo, en un evento en vivo, para mostrar solo a los anfitriones del evento en el escenario y ocultar a cualquier otro jugador que salte al escenario.

```ts
const entity = engine.addEntity()

AvatarModifierArea.create(entity, {
	area: Vector3.create(4, 3, 4),
	modifiers: [AvatarModifierType.AMT_HIDE_AVATARS],
	excludeIds: ['0xx1...', '0xx2...'],
})

Transform.create(entity, {
	position: Vector3.create(8, 0, 8),
})
```

{% hint style="warning" %}
**📔 Nota**: Asegúrate de que todos los IDs de jugador estén escritos en minúsculas. Usa `.toLowerCase()` si es necesario.
{% endhint %}

Las áreas de modificador se ejecutan localmente en la instancia de cada jugador. La lista de IDs excluidos puede ser diferente para cada jugador. En el ejemplo de abajo, cada jugador excluye su propio ID de un modificador que oculta avatares, para que cada uno vea su propio avatar y ningún otro.

```ts
import { getPlayer } from '@dcl/sdk/src/players'

export function main() {
	let userData = getPlayer()
	if (!userData) return

	const entity = engine.addEntity()

	AvatarModifierArea.create(entity, {
		area: Vector3.create(16, 5, 16),
		modifiers: [AvatarModifierType.AMT_HIDE_AVATARS],
		excludeIds: [userData.userId],
	})

	Transform.create(entity, {
		position: Vector3.create(8, 0, 8),
	})
}
```

{% hint style="danger" %}
**❗Advertencia**\
Si la lista de IDs excluidos va a cambiarse periódicamente (por ejemplo, en función de los jugadores que entren o salgan de un área), asegúrate de que la lista se mantenga ordenada. Ejecuta un `.sort()` en el array, para que la lista conserve el mismo orden cada vez que se pase. De este modo, solo se calculan los cambios en la lista. De lo contrario, esto puede tener un impacto significativo en el rendimiento de la scene.

```ts
AvatarModifierArea.create(entity, {
	area: Vector3.create(16, 5, 16),
	modifiers: [AvatarModifierType.AMT_HIDE_AVATARS],
	excludeIds: myAvatarList.sort(),
})
```

{% endhint %}

### Depurar áreas de modificador

Puede ser difícil saber exactamente qué partes de la scene cubren tus áreas de modificador a partir del código. La retroalimentación visual ayuda mucho a confirmar que están bien ubicadas.

Para verificar las posiciones de un `AvatarModifierArea` o de un `CameraModeArea`, dale a la entidad que lo contiene un `MeshRenderer` component con una `box` shape, y establece la escala al mismo tamaño que el `area` del área de modificador.

{% hint style="warning" %}
**📔 Nota**: Las áreas de modificador no están afectadas por la `scale` property of the transform, their size is based on their `area` propiedad.
{% endhint %}

```ts
const entity = engine.addEntity()
const areaSize = Vector3.create(8, 3, 8)

AvatarModifierArea.create(entity, {
	area: areaSize,
	modifiers: [AvatarModifierType.AMT_HIDE_AVATARS],
  	excludeIds: []
})

Transform.create(entity, {
	position: Vector3.create(8, 0, 8),
	scale: areaSize,
})

MeshRenderer.setBox(entity)
Material.setPbrMaterial(entity, {
	albedoColor: Color4.create(0.5, 0.5, 0.5, 0.5),
})
```

Para activar los efectos del área de modificador, la cabeza o el torso del jugador deben entrar en el área. No surtirá efecto si solo los pies del jugador están en el área. Asegúrate de que el jugador no pueda evadir fácilmente el área saltando.

{% hint style="warning" %}
**📔 Nota**: El área completa debería caber dentro de los límites de tu scene.
{% endhint %}

## Cambiar la apariencia de un avatar

No puedes cambiar qué wearables lleva puesto el avatar del jugador, pero sí puedes sustituir el avatar del jugador por un avatar NPC que puedas personalizar completamente.

Consulta [Avatares NPC](/creator/content-creator-es/escenas-sdk7/interactividad/npc-avatars.md) para más detalles.

{% hint style="warning" %}
**📔 Nota**: Para permitir que el jugador tenga control total sobre ese avatar, debes escuchar los eventos de Button para detectar cuándo pulsan un botón y luego activar la animación correspondiente en el avatar NPC. Consulta [Eventos de Button](/creator/content-creator-es/escenas-sdk7/interactividad/eventos-de-boton/system-based-events.md) para más detalles.

La fluidez del control puede no ser perfecta al hacer esto; quizá quieras usarlo solo en casos muy concretos.
{% endhint %}

{% hint style="info" %}
**💡 Consejo**: Para ver ejemplos funcionales de estas APIs, consulta la [`0,1-input-modifier`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/0,1-input-modifier) scene de prueba, que alterna cada `InputModifier` flag de movimiento por separado y muestra un avatar que sigue siendo transportado por una plataforma en movimiento mientras el movimiento está bloqueado; [`9,99-modifier-areas`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/9,99-modifier-areas), que combina `AvatarModifierArea` con elementos mutados en runtime; `excludeIds`y [`10,99-avatar-modifier-hide-nametags`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/10,99-avatar-modifier-hide-nametags), que aísla el `AMT_HIDE_NAMETAGS` modificador.
{% 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 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-es/escenas-sdk7/interactividad/player-avatar.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.
