> 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/npc-avatars.md).

# Avatares NPC

Muestra y controla el avatar NPC

Muestra un avatar como una Entity en una Scene.

{% hint style="info" %}
**💡 Consejo**: Prueba la [biblioteca NPC Toolkit](https://github.com/decentraland-scenes/dcl-npc-toolkit) para una experiencia más sencilla al trabajar con NPCs, especialmente si necesitas interactuar mediante un árbol de conversación.
{% endhint %}

## Crear un avatar

El siguiente fragmento crea un avatar con wearables y body shape aleatorios, y con el nombre "NPC".

```ts
const myAvatar = engine.addEntity()
AvatarShape.create(myAvatar)

Transform.create(myAvatar, {
	position: Vector3.create(4, 0.25, 5),
})
```

Cuando pasas datos para generar un `AvatarShape`, se requieren los siguientes campos:

* `id`: (obligatorio) Identificador interno del Avatar

También están disponibles los siguientes campos opcionales:

* `name`: Nombre para mostrar sobre la cabeza del Avatar. Valor predeterminado: "NPC". Establécelo en una cadena vacía para no mostrar ningún nombre, lo cual es útil cuando solo quieres un [Etiqueta del Avatar](/creator/content-creator-es/scenes-sdk7/interactividad/avatares/avatar-nametags.md) placa sobre el NPC.
* `bodyShape`: Cadena para definir qué body shape usar. Las opciones válidas son 'urn:decentraland:off-chain:base-avatars:BaseMale' y 'urn:decentraland:off-chain:base-avatars:BaseFemale'.
* `wearables`: Array con una lista de URNs de wearables que el avatar lleva actualmente. Si los wearables entran en conflicto (por ejemplo, si dos de ellos son sombreros), el último de la lista reemplaza al otro.
* `emotes`: Array con una lista de URNs de NFT emotes que el avatar es capaz de reproducir
* `eyeColor`: *Color3* para el color de ojos (cualquier color es válido)
* `skinColor`: *Color3* para el color de piel (cualquier color es válido)
* `hairColor`: *Color3* para el color de cabello (cualquier color es válido)
* `talking`: Si *true*, muestra un conjunto verde de barras junto al nombre, como cuando los jugadores usan voice chat en el mundo.
* <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p><strong>💡 Consejo</strong>: Consulta <a href="/creator/content-creator-es/scenes-sdk7/fundamentos-del-contenido-3d/color-types.md">tipos de color</a> para más detalles sobre cómo establecer colores.</p></div>

{% hint style="warning" %}
**📔 Nota**: La `AvatarShape`el componente debe importarse mediante

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

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

{% hint style="warning" %}
**📔 Nota**: Los campos URN deben seguir el mismo formato usado para [NFTShapes](/creator/content-creator-es/scenes-sdk7/media/display-a-certified-nft.md): `urn:decentraland:<CHAIN>:<CONTRACT_STANDARD>:<CONTRACT_ADDRESS>:<TOKEN_ID>`
{% endhint %}

## Animaciones

Los Avatars reproducen animaciones de inactividad predeterminadas mientras están quietos.

Para reproducir animaciones en el avatar, establece el `expressionTriggerId` string en el nombre de la animación que quieres reproducir.

```ts
const myAvatar = engine.addEntity()
AvatarShape.create(myAvatar, {
	id: '',
	emotes: [],
	wearables: [],
	expressionTriggerId: 'robot',
})

Transform.create(myAvatar, {
	position: Vector3.create(4, 0.25, 5),
})
```

El `expressionTriggerId` campo admite todas las [animaciones predeterminadas](/creator/content-creator-es/scenes-sdk7/interactividad/avatares/avatar-animations.md#default-animations), así como animaciones personalizadas [de un archivo de scene](/creator/content-creator-es/scenes-sdk7/interactividad/avatares/avatar-animations.md#custom-animations), e incluso URNs de emotes que se publican en el marketplace.

### Animaciones en bucle

Las animaciones en un `AvatarShape` se reproducen una sola vez; si quieres que el avatar siga repitiendo una animación, debes crear un System que le indique que reproduzca la animación de nuevo cada par de segundos.

Usa el `expressionTriggerTimestamp` para volver a reproducir el mismo emote. El valor de este campo es un [marca de tiempo de Lamport](https://en.wikipedia.org/wiki/Lamport_timestamp), lo que significa que no es un valor de tiempo, sino más bien un índice que aumenta en 1 por cada repetición del emote.

Así que la primera vez que reproduces un emote, estableces `expressionTriggerTimestamp` en *0*. Para reproducir el emote de nuevo, debes actualizar este valor a 1. Así es como el Engine sabe que esta es una nueva instrucción, y no una instrucción sobre la que ya ha actuado.

El siguiente fragmento crea un System que ejecuta el mismo emote cada 2 segundos:

```ts
const myAvatar = engine.addEntity()
AvatarShape.create(myAvatar, {
	id: '',
	emotes: [],
	wearables: [],
	expressionTriggerId: 'clap',
    expressionTriggerTimestamp: 0
})

Transform.create(myAvatar, {
	position: Vector3.create(4, 0.25, 5),
})

let clapTimer = 0
let emoteDuration = 2  // 2 segundos

// system
engine.addSystem((dt: number) => {
    clapTimer += dt
      
    if (clapTimer >= emoteDuration) {
        // Trigger the clap emote
        AvatarShape.getMutable(myAvatar).expressionTriggerTimestamp += 1
        
        clapTimer = 0 // Reiniciar el temporizador
    }
})
```

{% hint style="info" %}
**💡 Consejo**: Debes conocer la duración del emote y hacer que esa sea la duración del System. Si creas un emote que deja al avatar quieto en la misma pose, es recomendable hacer que la duración del emote sea más larga que la del System. De ese modo, puedes asegurarte de que no haya artefactos al finalizar y reiniciar la animación.
{% endhint %}

## Añade una etiqueta sobre el nombre

Usa el `AvatarNametag` Component para mostrar una placa con texto personalizado sobre el nombre del NPC, por ejemplo un rol como "Shopkeeper" o "Boss". Adjúntalo a la misma Entity que tiene el `AvatarShape`:

```ts
AvatarNametag.create(myAvatar, { label: 'Shopkeeper' })
```

Si el `AvatarShape` tiene un `name`, solo se muestra la placa, sin ningún cuadro de nametag vacío debajo. Esto es útil para etiquetar un NPC solo con un título.

{% hint style="info" %}
**💡 Consejo**: Para una placa codificada por colores sin texto, establece `label` en una cadena de espacios y elige un `backgroundColor`. Se preservan los espacios, así que más espacios hacen la placa más ancha.

```ts
AvatarNametag.create(myAvatar, {
	label: '      ',
	backgroundColor: Color3.Red(),
})
```

{% endhint %}

Consulta [Etiquetas del Avatar](/creator/content-creator-es/scenes-sdk7/interactividad/avatares/avatar-nametags.md) para la lista completa de campos, incluidos los colores.

## Copiar wearables del jugador

El siguiente fragmento cambia los wearables y otras características de un avatar NPC para que coincidan con los que el jugador lleva actualmente. Esto podría usarse en una scene como un maniquí, para mostrar un wearable o emote concreto combinado con el atuendo actual del jugador.

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


export function swapAvatar(avatar: Entity) {

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

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

  const mutableAvatar = AvatarShape.getMutable(avatar)

  mutableAvatar.wearables = userData.wearables
  mutableAvatar.bodyShape = userData.avatar?.bodyShapeUrn
  mutableAvatar.eyeColor = userData.avatar?.eyesColor
  mutableAvatar.skinColor = userData.avatar?.skinColor
  mutableAvatar.hairColor = userData.avatar?.hairColor
  
}
```

## Mostrar solo wearables

Usa el `showOnlyWearables` campo para mostrar solo los wearables listados de un avatar. El resto del cuerpo del avatar será invisible.

```ts
const myAvatar = engine.addEntity()
AvatarShape.create(myAvatar, {
	id: '',
	emotes: [],
	wearables: [
    'urn:decentraland:matic:collections-v2:0x90e5cb2d673699be8f28d339c818a0b60144c494:0'
  ],
	showOnlyWearables: true,
})

Transform.create(myAvatar, {
	position: Vector3.create(4, 0.25, 5),
})
```

Esto es útil para mostrar wearables, por ejemplo en una tienda.

{% hint style="info" %}
**💡 Consejo**: Si un wearable es bastante pequeño, intenta establecer el `escala` de la `Transform` a un valor mayor.
{% endhint %}

## Adjuntar una Entity a un NPC

Puedes usar la `AvatarAttach` feature para fijar una Entity a uno de los bones de un avatar NPC, por ejemplo para que el NPC esté sosteniendo un objeto en la mano. La Entity se moverá junto con el avatar cuando se anime.

Para usar esta feature, usa el `id` la propiedad del `AvatarShape` para asignar un id arbitrario a este avatar, y luego referencia ese id en el `AvatarAttach`. El id puede ser cualquier string que quieras.

```ts
// Crear NPC, con un ID
const myAvatar = engine.addEntity()
Transform.create(myAvatar, {
  position: Vector3.create(8, 0.25, 8),
})
AvatarShape.create(myAvatar, {
  id: "my-avatar-id", 
  wearables: [],
  emotes: []
})

// Crear objeto para adjuntar al NPC
const attachedEntity = engine.addEntity()
Transform.create(attachedEntity, {
    position: Vector3.create(4, 2, 4),
    scale: Vector3.create(0.15,0.15,0.15)
})
MeshRenderer.setBox(attachedEntity)
Material.setBasicMaterial(attachedEntity, { diffuseColor: Color4.Blue() })
AvatarAttach.create(attachedEntity, {
    avatarId: "my-avatar-id",
    anchorPointId: AvatarAnchorPointType.AAPT_LEFT_HAND
})
```

Más información sobre el `AvatarAttach` component [aquí](/creator/content-creator-es/scenes-sdk7/fundamentos-del-contenido-3d/entity-positioning.md#attach-an-entity-to-an-avatar).

## Reemplazar el avatar del jugador

No puedes cambiar qué wearables lleva puesto el avatar del jugador, pero en su lugar puedes sustituir el avatar del jugador por un avatar NPC que puedes personalizar completamente.

Para hacerlo, oculta el avatar propio del jugador con un [Avatar Modifier Area](/creator/content-creator-es/scenes-sdk7/interactividad/avatares/modifier-areas.md#hide-avatars) que usa el `AMT_HIDE_AVATARS` modifier, y muestra una `AvatarShape` Entity en la posición del jugador en su lugar.

{% hint style="warning" %}
**📔 Nota**: Para permitir que el jugador tenga control total sobre ese avatar, debes escuchar los button events para detectar cuándo pulsa un botón y luego activar la animación correspondiente en el avatar NPC. Consulta [Button Events](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/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 específicos.
{% 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/npc-avatars.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.
