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(); var target = body != null ? body.gameObject : gameObject; _onConsumed?.Invoke(); if (_destroy) Destroy(target); // XRGrabInteractable도 파괴 시 손에서 자동 해제됨 else target.SetActive(false); // 비활성화도 XRI가 선택을 취소해 손에서 놓게 됨 } }