> 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 Toolkit 라이브러리](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`: (필수) 아바타의 내부 식별자

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

* `이름`: 아바타 머리 위에 표시할 이름입니다. 기본값은 "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 { 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` 한 번만 재생됩니다. 아바타가 애니메이션을 계속 반복하게 하려면, 몇 초마다 애니메이션을 다시 재생하도록 지시하는 시스템을 만들어야 합니다.

단 하나의 예외는 반복되는 기본 이모트입니다, `sittingChair1`, `sittingChair2`, `sittingGround1` 그리고 `sittingGround2`, 이는 다음에서 포즈를 유지합니다: `AvatarShape` 다시 재생할 필요가 없습니다. 파일의 사용자 지정 애니메이션은 다음에서 절대 반복되지 않습니다: `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) {
        // 클랩 이모트를 트리거합니다
        AvatarShape.getMutable(myAvatar).expressionTriggerTimestamp += 1
        
        clapTimer = 0 // 타이머 재설정
    }
})
```

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

## 이름 위에 레이블 추가

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

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

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

{% hint style="info" %}
**💡 팁**: 텍스트가 없는 색상 구분 명판을 표시하려면 다음을 설정하세요 `label` 를 공백 문자열로 하고 다음을 선택하세요 `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
// NPC, ID 포함
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.
