73 lines
2.6 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|