using UnityEngine; using UnityEngine.XR.Interaction.Toolkit.Interactables; using VRShopping.Data.Food; using VRShopping.Player; namespace VRShopping.Items { // 시식 코너의 샘플. XRGrabInteractable로 잡을 수 있고, // 잡은 상태에서 메인 카메라(=입) 근처로 가져가면 먹힌다. [RequireComponent(typeof(XRGrabInteractable))] public class TastingSample : MonoBehaviour { [SerializeField] private FoodData _foodData; // 입(메인 카메라)으로 인정할 거리 (m) [SerializeField, Min(0.05f)] private float _eatDistance = 0.25f; // 잡혀있지 않아도 먹을 수 있게 할지 (기본은 잡은 상태에서만) [SerializeField] private bool _requireGrabbed = true; private XRGrabInteractable _grab; private bool _consumed; private void Awake() { _grab = GetComponent(); } private void Update() { if (_consumed || _foodData == null) return; if (_requireGrabbed && (_grab == null || !_grab.isSelected)) return; var cam = Camera.main; if (cam == null) return; float distSqr = (cam.transform.position - transform.position).sqrMagnitude; if (distSqr <= _eatDistance * _eatDistance) Consume(); } private void Consume() { var interactor = _grab.firstInteractorSelecting as MonoBehaviour; _consumed = true; // 손에서 강제 해제 (잡혀있던 상태로 Destroy되면 XRI 경고) if (_grab != null && _grab.isSelected && _grab.interactionManager != null) _grab.interactionManager.CancelInteractableSelection((UnityEngine.XR.Interaction.Toolkit.Interactables.IXRSelectInteractable)_grab); PlayerHunger hunger = interactor != null ? interactor.GetComponentInParent() : null; if(hunger != null) { hunger.Eat(_foodData.HungerRestoreAmount); } // VFX/SFX는 임시 오브젝트로 분리 재생 — 본체가 즉시 Destroy되어도 끊기지 않음 if (_foodData.EatVfx != null) { var vfx = Instantiate(_foodData.EatVfx, transform.position, Quaternion.identity); vfx.Play(); var main = vfx.main; Destroy(vfx.gameObject, main.duration + main.startLifetime.constantMax); } if (_foodData.EatSfx != null) AudioSource.PlayClipAtPoint(_foodData.EatSfx, transform.position); Destroy(gameObject); } } }