65 lines
2.2 KiB
C#
65 lines
2.2 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 AudioSource _sfxSource;
|
|
private bool _consumed;
|
|
|
|
private void Awake()
|
|
{
|
|
_grab = GetComponent<XRGrabInteractable>();
|
|
_sfxSource = GetComponent<AudioSource>();
|
|
}
|
|
|
|
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()
|
|
{
|
|
_consumed = true;
|
|
|
|
if (PlayerHunger.Instance != null)
|
|
PlayerHunger.Instance.Eat(_foodData.HungerRestoreAmount);
|
|
|
|
// 손에서 강제 해제 (잡혀있던 상태로 Destroy되면 XRI 경고)
|
|
if (_grab != null && _grab.isSelected && _grab.interactionManager != null)
|
|
_grab.interactionManager.CancelInteractableSelection((UnityEngine.XR.Interaction.Toolkit.Interactables.IXRSelectInteractable)_grab);
|
|
|
|
// SFX 재생 후 파괴 (사운드 길이 고려)
|
|
var sfx = _foodData.EatSfx;
|
|
if (sfx != null)
|
|
{
|
|
AudioSource.PlayClipAtPoint(sfx, transform.position);
|
|
}
|
|
|
|
Destroy(gameObject);
|
|
}
|
|
}
|
|
}
|