# Avatares NPC

Exiba um avatar como uma entidade em uma cena.

{% hint style="info" %}
**💡 Dica**: Experimente a [biblioteca NPC Toolkit](https://github.com/decentraland-scenes/dcl-npc-toolkit) para uma experiência mais fácil ao lidar com NPCs, especialmente se você precisar interagir por meio de uma árvore de conversa.
{% endhint %}

## Criar um avatar

O snippet a seguir cria um avatar com wearables e body shape aleatórios, e nome "NPC".

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

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

Ao passar dados para gerar um `AvatarShape`, os seguintes campos são obrigatórios:

* `id`: (obrigatório) Identificador interno do Avatar

Os seguintes campos opcionais também estão disponíveis:

* `name`: Nome a ser exibido acima da cabeça do Avatar. Padrão: "NPC".
* `bodyShape`: String para definir qual body shape usar. As opções válidas são 'urn:decentraland:off-chain:base-avatars:BaseMale' e 'urn:decentraland:off-chain:base-avatars:BaseFemale'.
* `wearables`: Array com a lista de URNs dos wearables que o avatar está usando no momento. Se os wearables entrarem em conflito (como quando dois deles são chapéus), o último da lista substitui o outro.
* `emotes`: Array com a lista de URNs dos emotes NFT que o avatar é capaz de reproduzir
* `eyeColor`: *Color3* para a cor dos olhos (qualquer cor é válida)
* `skinColor`: *Color3* para a cor da pele (qualquer cor é válida)
* `hairColor`: *Color3* para a cor do cabelo (qualquer cor é válida)
* `talking`: Se *true*, exibe um conjunto verde de barras ao lado do nome, como quando os players usam chat de voz in-world.
* <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p><strong>💡 Dica</strong>: Consulte <a href="/pages/67a7d7b853b5d1fd222cf8d62e61c780936c7a37">tipos de cor</a> para mais detalhes sobre como definir cores.</p></div>

{% hint style="warning" %}
**📔 Nota**: A `AvatarShape`component tem de ser importado via

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

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

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

## Animations

Avatars reproduzem animações idle padrão enquanto estão parados.

Para reproduzir animações no avatar, defina a `expressionTriggerId` string com o nome da animação que você quer reproduzir.

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

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

O `expressionTriggerId` campo suporta todas as [animações padrão](/creator/content-creator-pt/scenes-sdk7/interatividade/player-avatar.md#default-animations), assim como animações personalizadas [de um arquivo de cena](/creator/content-creator-pt/scenes-sdk7/interatividade/player-avatar.md#custom-animations), e até mesmo URNs de emotes publicados no marketplace.

### Animações em Loop

As animações em um `AvatarShape` são reproduzidas uma vez; se você quiser que o avatar continue em loop com uma animação, você deve criar um system que diga para reproduzir a animação novamente a cada poucos segundos.

Use o `expressionTriggerTimestamp` para reproduzir o mesmo emote novamente. O valor deste campo é um [timestamp lamport](https://en.wikipedia.org/wiki/Lamport_timestamp), o que significa que não é um valor de tempo, mas sim um índice que aumenta em 1 para cada repetição do emote.

Então, da primeira vez que você reproduzir um emote, você define `expressionTriggerTimestamp` // desenhar UI *0*. Para reproduzir o emote novamente, você deve atualizar esse valor para 1. É assim que o engine sabe que esta é uma nova instrução, e não uma instrução à qual ele já tenha reagido.

O snippet a seguir cria um system que executa o mesmo emote a 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) {
        // Disparar o emote de aplauso
        AvatarShape.getMutable(wearable).expressionTriggerTimestamp =+ 1 
        
        clapTimer = 0 // Reiniciar o timer
    }
})
```

{% hint style="info" %}
**💡 Dica**: Você precisa conhecer a duração do emote e fazer com que essa seja a duração do system. Se você criar um emote que mantém o avatar parado em uma mesma pose, é recomendável tornar a duração do emote maior do que a do system. Dessa forma, você pode garantir que não haverá artefatos ao finalizar e redefinir a animação.
{% endhint %}

## Copiar wearables do player

O snippet a seguir altera os wearables e outras características de um avatar NPC para corresponder àqueles que o player está usando no momento. Isso pode ser usado em uma cena como um manequim, para exibir um wearable ou emote específico combinado com a roupa atual do player.

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

## Exibir apenas wearables

Use o `show_only_wearables` campo para exibir apenas os wearables listados de um avatar. O restante do corpo do avatar ficará invisível.

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

Isso é útil para exibir wearables, por exemplo em uma loja.

{% hint style="info" %}
**💡 Dica**: Se um wearable for muito pequeno, tente definir o `scale` de `Transform` para um valor maior.
{% endhint %}

## Anexar uma entidade a um NPC

Você pode usar o `AvatarAttach` recurso para fixar uma entidade a um dos bones de um avatar NPC, por exemplo para que o NPC esteja segurando um objeto na mão. A entidade se moverá junto com o avatar quando ele animar.

Para usar esse recurso, use o `id` component em qualquer UI entity. Por exemplo, para definir uma entity que não tem nenhum `AvatarShape` para atribuir um id arbitrário a este avatar e então referencie esse id no `AvatarAttach`. O id pode ser qualquer string que você quiser.

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

// Criar objeto para anexar ao 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
})
```

Saiba mais sobre o `AvatarAttach` component [aqui](/creator/content-creator-pt/scenes-sdk7/essenciais-de-conteudo-3d/entity-positioning.md#attach-an-entity-to-an-avatar).


---

# Agent Instructions: 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:

```
GET https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/interatividade/npc-avatars.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
