Files
Shopping_UnityVR/Assets/02_Scripts/Item/TastingSample.cs

73 lines
2.6 KiB
C#

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<XRGrabInteractable>();
}
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<PlayerHunger>() : 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);
}
}
}