> 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/interactividad/avatares/avatar-animations.md).

# Animaciones del Avatar

Haz que el Avatar del jugador reproduzca animaciones predeterminadas o personalizadas, y detecta cuándo termina un emote

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

Las animaciones controladas por el jugador que se ejecutan en todo el cuerpo se sustituyen por las animaciones de locomoción predeterminadas, como caminar y saltar. Por eso, las animaciones de cuerpo completo reproducidas por la escena solo se ejecutan 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 pueden ser animados 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 las colisiones, y sus movimientos no están restringidos por la física de la escena. Ten en cuenta también que, si una animación desplaza al jugador de su posición original (por ejemplo, si la animación incluye un salto), el componente 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** acción para reproducir una animación predeterminada, o la **Reproducir emote personalizado** acción para reproducir una animación desde un archivo. Consulta [Convierte cualquier item en smart](/creator/content-creator-es/scene-editor/interactividad/make-any-item-smart.md).

### Animaciones predeterminadas

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

* `predefinedEmote`: Un nombre de cadena para un emote existente.
* `mask`: (opcional) Reproduce 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` campo:

* `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 [Modificadores de entrada](/creator/content-creator-es/scenes-sdk7/interactividad/avatares/locomotion.md#freeze-the-player) durante la duración de la animación del avatar.
{% endhint %}

### Animaciones personalizadas

Usa el `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 **deben** 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`: Una cadena con una 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) Reproduce 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 [Modificadores de entrada](/creator/content-creator-es/scenes-sdk7/interactividad/avatares/locomotion.md#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()` aceptar una `mask` propiedad opcional, que limita la animación a solo una parte del cuerpo del avatar.

Normalmente, una animación se detiene en cuanto el jugador camina o salta, porque las animaciones de locomoción predeterminadas toman el control de todo el cuerpo. Cuando estableces `mask` en `AvatarMask.AM_UPPER_BODY`, la animación solo controla al avatar de la cintura hacia arriba, y las piernas siguen siendo controladas por las animaciones de locomoción 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.
* El `loop` La 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 locomoción normal; con `loop: true` se repite hasta que se detiene.
* Para detener una animación enmascarada en bucle desde el código, llama a `stopEmote({})`, también importado de `~system/RestrictedActions`.

### Detectar cuándo finaliza un emote

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

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

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

Usa el `onChange` función en el `AvatarEmoteCommand` componente para reaccionar a 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('emote fue interrumpido: ', emote.emoteUrn)
				break
		}
	})
}
```

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

{% hint style="info" %}
**💡 Consejo**: Para reproducir animaciones en avatares que no sean jugadores, consulta [Avatares NPC](/creator/content-creator-es/scenes-sdk7/interactividad/avatares/npc-avatars.md#animations).
{% 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/interactividad/avatares/avatar-animations.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.
