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

# NPC 아바타

NPC 아바타 표시 및 제어

아바타를 장면의 엔티티로 표시합니다.

{% hint style="info" %}
**💡 팁**: 다음을 사용해 보세요 [NPC 툴킷 라이브러리](https://github.com/decentraland-scenes/dcl-npc-toolkit) NPC를 다루는 일을 더 쉽게 해주는, 특히 대화 트리를 통해 상호작용해야 할 때 유용한 경험을 제공합니다.
{% endhint %}

## 아바타 만들기

다음 스니펫은 임의의 착용 아이템과 체형, 그리고 이름이 "NPC"인 아바타를 생성합니다.

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

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

아바타를 생성하기 위해 데이터를 전달할 때 `AvatarShape`, 다음 필드가 필요합니다:

* `id`: (필수) 아바타의 내부 식별자

다음 선택적 필드도 사용할 수 있습니다:

* `name`: 아바타 머리 위에 표시할 이름입니다. 기본값: "NPC". 빈 문자열로 설정하면 이름을 전혀 표시하지 않게 할 수 있으며, 이는 오직 [아바타 이름표](/creator/content-creator-ko/sdk7/interactivity/avatars/avatar-nametags.md) NPC 위의 명판.
* `bodyShape`: 사용할 체형을 정의하는 문자열입니다. 유효한 옵션은 'urn:decentraland:off-chain:base-avatars:BaseMale' 및 'urn:decentraland:off-chain:base-avatars:BaseFemale'입니다.
* `wearables`: 아바타가 현재 착용 중인 착용 아이템 URN 목록이 담긴 배열입니다. 착용 아이템이 서로 충돌하는 경우(예: 둘 다 모자인 경우), 목록의 마지막 항목이 다른 항목을 대체합니다.
* `emotes`: 아바타가 재생할 수 있는 NFT 이모트 URN 목록이 담긴 배열입니다
* `eyeColor`: *Color3* 눈 색상용(어떤 색이든 유효합니다)
* `skinColor`: *Color3* 피부 색상용(어떤 색이든 유효합니다)
* `hairColor`: *Color3* 머리카락 색상용(어떤 색이든 유효합니다)
* `talking`: 만약 *true*, 이름 옆에 녹색 막대가 표시되며, 이는 플레이어가 월드 내 음성 채팅을 사용할 때와 같습니다.
* <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p><strong>💡 팁</strong>: 참조 <a href="/creator/content-creator-ko/sdk7/3d/color-types.md">투명도를 위한 값을 참조하세요. </a> 색상을 설정하는 방법에 대한 자세한 내용은</p></div>

{% hint style="warning" %}
**📔 참고**: `AvatarShape`구성 요소는 다음을 통해 import해야 합니다

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

다음 [가져오기](/creator/content-creator-ko/sdk7/getting-started/coding-scenes.md#imports) 를 참고해 쉽게 처리하는 방법을 확인하세요.
{% endhint %}

{% hint style="warning" %}
**📔 참고**: URN 필드는 다음에 사용되는 것과 동일한 형식을 따라야 합니다 [NFTShapes](/creator/content-creator-ko/sdk7/media/display-a-certified-nft.md): `urn:decentraland:<CHAIN>:<CONTRACT_STANDARD>:<CONTRACT_ADDRESS>:<TOKEN_ID>`
{% endhint %}

## 애니메이션

아바타는 가만히 있을 때 기본 대기 애니메이션을 재생합니다.

아바타에서 애니메이션을 재생하려면 `expressionTriggerId` 문자열을 재생하려는 애니메이션 이름으로 설정하세요.

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

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

이 `expressionTriggerId` 필드는 모든 [기본 애니메이션](/creator/content-creator-ko/sdk7/interactivity/avatars/avatar-animations.md#default-animations), 사용자 지정 애니메이션뿐만 아니라 [씬 파일의](/creator/content-creator-ko/sdk7/interactivity/avatars/avatar-animations.md#custom-animations), 그리고 마켓플레이스에 게시된 이모트의 URN까지 지원합니다.

### 루프 애니메이션

의 애니메이션은 `AvatarShape` 한 번만 재생되므로, 아바타가 애니메이션을 계속 반복하게 하려면 몇 초마다 다시 재생하도록 지시하는 시스템을 만들어야 합니다.

다음을 사용하세요 `expressionTriggerTimestamp` 같은 이모트를 다시 재생하기 위한 것입니다. 이 필드의 값은 [램포트 타임스탬프](https://en.wikipedia.org/wiki/Lamport_timestamp)즉 시간 값이 아니라 이모트가 반복될 때마다 1씩 증가하는 인덱스라는 뜻입니다.

따라서 이모트를 처음 재생할 때는 `expressionTriggerTimestamp` 를 *0*. 이모트를 다시 재생하려면 이 값을 1로 업데이트해야 합니다. 그래야 엔진이 이것이 이미 처리한 지시가 아니라 새로운 지시임을 알 수 있습니다.

다음 스니펫은 2초마다 동일한 이모트를 실행하는 시스템을 만듭니다:

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

// 시스템
engine.addSystem((dt: number) => {
    clapTimer += dt
      
    if (clapTimer >= emoteDuration) {
        // clap 이모트를 트리거합니다
        AvatarShape.getMutable(myAvatar).expressionTriggerTimestamp += 1
        
        clapTimer = 0 // 타이머 재설정
    }
})
```

{% hint style="info" %}
**💡 팁**: 이모트의 지속 시간을 알아야 하며, 이를 시스템의 지속 시간으로 설정해야 합니다. 아바타를 같은 포즈로 고정하는 이모트를 만든다면, 이모트의 지속 시간을 시스템보다 더 길게 설정하는 것이 좋습니다. 이렇게 하면 애니메이션을 끝내고 재설정할 때 아티팩트가 생기지 않도록 할 수 있습니다.
{% endhint %}

## 이름 위에 레이블 추가

다음을 사용하세요 `AvatarNametag` 컴포넌트를 사용하면 NPC 이름 위에 사용자 지정 텍스트가 적힌 명판을 표시할 수 있습니다. 예를 들어 "상점 주인"이나 "보스"와 같은 역할입니다. 이것을 다음을 가진 동일한 엔티티에 연결하세요 `AvatarShape`:

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

만약 `AvatarShape` 가 비어 있는 `name`, 명판만 표시되고 그 아래에는 빈 이름표 상자가 표시되지 않습니다. 이는 NPC에 직함만 붙이고 싶을 때 유용합니다.

{% hint style="info" %}
**💡 팁**: 텍스트 없이 색상으로 구분된 명판을 만들려면 다음을 설정하세요 `레이블` 를 공백 문자열로 설정하고 다음을 선택하세요: `backgroundColor`. 공백은 그대로 유지되므로, 공백이 많을수록 명판이 더 넓어집니다.

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

{% endhint %}

다음 [아바타 이름표](/creator/content-creator-ko/sdk7/interactivity/avatars/avatar-nametags.md) 색상을 포함한 전체 필드 목록은

## 플레이어의 착용 아이템 복사

다음 스니펫은 NPC 아바타의 착용 아이템과 기타 특성을 현재 플레이어가 착용 중인 것과 일치하도록 변경합니다. 이는 씬에서 마네킹처럼 사용하여 특정 착용 아이템이나 이모트를 플레이어의 현재 복장과 함께 보여주는 데 사용할 수 있습니다.

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

## 착용 아이템만 표시

다음을 사용하세요 `showOnlyWearables` 필드를 사용하면 아바타에 나열된 착용 아이템만 표시할 수 있습니다. 아바타의 나머지 신체는 보이지 않게 됩니다.

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

이는 예를 들어 상점에서 착용 아이템을 보여줄 때 유용합니다.

{% hint style="info" %}
**💡 팁**: 착용 아이템이 다소 작다면 다음을 설정해 보세요 `크기` 의 `Transform` 값을 더 큰 값으로.
{% endhint %}

## 엔티티를 NPC에 연결하기

다음을 사용할 수 있습니다 `AvatarAttach` 기능을 사용하면 엔티티를 NPC 아바타의 뼈대 중 하나에 고정할 수 있습니다. 예를 들어 NPC가 손에 물건을 들고 있게 할 수 있습니다. 엔티티는 애니메이션이 재생될 때 아바타와 함께 움직입니다.

이 기능을 사용하려면 `id` 속성을 `AvatarShape` 를 사용해 이 아바타에 임의의 id를 할당한 다음, 해당 id를 다음에서 참조하세요 `AvatarAttach`. id는 원하는 아무 문자열이나 가능합니다.

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

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

다음에 대해 자세히 알아보기 `AvatarAttach` 컴포넌트 [여기](/creator/content-creator-ko/sdk7/3d/entity-positioning.md#attach-an-entity-to-an-avatar).

## 플레이어의 아바타 교체

플레이어 아바타가 어떤 착용 아이템을 입고 있는지는 바꿀 수 없지만, 대신 완전히 사용자 지정할 수 있는 NPC 아바타로 플레이어의 아바타를 바꿀 수는 있습니다.

이를 위해 플레이어 자신의 아바타를 다음을 사용해 숨기세요 [아바타 수정 영역](/creator/content-creator-ko/sdk7/interactivity/avatars/modifier-areas.md#hide-avatars) 를 사용하는 `AMT_HIDE_AVATARS` 수정자를 사용하여 `AvatarShape` 대신 플레이어 위치에 엔티티를 표시합니다.

{% hint style="warning" %}
**📔 참고**: 플레이어가 해당 아바타를 완전히 제어할 수 있도록 하려면 버튼 이벤트를 수신하여 버튼을 눌렀는지 감지한 다음, NPC 아바타에서 해당 애니메이션을 트리거해야 합니다. 다음을 참조하세요 [버튼 이벤트](/creator/content-creator-ko/sdk7/interactivity/button-events/system-based-events.md) 자세한 내용은.

이렇게 할 때 제어의 부드러움이 완벽하지 않을 수 있으므로, 매우 특정한 경우에만 사용하는 것이 좋습니다.
{% 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-ko/sdk7/interactivity/avatars/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.
