물품들 상호작용 달기
This commit is contained in:
67
Assets/02_Scripts/Mission/MoveItemsToZoneObjective.cs
Normal file
67
Assets/02_Scripts/Mission/MoveItemsToZoneObjective.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user