> 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/button-events/system-based-events.md).

# 시스템 기반 이벤트

씬에서 사용자 클릭을 처리하는 방법을 알아보세요.

씬에 동일한 로직으로 활성화되는 유사한 엔티티가 여러 개 있다면, 하나의 시스템을 작성해 모든 엔티티를 순회하고 해당 동작을 한 번만 정의할 수 있습니다. 이것이 또한 가장 성능이 좋고 더 [데이터 지향적인](/creator/content-creator-ko/sdk7/architecture/data-oriented-programming.md) 접근 방식입니다.

시스템을 사용하여 감지할 수도 있습니다 [전역 입력 이벤트](#global-input-events), 그래서 플레이어의 커서가 어디를 가리키고 있는지와 상관없이 키가 눌릴 때마다 씬이 반응합니다.

활성화하기 위해 단일 엔티티를 클릭하거나 버튼을 누르기만 하면 된다면, 가장 쉬운 방법은 [콜백 등록](/creator/content-creator-ko/sdk7/interactivity/button-events/register-callback.md) 접근 방식입니다.

더 구체적인 커스텀 로직을 설정하려면, 원시 데이터를 다루고 다음을 사용하는 것이 좋습니다. [고급](/creator/content-creator-ko/sdk7/interactivity/button-events/advanced-button-events.md) 접근 방식입니다.

엔티티가 상호작용 가능하려면 [콜라이더](/creator/content-creator-ko/sdk7/3d/colliders.md). 자세한 내용은 [장애물](/creator/content-creator-ko/sdk7/interactivity/button-events/click-events.md#obstacles) 자세한 내용은 다음을 참조하세요. 이는 근접 클릭 이벤트에도 적용됩니다.

## 시스템 사용하기

input에서 헬퍼 함수 중 하나를 실행하여 버튼 이벤트를 확인합니다 `inputSystem` 네임스페이스를 매 틱마다 다음 안에서 [시스템](/creator/content-creator-ko/sdk7/architecture/systems.md).

예를 들어, 다음 시스템은 `inputSystem.isTriggered()` 함수를 사용하여 포인터가 클릭되었는지 확인합니다. 매 틱마다 버튼이 눌렸는지 확인합니다. 만약 `inputSystem.isTriggered()` 를 반환합니다. *true*, 시스템은 이에 대한 커스텀 로직을 실행합니다.

```ts
engine.addSystem(() => {
	if (inputSystem.isTriggered(InputAction.IA_POINTER, PointerEventType.PET_DOWN)) {
		// 버튼 눌림에 대한 로직
	}
})
```

다음 헬퍼 함수들을 사용할 수 있습니다 `inputSystem` 네임스페이스에서, 그리고 매 틱마다 비슷하게 호출할 수 있습니다:

* `inputSystem.isTriggered`: 마지막 틱 이후 입력 액션이 발생했으면 true를 반환합니다.
* `inputSystem.isPressed`: 입력이 현재 눌린 상태이면 true를 반환합니다. 버튼이 다시 올라갈 때까지 매 틱 true를 반환합니다.
* `inputSystem.getInputCommand`: 입력 액션에 대한 데이터를 가진 객체를 반환합니다.

각 항목에 대한 자세한 내용은 아래 섹션을 참조하세요.

엔티티에서 버튼 이벤트를 처리할 때는 항상 플레이어에게 피드백을 제공하여, 해당 엔티티와 상호작용할 수 있음을 인지하게 하세요. 다음을 추가하면 `PointerEvents` 엔티티에 컴포넌트를 추가하면, 플레이어는 커서를 그 엔티티 위에 올렸을 때 힌트를 보게 됩니다. 다음을 참조하세요. [피드백 표시](#show-feedback) 상호작용 가능한 엔티티에 호버 힌트를 추가하는 방법을 알아보세요.

### 전역 입력 이벤트

사용: `inputSystem.isTriggered` SDK가 추적하는 모든 입력에서 버튼 눌림 및 버튼 뗌 이벤트를 감지합니다.

```ts
engine.addSystem(() => {
	if (
		inputSystem.isTriggered(InputAction.IA_POINTER, PointerEventType.PET_DOWN)
	) {
		// 버튼 눌림에 대한 로직
	}
})
```

위 예제는 포인터가 어디를 가리키고 있는지나 그 경로에 어떤 엔티티가 있는지와 상관없이 버튼이 눌렸는지 확인합니다.

`inputSystem.isTriggered()` 를 반환합니다. *true* 지정된 버튼이 게임 루프의 현재 틱에서 눌렸을 때에만 해당합니다. 버튼이 눌리지 않았거나 이전 틱부터 이미 눌린 상태였다면, 반환합니다 *false*.

{% hint style="warning" %}
**📔 참고**: 포인터 이벤트가 감지되려면 플레이어가 씬의 경계 안에 서 있어야 합니다. 또한 플레이어의 커서가 잠겨 있어야 하며, 자유 커서 상태에서 누른 버튼은 감지되지 않습니다.

상호작용하려는 모든 엔티티에는 다음 두 가지가 모두 있어야 합니다 [`PointerEvents` 컴포넌트](#show-feedback) 그리고 [콜라이더](/creator/content-creator-ko/sdk7/3d/colliders.md).
{% endhint %}

그 `inputSystem.isTriggered` 함수는 다음 필수 인수를 받습니다:

* `InputAction`: 어떤 입력을 들을지, 다음의 값으로 `InputAction` 열거형입니다. 다음을 참조하세요: [포인터 버튼](/creator/content-creator-ko/sdk7/interactivity/button-events/click-events.md#pointer-buttons) 지원되는 옵션은 다음을 참조하세요.
* `PointerEventType`: 어떤 유형의 이벤트를 들을지, 다음의 값으로 `PointerEventType` 열거형입니다. 다음을 참조하세요: [포인터 이벤트의 유형](/creator/content-creator-ko/sdk7/interactivity/button-events/click-events.md#types-of-pointer-events) 지원되는 옵션은 다음을 참조하세요.

### 엔티티 활성화하기

특정 엔티티를 가리키는 동안 버튼 이벤트를 감지하려면, 다음에 세 번째 선택적 인수를 전달하세요. `inputSystem.isTriggered` 비교할 엔티티를 지정합니다.

```ts
// 엔티티에 PointerEvents 컴포넌트 추가
PointerEvents.create(myEntity, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_PRIMARY,
				showFeedback: false,
			},
		},
	],
})

// 시스템 생성
engine.addSystem(() => {
	if (
		inputSystem.isTriggered(
			InputAction.IA_POINTER,
			PointerEventType.PET_DOWN,
			myEntity
		)
	) {
		// myEntity에서의 버튼 눌림에 대한 로직
	}
})
```

위 예제는 단일 하드코딩된 엔티티가 포인터 버튼(왼쪽 마우스 버튼)으로 눌렸는지 매 틱마다 확인합니다.

그 `inputSystem.isTriggered` 함수는 다음 인수를 받습니다:

* `InputAction`: 어떤 입력을 들을지, 다음의 값으로 `InputAction` 열거형입니다. 다음을 참조하세요: [포인터 버튼](/creator/content-creator-ko/sdk7/interactivity/button-events/click-events.md#pointer-buttons) 지원되는 옵션은 다음을 참조하세요.
* `PointerEventType`: 어떤 유형의 이벤트를 들을지, 다음의 값으로 `PointerEventType` 열거형입니다. 다음을 참조하세요: [포인터 이벤트의 유형](/creator/content-creator-ko/sdk7/interactivity/button-events/click-events.md#types-of-pointer-events) 지원되는 옵션은 다음을 참조하세요.
* `Entity` *(선택 사항)*: 이 이벤트를 확인할 엔티티입니다. 값이 제공되지 않으면 플레이어의 커서가 어디를 가리키고 있었는지와 상관없이 버튼의 전역 눌림을 확인합니다.

이 예제에서는 또한 다음을 추가하고 있음을 참고하세요 `PointerEvents` 상호작용하려는 엔티티에 컴포넌트를 추가합니다. 이 단계는 필수이며, 이 컴포넌트가 없으면 엔티티는 다음 함수들로 감지할 수 없습니다 `inputSystem`. 다음을 참조하세요 [피드백 표시](#show-feedback) 에 대한 자세한 내용은 `PointerEvents` 컴포넌트를 부여해야 합니다.

{% hint style="warning" %}
**📔 참고**: 그리고 [콜라이더](/creator/content-creator-ko/sdk7/3d/colliders.md). 자세한 내용은 [장애물](/creator/content-creator-ko/sdk7/interactivity/button-events/click-events.md#obstacles) 자세한 내용은 다음을 참조하세요.
{% endhint %}

플레이어가 같은 방식으로 상호작용할 수 있는 엔티티가 여러 개 있다면, 다음을 사용하는 것을 고려하세요 `inputSystem.getInputCommand`. 이 명령은 엔티티 ID를 포함한 전역 클릭 명령에 대한 정보를 반환하며, 이를 사용해 모두를 처리할 수 있는 단일 함수를 실행할 수 있습니다.

```ts
engine.addSystem(() => {
	const result = inputSystem.getInputCommand(
		InputAction.IA_POINTER,
		PointerEventType.PET_DOWN
	)
	if (result) {
		if (result.hit?.entityId === myEntity) {
			// 클릭 처리
		}
	}
})
```

{% hint style="warning" %}
**📔 참고**: 상호작용하려는 모든 엔티티에는 다음 두 가지가 모두 있어야 합니다 [`PointerEvents` 컴포넌트](#show-feedback) 그리고 [콜라이더](/creator/content-creator-ko/sdk7/3d/colliders.md).
{% endhint %}

참고 [입력 동작의 데이터](#data-from-input-action) 자세한 내용은 다음을 참조하세요. 이 메서드는 포인터 이벤트의 히트에 대한 더 자세한 데이터도 제공합니다.

### 입력 버튼 뗌

다음과 같은 방식으로 pointer up 이벤트도 확인할 수 있습니다. `PointerEventType.PET_UP`.

```ts
engine.addSystem(() => {
	if (
		inputSystem.isTriggered(
			InputAction.IA_POINTER,
			PointerEventType.PET_UP,
			myEntity
		)
	) {
		// myEntity를 가리키는 동안 버튼 뗌에 대한 로직
	}
})
```

{% hint style="warning" %}
**📔 참고**: 특정 엔티티를 대상으로 pointer up 이벤트를 확인할 때는 버튼이 눌렸을 당시 커서가 어디를 가리키고 있었는지는 고려하지 않습니다. 버튼이 올라갈 때 커서가 어디를 가리키고 있는지만 고려합니다.

또한 해당 엔티티에는 다음 두 가지가 모두 있어야 한다는 점을 기억하세요 [`PointerEvents` 컴포넌트](#show-feedback) 그리고 [콜라이더](/creator/content-creator-ko/sdk7/3d/colliders.md).
{% endhint %}

### 눌린 버튼 확인

다음을 사용하여 버튼이 현재 눌려 있는지 확인합니다 `inputSystem.isPressed()` 시스템 안에서.

```ts
engine.addSystem(() => {
	if (inputSystem.isPressed(InputAction.IA_POINTER)) {
		// 버튼이 눌린 상태에 대한 로직
	}
})
```

`inputSystem.isPressed()` 를 반환합니다. *true* 버튼이 언제 눌렸는지와 플레이어의 커서가 어디를 가리키고 있는지와 상관없이, 버튼이 현재 눌린 상태이면 true를 반환합니다. 그렇지 않으면 반환합니다 *false*.

그 `inputSystem.isPressed` 함수는 하나의 인수를 받습니다:

* `InputAction`: 어떤 입력을 들을지, 다음의 값으로 `InputAction` 열거형입니다. 다음을 참조하세요: [포인터 버튼](/creator/content-creator-ko/sdk7/interactivity/button-events/click-events.md#pointer-buttons) 지원되는 옵션은 다음을 참조하세요.

### 여러 엔티티 처리

씬에 포인터 이벤트의 영향을 같은 방식으로 받는 엔티티가 여러 개 있다면, 모두를 순회하는 시스템을 작성하는 것이 합리적입니다.

```ts
engine.addSystem(() => {
	const activatedEntites = engine.getEntitiesWith(PointerEvents)
	for (const [entity] of activatedEntites) {
		if (
			inputSystem.isTriggered(
				InputAction.IA_POINTER,
				PointerEventType.PET_DOWN,
				entity
			)
		) {
			// 엔티티와의 상호작용에 대한 로직
		}
	}
})
```

이 예제는 다음을 사용합니다 [컴포넌트 쿼리](/creator/content-creator-ko/sdk7/architecture/querying-components.md) 다음을 가진 모든 엔티티를 순회하기 위해 `PointerEvents` 컴포넌트. 그런 다음 각 엔티티를 다음으로 확인합니다 `inputSystem.isTriggered`다음으로, 하나씩 순회합니다. 이들 엔티티 중 하나에서 입력 액션이 감지되면 커스텀 로직을 실행합니다.

다음을 순회하는 대신 *모든* 다음을 가진 엔티티들을 `PointerEvents` 컴포넌트 하나뿐이지만, 이 컴포넌트는 다음 안에 여러 객체를 포함할 수 있습니다. 서로 다른 방식으로 동작해야 하는 엔티티를 처리하기 위해 서로 다른 시스템을 작성할 수 있습니다. 권장되는 방법은 서로 다른 유형의 엔티티를 특정 [사용자 정의 컴포넌트](/creator/content-creator-ko/sdk7/architecture/custom-components.md)으로 표시하고, 별도의 시스템에서 이를 순회하는 것입니다.

```ts
engine.addSystem(() => {
	const activatedDoors = engine.getEntitiesWith(IsDoor, PointerEvents)
	for (const [entity] of activatedDoors) {
		if (
			inputSystem.isTriggered(
				InputAction.IA_POINTER,
				PointerEventType.PET_DOWN,
				entity
			)
		) {
			openDoor(entity)
		}
	}
})

engine.addSystem(() => {
	const pickedUpGems = engine.getEntitiesWith(IsGem, PointerEvents)
	for (const [entity] of pickedUpGems) {
		if (
			inputSystem.isTriggered(
				InputAction.IA_POINTER,
				PointerEventType.PET_DOWN,
				entity
			)
		) {
			pickUp(entity)
		}
	}
})
```

이 예제에는 다음 이름의 커스텀 컴포넌트를 가진 모든 엔티티를 순회하는 하나의 시스템과 `IsDoor` 다음 이름의 커스텀 컴포넌트를 가진 모든 엔티티를 순회하는 또 하나의 시스템이 있습니다 `isGem`입니다. 두 시스템 모두 일치하는 각 엔티티가 포인터 버튼으로 활성화되었는지 확인합니다.

씬 코드를 이렇게 구성하는 방식은 매우 [데이터 지향적인](/creator/content-creator-ko/sdk7/architecture/data-oriented-programming.md) 하며, 메모리 자원을 매우 효율적으로 사용하게 됩니다.

\## 엔티티의 여러 버튼

다음과 같은 헬퍼를 사용하면 `pointerEventsSystem.onPointerDown`각 엔티티는 하나의 이벤트 유형만 가질 수 있습니다. 서로 다른 두 버튼 이벤트를 등록할 수는 없습니다. 시스템 기반 이벤트를 사용할 때는 그런 제한이 없습니다. 예를 들어, 플레이어가 E와 F를 눌러 각각 다른 기능을 실행하며 상호작용할 수 있는 엔티티가 있습니다.

```ts
    engine.addSystem(() => {
        if (inputSystem.isTriggered(InputAction.IA_PRIMARY, PointerEventType.PET_DOWN, myEntity)) {
            // E에 반응
        }
        if (inputSystem.isTriggered(InputAction.IA_SECONDARY, PointerEventType.PET_DOWN, myEntity)) {
            // F에 반응
        }
    })
```

## 피드백 표시

엔티티를 가리키는 동안 UI 힌트를 표시하려면, 엔티티의 다음 속성을 사용하세요 `PointerEvents` 컴포넌트를 부여해야 합니다.

```ts
// 엔티티 생성
const myEntity = engine.addEntity()

// 엔티티에 PointerEvents 컴포넌트 추가
PointerEvents.create(myEntity, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
			},
		},
	],
})
```

플레이어의 커서가 이 엔티티의 콜라이더를 가리키면, UI는 해당 엔티티와 상호작용할 수 있음을 나타내는 호버 힌트를 표시합니다. 구성할 수 있는 내용의 자세한 사항은 아래 섹션을 참조하세요.

{% hint style="warning" %}
**📔 참고**:  `PointerEvents` 컴포넌트는 호버 피드백 표시만 처리합니다. 버튼 이벤트 자체를 커스텀 로직으로 처리하려면 다음을 참조하세요. [시스템 사용하기](#check-for-events).
{% endhint %}

그 `PointerEvents` 컴포넌트에는 최소 하나의 포인터 이벤트 정의가 필요합니다. 각 포인터 이벤트 정의는 다음과 같이 구성할 수 있습니다:

* `eventType`: 어떤 유형의 이벤트를 들을지, 다음의 값으로 `PointerEventType` 열거형입니다. 다음을 참조하세요: [포인터 이벤트의 유형](/creator/content-creator-ko/sdk7/interactivity/button-events/click-events.md#types-of-pointer-events) 지원되는 옵션은 다음을 참조하세요.
* `eventInfo`: 다음 필드를 포함할 수 있는 객체:
  * `버튼` (*필수*): 어떤 입력을 들을지, 다음의 값으로 `InputAction` 열거형입니다. 다음을 참조하세요: [포인터 버튼](/creator/content-creator-ko/sdk7/interactivity/button-events/click-events.md#pointer-buttons) 지원되는 옵션은 다음을 참조하세요.
  * `hoverText` *(선택 사항)*: 호버 피드백 힌트에 표시할 문자열입니다. 기본값은 "상호작용"입니다.
  * `showFeedback` *(선택 사항)*: false이면 이 엔티티의 호버 힌트와 가장자리 강조 표시는 모두 숨깁니다. *true* 항목만 내보냅니다.
  * `showHighlight` *(선택 사항)*: true이면 플레이어가 커서를 엔티티 위에 올렸을 때 가장자리 강조 표시를 볼 수 있습니다. *true* 기본값입니다. 이 값은 다음의 경우에만 고려됩니다. `showFeedback` 일 때 *true*.
  * `maxDistance` *(선택 사항)*: 플레이어의 얼마나 멀리 **아바타** 떨어져 있어도 엔티티와 상호작용할 수 있는지, 미터 단위입니다. 기본값은 *10미터*. 자세한 내용은 [최대 거리](#max-distance).
  * `maxCameraDistance` *(선택 사항)*: 얼마나 멀리 **현재 활성 카메라의** 떨어져 있어도 엔티티와 상호작용할 수 있는지, 미터 단위입니다. 기본적으로 설정되지 않습니다. 다음을 참조하세요 [최대 거리](#max-distance).
  * `우선순위` *(선택 사항)*: 여러 엔티티가 겹칠 때 어느 엔티티가 우선되는지입니다. 값이 높을수록 우선합니다. *0* 항목만 내보냅니다.

하나의 `PointerEvents` 컴포넌트는 여러 포인터 이벤트 정의를 담을 수 있으며, 서로 다른 버튼에 대한 서로 다른 이벤트를 감지할 수 있습니다. 각 엔티티는 다음만 가질 수 있습니다 *하나만* `PointerEvents` 컴포넌트 하나뿐이지만, 이 컴포넌트는 다음 안에 여러 객체를 포함할 수 있습니다 `pointerEvents` 배열에, 응답할 이벤트마다 하나씩.

```ts
PointerEvents.create(NPCEntity, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
				hoverText: 'Greet',
			},
		},
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_PRIMARY,
				hoverText: 'Choke',
			},
		},
		{
			eventType: PointerEventType.PET_UP,
			eventInfo: {
				button: InputAction.IA_PRIMARY,
				hoverText: 'Stop Choke',
			},
		},
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_SECONDARY,
				hoverText: 'Give gem',
			},
		},
	],
})
```

플레이어는 각 포인터 이벤트마다 하나씩 여러 레이블이 커서를 중심으로 방사형으로 표시되는 것을 보게 됩니다.

아래 예제는 다음을 함께 사용합니다 `PointerEvents` 호버 힌트를 표시하고, 플레이어의 동작을 커스텀 로직으로 실제 처리하는 시스템을 함께 사용합니다.

```ts
// 엔티티 생성
const myEntity = engine.addEntity()

// 엔티티에 호버 피드백 제공
PointerEvents.create(myEntity, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
				hoverText: 'Open',
			},
		},
	],
})

// 엔티티의 클릭 이벤트 처리
engine.addSystem(() => {
	if (
		inputSystem.isTriggered(
			InputAction.IA_POINTER,
			PointerEventType.PET_DOWN,
			myEntity
		)
	) {
		// 입력 액션에 대한 커스텀 로직
	}
})
```

### 호버 피드백

플레이어가 다음이 있는 아이템 위에 커서를 올리면 `PointerEvents` 컴포넌트가 있는 경우, 다음이 표시됩니다:

* 엔티티의 가장자리 강조 표시
* 커서 근처에, 눌러야 하는 버튼의 아이콘과 "상호작용"이라고 적힌 문자열이 있는 호버 힌트가 표시됩니다.

이러한 요소는 켜고 끌 수 있으며 사용자 지정할 수 있습니다.

UI의 호버 피드백은 다음에서 선택한 입력에 따라 다른 아이콘을 표시합니다. `버튼` 필드입니다. PC에서는 다음이 있는 아이콘을 표시합니다 `E` 에 대해 `InputAction.IA_PRIMARY`, 그리고 `F` 에 대해 `InputAction.IA_SECONDARY`, 그리고 마우스는 `InputAction.IA_POINTER`.

문자열을 변경하려면 다음의 값을 변경하세요 `hoverText` 값입니다. 이 문자열은 짧게 유지하세요. 그래야 빠르게 읽을 수 있고 화면에서 너무 방해되지 않습니다.

```ts
// 엔티티 생성
const chest = engine.addEntity()

// 엔티티에 PointerEvents 컴포넌트 추가
PointerEvents.create(chest, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
				hoverText: 'Open',
			},
		},
	],
})
```

위 예제에서 포인터 이벤트에는 다음 값이 포함됩니다 `hoverText`. 이 필드는 플레이어가 엔티티를 가리키는 동안 UI에 표시할 문자열을 정의합니다. 기본적으로 이 문자열은 다음을 나타냅니다 *상호작용*.

{% hint style="info" %}
**💡 팁**:  `hoverText` 문자열은 상호작용 시 발생하는 동작을 설명해야 합니다. 예를 들어 `Open`, `활성화`, `집기`, `선택`. 이러한 문자열은 플레이어의 집중을 너무 많이 빼앗지 않도록 가능한 한 짧아야 합니다.
{% endhint %}

엔티티에 여러 포인터 이벤트가 있으면, 각각의 호버 힌트가 커서를 중심으로 방사형으로 표시됩니다.

그 `hoverText` 다음의 `.UP` 포인터 이벤트는 플레이어가 이미 해당 키를 누른 채 엔티티를 가리키고 있을 때만 표시됩니다.

엔티티에 다음 두 가지가 모두 있으면: `DOWN` 포인터 이벤트와 `UP` 포인터 이벤트, 다음에 대한 힌트는 `DOWN` 동작은 버튼이 눌리지 않은 동안 표시됩니다. 힌트는 다음의 힌트로 바뀝니다 `UP` 이벤트는 버튼이 눌리고 계속 눌려 있는 경우에만 표시됩니다.

```ts
// 엔티티 생성
const entity = engine.addEntity()

// 엔티티에 PointerEvents 컴포넌트 추가
PointerEvents.create(entity, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
				hoverText: 'Drag',
			},
		},
		{
			eventType: PointerEventType.PET_UP,
			eventInfo: {
				button: InputAction.IA_POINTER,
				hoverText: 'Drop',
			},
		},
	],
})
```

호버 힌트를 숨기되 가장자리 강조 표시는 남기려면 다음의 값을 설정하세요 `hoverText` 를 ""로.

```ts
// 엔티티 생성
const chest = engine.addEntity()

// 엔티티에 PointerEvents 컴포넌트 추가
PointerEvents.create(chest, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
				hoverText: '',
			},
		},
	],
})
```

가장자리 강조 표시는 숨기되 호버 힌트는 남기려면 다음을 설정하세요 `showHighlight` 를 *false*.

```ts
// 엔티티 생성
const chest = engine.addEntity()

// 엔티티에 PointerEvents 컴포넌트 추가
PointerEvents.create(chest, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
				hoverText: '문 열기',
				showHighlight: false,
			},
		},
	],
})
```

호버 힌트와 가장자리 강조 표시를 모두 숨기려면 다음을 설정하세요 `showFeedback` 를 *false*. 이렇게 하면 커서는 아이콘, 텍스트 또는 가장자리 하이라이트를 표시하지 않습니다. 또는 그냥 다음을 제거할 수도 있습니다 `PointerEvents` 엔티티에서 컴포넌트를 제거합니다.

```ts
// 엔티티 생성
const chest = engine.addEntity()

// 엔티티에 PointerEvents 컴포넌트 추가
PointerEvents.create(chest, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
				showFeedback: false,
			},
		},
	],
})
```

### 최대 거리

일부 엔티티는 의도적으로 가까운 거리에서만 상호작용 가능하도록 할 수 있습니다. 플레이어가 엔티티에서 너무 멀리 떨어져 있으면 호버 힌트가 커서 옆에 표시되지 않습니다.

기본적으로 엔티티는 플레이어의 **아바타** 가 다음 범위 안에 있을 때만 클릭할 수 있습니다 *10미터* 해당 엔티티의. 다음을 설정하여 그 범위를 변경할 수 있습니다 `maxDistance` 포인터 이벤트의 속성.

```ts
// 엔티티 생성
const myEntity = engine.addEntity()

// 엔티티에 PointerEvents 컴포넌트 추가
PointerEvents.create(myEntity, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
				maxDistance: 6,
			},
		},
	],
})

// 포인터 이벤트를 처리할 시스템 구현
engine.addSystem(() => {
	// 포인터 이벤트에 대한 데이터 가져오기
	const cmd = inputSystem.getInputCommand(
		InputAction.IA_POINTER,
		PointerEventType.PET_DOWN,
		myEntity
	)

	// 클릭이 충분히 가까웠는지 확인
	if (cmd && cmd.hit && cmd.hit.length < 6) {
		// 작업 수행
	}
})
```

위 예제는 호버 힌트의 최대 거리를 다음으로 설정합니다 *6미터*. 입력 액션을 처리하는 로직도 같은 규칙을 따르도록 하세요. 다음을 참조하세요 [입력 동작의 데이터](#data-from-input-action) 입력 액션의 거리를 얻는 방법은

`maxDistance` 는 플레이어의 **아바타**을 기준으로 측정되므로, 1인칭과 3인칭에서 동일하게 동작합니다.

상호작용을 다음의 거리로 제한하려면 **현재 활성 카메라의** 대신, 다음을 사용하세요 `maxCameraDistance`. 둘 다 설정하면 어느 한쪽 검사만 통과해도 충분합니다. 다음을 참조하세요 [거리 제한](/creator/content-creator-ko/sdk7/interactivity/button-events/register-callback.md#distance-limits) 전체 규칙 집합은

{% hint style="warning" %}
**📔 참고**: `maxPlayerDistance` 는 다음의 더 이상 사용되지 않는 별칭입니다: `maxDistance`. 둘 다 아바타를 기준으로 거리를 측정하므로, 다음을 사용하세요 `maxDistance` 새 장면에서
{% endhint %}

## 고급 커스텀 힌트

그 `PointerEvents` 컴포넌트는 플레이어의 커서가 엔티티 위에 호버를 시작할 때 UI 힌트를 쉽게 추가합니다. 일반적으로 힌트가 다른 Decentraland 씬에서 플레이어가 익숙하게 보는 방식과 일관되게 동작하는 것은 좋은 일입니다. 하지만 어떤 경우에는 어떤 것이 상호작용 가능하다는 것을 커스텀 방식으로 알리고 싶을 수 있습니다. 예를 들어 플레이어가 엔티티 위에 호버를 시작할 때 은은한 소리를 재생할 수 있습니다. 호버 중에는 엔티티 주위에 빛나는 하이라이트를 표시하고, 호버하지 않을 때는 숨길 수도 있습니다. 특정 게임플레이 메커니즘에도 사용할 수 있습니다.

사용하세요 `inputSystem.isTriggered()` 함수를 다음과 함께 `PointerEventType.PET_HOVER_ENTER` 및 `PointerEventType.PET_HOVER_LEAVE` 이벤트를 사용해 플레이어의 커서가 엔티티의 콜라이더를 가리키기 시작할 때와 더 이상 가리키지 않을 때마다 커스텀 동작을 수행합니다.

아래 예제는 엔티티를 다음 크기로 확대합니다 *1.5* 커서가 해당 콜라이더를 가리키기 시작하면, 다시 다음 크기로 되돌립니다 *1* 커서가 엔티티를 벗어나면.

```ts
engine.addSystem(() => {
	const meshEntities = engine.getEntitiesWith(MeshRenderer)
	for (const [entity] of meshEntities) {
		if (
			inputSystem.isTriggered(
				InputAction.IA_POINTER,
				PointerEventType.PET_HOVER_ENTER,
				entity
			)
		) {
			Transform.getMutable(entity).scale = Vector3.create(1.5, 1.5, 1.5)
		}

		if (
			inputSystem.isTriggered(
				InputAction.IA_POINTER,
				PointerEventType.PET_HOVER_LEAVE,
				entity
			)
		) {
			Transform.getMutable(entity).scale = Vector3.create(1, 1, 1)
		}
	}
})
```

{% hint style="warning" %}
**📔 참고**: 상호작용하려는 모든 엔티티에는 다음 두 가지가 모두 있어야 합니다 [`PointerEvents` 컴포넌트](#show-feedback) 그리고 [콜라이더](/creator/content-creator-ko/sdk7/3d/colliders.md).
{% endhint %}

## 근접 이벤트

커서가 어디를 향하고 있는지와 상관없이 근접 버튼 눌림을 확인하려면 다음을 사용하세요 `PET_DOWN` 다음을 사용하는 엔티티에서 `InteractionType.PROXIMITY`. 다음을 설정하세요 `interactionType` 포인터 이벤트 정의의 필드에서, 다음 옆에 `eventInfo`, 이벤트를 근접 기반으로 표시합니다.

참고 [**근접 이벤트**](/creator/content-creator-ko/sdk7/interactivity/button-events/proximity-events.md) 사용 가능한 헬퍼 함수들을 포함한 자세한 내용은

```ts
PointerEvents.create(myEntity, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_PRIMARY,
				hoverText: 'Press E',
				maxDistance: 5
			},
			interactionType: InteractionType.PROXIMITY,
		},
	],
})

engine.addSystem(() => {
	if (inputSystem.isTriggered(InputAction.IA_PRIMARY, PointerEventType.PET_DOWN, myEntity)) {
		console.log('Player pressed button near entity')
	}
})
```

다음과 같은 헬퍼를 사용하면 `pointerEventsSystem.onProximityDown`엔티티는 한 개의 커서 핸들러와 한 개의 근접 핸들러를 동시에 가질 수 있으며, 두 콜백이 모두 실행됩니다. 하지만 같은 핸들러에 서로 다른 두 버튼을 등록할 수는 없습니다. 시스템 기반 이벤트에는 그런 제한이 없습니다. 동작마다 하나의 항목을 정의하면 됩니다. 예를 들어, 커서를 가리키고 E를 누르거나, 커서로 가리키지 않고 가까이 걸어가 E를 눌러도 상호작용할 수 있는 엔티티가 있습니다.

```ts
	PointerEvents.create(myEntity, {
        pointerEvents: [
            {
                eventType: PointerEventType.PET_DOWN,
                eventInfo: {
                    button: InputAction.IA_POINTER,
                    hoverText: '클릭',
                    maxDistance: 15,
                },
                interactionType: InteractionType.CURSOR,
            },
            {
                eventType: PointerEventType.PET_DOWN,
                eventInfo: {
                    button: InputAction.IA_PRIMARY,
                    hoverText: 'Press E',
                    maxDistance: 15,
                },
                interactionType: InteractionType.PROXIMITY,
            },
        ],
    })
    
    engine.addSystem(() => {
        if (inputSystem.isTriggered(InputAction.IA_POINTER, PointerEventType.PET_DOWN, myEntity)) {
            console.log('Player clicked at entity')
        }
        if (inputSystem.isTriggered(InputAction.IA_PRIMARY, PointerEventType.PET_DOWN, myEntity)) {
            console.log('Player pressed button near entity')
        }
    })
```

다음을 사용해 `inputSystem.isTriggered()` 와 함께 `PET_PROXIMITY_ENTER` 및 `PET_PROXIMITY_LEAVE` 플레이어가 엔티티의 근접 범위에 들어오거나 나갈 때 반응하는 이벤트 유형입니다. 이는 근접 활성화된 엔티티에 대해 추가 피드백을 표시할 때 유용하며, 예를 들어 소리나 애니메이션을 재생할 수 있습니다.

이렇게 하려면 엔티티에 다음이 있어야 합니다 `PointerEvents` 해당 근접 이벤트 유형이 정의된 컴포넌트가

```ts
PointerEvents.create(myEntity, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_PROXIMITY_ENTER,
			eventInfo: {
				button: InputAction.IA_POINTER,
				maxDistance: 5,
			},
		},
		{
			eventType: PointerEventType.PET_PROXIMITY_LEAVE,
			eventInfo: {
				button: InputAction.IA_POINTER,
				maxDistance: 5,
				showFeedback: false,
			},
		},
	],
})

engine.addSystem(() => {
	if (inputSystem.isTriggered(InputAction.IA_POINTER, PointerEventType.PET_PROXIMITY_ENTER, myEntity)) {
		console.log('Player entered proximity')
	}
	if (inputSystem.isTriggered(InputAction.IA_POINTER, PointerEventType.PET_PROXIMITY_LEAVE, myEntity)) {
		console.log('Player left proximity')
	}
})
```

## 입력 동작의 데이터

눌린 버튼, 맞은 엔티티, 레이의 방향과 길이 등 입력 동작에서 데이터를 가져옵니다. 다음을 참조하세요 ([문서 보기](https://github.com/decentraland/docs/tree/main/README.md))에서 사용 가능한 모든 데이터에 대한 설명을 볼 수 있습니다.

이 데이터를 가져오려면 다음을 사용하세요 `inputSystem.getInputCommand`. 이 함수는 입력 이벤트에 대한 데이터가 포함된 전체 데이터 구조를 반환합니다.

```ts
engine.addSystem(() => {
	const cmd = inputSystem.getInputCommand(
		InputAction.IA_POINTER,
		PointerEventType.PET_DOWN,
		myEntity
	)
	if (cmd) {
		console.log(cmd.hit?.entityId)
	}
})
```

쿼리와 일치하는 입력 액션이 없었다면 `inputSystem.getInputCommand` 를 반환합니다. *null*. 로직에서 이 상황을 처리하도록 하세요.

### 최대 클릭 거리

최대 거리를 강제하여 엔티티가 가까운 거리에서만 클릭 가능하도록 하려면 다음을 가져오세요 `hit.length` 이벤트 데이터의 속성.

```ts
// 포인터 이벤트를 처리할 시스템 구현
engine.addSystem(() => {
	// 포인터 이벤트에 대한 데이터 가져오기
	const cmd = inputSystem.getInputCommand(
		InputAction.IA_POINTER,
		PointerEventType.PET_DOWN,
		myEntity
	)

	// 클릭이 충분히 가까웠는지 확인
	if (cmd && cmd.hit && cmd.hit.length < 6) {
		// 작업 수행
	}
})
```

{% hint style="warning" %}
**📔 참고**: 멀리 있는 이벤트를 무시한다면, 반드시 다음을 설정하세요 `maxDistance` 매개변수를 다음의 `PointerEvents` 컴포넌트에 일관되게 동작하도록.
{% endhint %}

### 모델 내부의 서로 다른 메시

종종 *.glTF* 3D 모델은 각기 고유한 내부 이름을 가진 여러 메시로 구성됩니다. 모든 버튼 이벤트에는 어떤 특정 메시가 클릭되었는지에 대한 정보가 포함되어 있으므로, 이 정보를 사용해 경우마다 다른 클릭 동작을 실행할 수 있습니다.

모델 내부의 메시 이름을 확인하려면 다음과 같은 편집 도구로 3D 모델을 열어야 합니다 [Blender](https://www.blender.org/) 예를 들어.

![](https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-c0c8238fe31b8eb541ccb25d29459670a994f03e%2Fmesh-names%20\(1\).png?alt=media)

{% hint style="info" %}
**💡 팁**: 로그를 찍고 콘솔에서 읽어 클릭된 메시의 이름을 알아낼 수도 있습니다.
{% endhint %}

다음에 접근할 수 있습니다 `meshName` 속성을 다음의 일부로 `히트` 객체에서, 이는 클릭 이벤트에 의해 반환됩니다.

아래 예제에는 다음 이름의 메시를 포함한 집 모델이 있습니다 `firePlace`. 해당 메시가 클릭되었을 때만 벽난로를 켜고 싶습니다.

```ts
engine.addSystem(() => {
	const cmd = inputSystem.getInputCommand(
		InputAction.IA_POINTER,
		PointerEventType.PET_DOWN,
		myEntity
	)
	if (cmd && cmd.hit?.meshName === 'firePlace') {
		// 불을 켜기
	}
})
```

{% hint style="warning" %}
**📔 참고**: 이는 포인터 기반 이벤트에만 적용되며, 근접 기반 이벤트에는 적용되지 않습니다. 근접 기반 이벤트의 경우 모델의 모든 메시가 한 번에 플레이어 근처에 있을 수 있기 때문입니다.
{% 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.decentraland.org/creator/content-creator-ko/sdk7/interactivity/button-events/system-based-events.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
