> 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/proximity-events.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) 자세한 내용은 다음을 참조하세요.

## 근접 콜백 등록

그 `pointerEventsSystem` 근접 이벤트를 위한 헬퍼 함수를 포함하며, 다음과 같은 패턴을 따릅니다. [포인터 이벤트 콜백](/creator/content-creator-ko/sdk7/interactivity/button-events/register-callback.md).

### 근접 버튼 누르기

사용: `pointerEventsSystem.onProximityDown` 플레이어가 범위 내에 있을 때 버튼 누르기를 감지하기 위해 사용됩니다. 반면 `onPointerDown`, 이것은 플레이어가 커서를 엔티티에 맞출 필요가 없습니다.

```ts
pointerEventsSystem.onProximityDown(
    {
        entity: myEntity,
        opts: {
            button: InputAction.IA_PRIMARY,
            hoverText: 'Press E',
            maxDistance: 5,
        },
    },
    function () {
        console.log('Player pressed button near entity')
    }
)
```

사용: `pointerEventsSystem.onProximityUp` 를 사용해 플레이어가 범위 안에 있을 때 버튼을 놓는 순간을 감지합니다.

```ts
pointerEventsSystem.onProximityUp(
    {
        entity: myEntity,
        opts: {
            button: InputAction.IA_PRIMARY,
            hoverText: 'E 키를 놓으세요',
            maxDistance: 5,
        },
    },
    function () {
        console.log('플레이어가 엔티티 근처에서 버튼을 놓았습니다')
    }
)
```

{% hint style="warning" %}
**📔 참고**: 하나의 `onProximityDown` 와 하나의 `onProximityUp` 만 엔티티마다 등록할 수 있습니다. 한 번 추가되면 제거될 때까지 계속 감지합니다. 시스템 루프 안에서 이들을 호출하지 마세요. 그러면 동작이 계속 덮어써지기 때문입니다.
{% endhint %}

## 근접 이벤트 유형

다음에 두 가지 새 값이 추가되었습니다. `PointerEventType` 열거형의 다음 값 중 하나입니다:

* `PET_PROXIMITY_ENTER`: 플레이어가 엔티티의 근접 범위 안으로 들어오면 트리거됩니다.
* `PET_PROXIMITY_LEAVE`: 플레이어가 엔티티의 근접 범위 밖으로 나가면 트리거됩니다.

이것들은 다음과 함께 사용할 수 있습니다. `PointerEvents` 컴포넌트와 `inputSystem` 에 대한 [시스템 기반 접근 방식](/creator/content-creator-ko/sdk7/interactivity/button-events/system-based-events.md#proximity-events). 이 접근 방식은 다음을 사용한 근접 버튼 누르기도 지원합니다. `InteractionType.PROXIMITY` 필드에 붙여 넣어 자체 스트리밍 인프라를 지정하세요.

## 우선순위

여러 엔티티가 범위 내에 있고 같은 입력에 응답할 수 있을 때는 하나만 활성화되며, 기본적으로 가장 가까운 것이 선택됩니다. 다음을 사용해 `우선순위` 필드로 어떤 것이 우선하는지 제어하세요. 우선순위 값이 **더 높은 숫자를** 가지는 엔티티가 먼저 응답합니다.

플레이어가 근접 상호작용이 있는 엔티티의 범위 안에 있으면서 동시에 플레이어의 커서가 포인터 상호작용이 있는 엔티티를 가리키는 경우, 포인터 상호작용이 있는 엔티티가 항상 우선합니다. 다시 말하지만, 활성화되는 엔티티는 하나뿐입니다.

```ts
pointerEventsSystem.onProximityDown(
    {
        entity: doorEntity,
        opts: {
            button: InputAction.IA_PRIMARY,
            hoverText: '문 열기',
            maxDistance: 5,
            priority: 2,
        },
    },
    function () {
        console.log('문이 활성화됨')
    }
)

pointerEventsSystem.onProximityDown(
    {
        entity: floorEntity,
        opts: {
            button: InputAction.IA_PRIMARY,
            hoverText: '여기에 서기',
            maxDistance: 5,
            priority: 1,
        },
    },
    function () {
        console.log('바닥이 활성화됨')
    }
)
```

위의 예시에서는 두 엔티티가 모두 범위 내에 있더라도, 문 엔티티가 더 높은 우선순위를 가지므로 응답합니다.

그 `우선순위` 필드는 ...의 속성에서도 설정할 수 있습니다. `PointerEvents` 컴포넌트를 부여해야 합니다.

## 옵션

근접 헬퍼 함수는 포인터 대응 함수와 동일한 옵션을 받습니다:

* `버튼`: 어떤 버튼을 감지할지 지정합니다. 참고 [포인터 버튼](/creator/content-creator-ko/sdk7/interactivity/button-events/click-events.md#pointer-buttons) 지원되는 옵션은 다음을 참조하세요.
* `maxDistance`: 플레이어의 **아바타** 엔티티까지의 최대 거리(미터 단위). 기본값은 10입니다.
* `hoverText`: 플레이어가 엔티티 근처에 있을 때 UI에 표시할 텍스트.
* `showHighlight`: true이면 플레이어가 범위 내에 있을 때 엔티티에 가장자리 하이라이트를 표시합니다. *true* 항목만 내보냅니다.
* `showFeedback`: true이면 엔티티 중심 주변에 호버 피드백을 표시합니다. *true* 항목만 내보냅니다.
* `우선순위`: 여러 엔티티가 근접해 있을 때 충돌을 해결합니다. 더 높은 값이 우선합니다. 여러 엔티티의 우선순위 값이 같으면 가장 가까운 엔티티가 선택됩니다.

`maxPlayerDistance` 는 다음의 더 이상 사용되지 않는 별칭입니다: `maxDistance`. 둘 다 아바타를 기준으로 거리를 측정하므로, 다음을 사용하세요 `maxDistance` 새 장면에서

### 범위 내로 간주되는 조건

근접 이벤트는 **플레이어 캡슐의 중심**, 대략 가슴 높이에서 엔티티 콜라이더의 가장 가까운 지점까지를 측정합니다. 이는 커서 클릭이 측정하는 지점보다 약 1미터 위이므로, 같은 위치라도 각 경로에서 약간 다른 거리로 읽힐 수 있습니다.

거리만으로는 충분하지 않습니다. 근접 이벤트를 발생시키려면 플레이어는 또한:

* 되기 **정면을 향하기** 엔티티를, 전방 약 120도의 원뿔 범위 안에서.
* 가져야 **명확한 시야** 를 확보해야 하며, 그 사이에 아무것도 없어야 합니다.

{% hint style="warning" %}
**📔 참고**: 근접 이벤트는 `maxCameraDistance`. 카메라가 어디에 있든 차이는 없습니다. 아바타의 거리, 정면 방향, 시야선만 고려됩니다. 참고 [거리 제한](/creator/content-creator-ko/sdk7/interactivity/button-events/register-callback.md#distance-limits) 커서 이벤트에서 카메라 제한이 어떻게 작동하는지.
{% endhint %}

## 콜백 제거

근접 콜백을 제거하려면 해당하는 remove 함수를 사용하세요:

```ts
pointerEventsSystem.removeOnProximityDown(myEntity)
pointerEventsSystem.removeOnProximityUp(myEntity)
pointerEventsSystem.removeOnProximityEnter(myEntity)
pointerEventsSystem.removeOnProximityLeave(myEntity)
```

한 번 제거되면 엔티티는 더 이상 해당 근접 이벤트에 반응하지 않습니다.

## 근접 진입 및 이탈

사용: `pointerEventsSystem.onProximityEnter` 를 사용해 플레이어가 엔티티의 근접 범위 안으로 들어올 때 콜백을 실행하고, `pointerEventsSystem.onProximityLeave` 를 사용해 플레이어가 나갈 때 실행합니다. 이는 아이템과 상호작용할 수 있을 때 소리나 애니메이션 같은 추가 피드백 힌트를 플레이어에게 표시하는 데 사용할 수 있습니다.

```ts
pointerEventsSystem.onProximityEnter(
    {
        entity: myEntity,
        opts: {
            button: InputAction.IA_POINTER,
            hoverText: '근처',
            maxDistance: 5,
        },
    },
    function () {
        console.log('Player entered proximity')
    }
)

pointerEventsSystem.onProximityLeave(
    {
        entity: myEntity,
        opts: {
            button: InputAction.IA_POINTER,
            hoverText: '근처',
            maxDistance: 5,
        },
    },
    function () {
        console.log('Player left proximity')
    }
)
```

## 예시: 근접 문

다음 예시는 플레이어가 근처에 서 있을 때 버튼을 누르면 문을 열거나 닫습니다. 문을 바라볼 필요는 없습니다.

```ts
const doorPivot = engine.addEntity()
Transform.create(doorPivot, { position: Vector3.create(3, 0, 4) })

const door = engine.addEntity()
GltfContainer.create(door, { src: 'assets/door.glb' })
Transform.create(door, { position: Vector3.create(-1, 0, 0), parent: doorPivot })

let isDoorOpen = false
const closedRot = Quaternion.fromEulerDegrees(0, 0, 0)
const openRot = Quaternion.fromEulerDegrees(0, 90, 0)

pointerEventsSystem.onProximityDown(
    {
        entity: door,
        opts: {
            button: InputAction.IA_PRIMARY,
            hoverText: '열기 / 닫기',
            maxDistance: 5,
            priority: 1,
        },
    },
    function () {
        if (isDoorOpen) {
            Tween.setRotate(doorPivot, openRot, closedRot, 700)
            isDoorOpen = false
        } else {
            Tween.setRotate(doorPivot, closedRot, openRot, 700)
            isDoorOpen = true
        }
    }
)
```


---

# 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/proximity-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.
