물품들 상호작용 달기

This commit is contained in:
2026-07-17 12:45:12 +09:00
parent ad6ccadc8e
commit fc06825972
23 changed files with 229 additions and 26 deletions

View File

@@ -0,0 +1,67 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
// "지정한 물건들을 전부 이 존 안으로 옮기기" 목표.
// 트리거 콜라이더가 붙은 존 오브젝트에 추가하고 물건들을 목록에 등록한다.
// 물건 쪽에 Rigidbody가 있어야 트리거 이벤트가 발생한다 (XRGrabInteractable이면 이미 있음).
[RequireComponent(typeof(Collider))]
public class MoveItemsToZoneObjective : MissionObjective
{
[Tooltip("이 존 안으로 옮겨야 하는 물건들 (씬 오브젝트 루트)")]
[SerializeField] private List<Transform> _requiredItems = new();
[Tooltip("들어온 개수가 바뀔 때마다 (현재 개수, 전체 개수) — 진행 UI 연결용")]
public UnityEvent<int, int> OnCountChanged;
[Tooltip("대사 텍스트에서 {키}로 진행 상황을 쓰려면 키 이름 지정 (값 예: \"3/5\"). 비우면 안 씀")]
[SerializeField] private string _dialogVariableKey;
private readonly HashSet<Transform> _inside = new();
public int Count => _inside.Count;
public int Total => _requiredItems.Count;
public override bool IsComplete => Count >= Total;
private void Awake()
{
var col = GetComponent<Collider>();
if (!col.isTrigger)
Debug.LogWarning($"[MoveItemsToZoneObjective] 콜라이더가 트리거가 아님: {name}");
}
private void Start() => Publish(); // UI/대사 변수 초기값 (0/N)
private void OnTriggerEnter(Collider other)
{
var item = FindRequiredItem(other);
if (item != null && _inside.Add(item)) Publish();
}
private void OnTriggerExit(Collider other)
{
var item = FindRequiredItem(other);
if (item != null && _inside.Remove(item)) Publish();
}
// 콜라이더에서 등록된 물건을 찾는다 (자식 콜라이더 대응 — 부모로 거슬러 올라가며 확인)
private Transform FindRequiredItem(Collider col)
{
var t = col.attachedRigidbody != null ? col.attachedRigidbody.transform : col.transform;
while (t != null)
{
if (_requiredItems.Contains(t)) return t;
t = t.parent;
}
return null;
}
private void Publish()
{
_inside.RemoveWhere(t => t == null); // 파괴된 물건 정리
if (!string.IsNullOrEmpty(_dialogVariableKey))
DialogVariables.Set(_dialogVariableKey, $"{Count}/{Total}");
OnCountChanged?.Invoke(Count, Total);
RaiseChanged();
}
}