Files
2026-07-23 13:08:43 +09:00

56 lines
2.7 KiB
C#

using UnityEngine;
using UnityEngine.Events;
// 대화 중 "건네기/터치" 제스처를 수행하는 오브젝트(꽃다발·김치·손 등)에 붙인다.
// 이 오브젝트가 NPC의 받는 존(_targetTag 태그의 트리거)에 닿으면, 자신의 GestureKey로 히든 분기를 발동시킨다.
//
// 어떤 아이템인지는 GestureKey로 구분된다:
// - 노드가 HiddenGestureKey="kimchi"로 무장 → 김치(GestureKey="kimchi")만 발동, 꽃다발("bouquet")은 무시.
// 그래서 "김치를 줘야 하는데 꽃다발을 주면 이벤트가 안 진행"이 자동으로 보장된다.
//
// 콜라이더가 있는 오브젝트에 붙일 것 (잡는 아이템은 보통 XRGrabInteractable이 있는 루트).
// 존은 무장 여부와 무관하게 항상 닿을 수 있지만, 무장 안 된 순간에 닿으면 아무 일도 안 일어난다.
public class DialogGestureItem : MonoBehaviour
{
[Tooltip("이 오브젝트의 제스처 키. 대화 노드의 HiddenGestureKey와 일치할 때만 발동 (예: kimchi, bouquet, slap)")]
[SerializeField] private string _gestureKey;
[Tooltip("이 태그를 가진 트리거(NPC 받는 존)에 닿아야 발동. 비우면 태그 무시(아무 트리거나)")]
[SerializeField] private string _targetTag = "GiveZone";
[Header("Consume (건넨 뒤 사라지게)")]
[Tooltip("켜면 발동 시 이 오브젝트가 사라진다(건넨 연출). 손처럼 사라지면 안 되는 건 꺼둘 것")]
[SerializeField] private bool _consumeOnGiven = true;
[Tooltip("사라지는 방식: 켜면 완전 파괴(Destroy), 끄면 비활성화(SetActive false — 재사용 가능)")]
[SerializeField] private bool _destroy = true;
[Tooltip("사라지기 직전 호출 (파티클·사운드 연출용)")]
[SerializeField] private UnityEvent _onConsumed;
private void OnTriggerEnter(Collider other)
{
if (!string.IsNullOrEmpty(_targetTag) && !other.CompareTag(_targetTag)) return;
// 노드가 이 키로 무장 중일 때만 true — 그때만 소비한다(엉뚱한 타이밍/엉뚱한 아이템은 안 사라짐).
if (!HiddenBranchResolver.Fire(_gestureKey)) return;
if (_consumeOnGiven)
Consume();
}
private void Consume()
{
// 스크립트가 자식 콜라이더에 붙어 있어도 아이템 전체(Rigidbody 루트)를 처리
var body = GetComponentInParent<Rigidbody>();
var target = body != null ? body.gameObject : gameObject;
_onConsumed?.Invoke();
if (_destroy)
Destroy(target); // XRGrabInteractable도 파괴 시 손에서 자동 해제됨
else
target.SetActive(false); // 비활성화도 XRI가 선택을 취소해 손에서 놓게 됨
}
}