using UnityEngine; using UnityEngine.XR.Interaction.Toolkit; namespace LevelUp.GrabInteractions { [RequireComponent(typeof(UnityEngine.XR.Interaction.Toolkit.Interactables.XRGrabInteractable))] public class ResetObject : MonoBehaviour { [Header("基础重置设置")] [Tooltip("物体返回原位之前的延迟时间 (秒)。")] [SerializeField] protected float resetDelayTime = 3f; protected UnityEngine.XR.Interaction.Toolkit.Interactables.XRGrabInteractable m_GrabInteractable; protected Vector3 returnToPosition; protected Quaternion returnToRotation; protected Rigidbody m_Rigidbody; [Tooltip("指示物体是否应该被重置。子类可用于逻辑判断。")] public bool shouldReturnHome { get; protected set; } = true; public AudioSource downAudio; protected void Awake() { m_GrabInteractable = GetComponent(); m_Rigidbody = GetComponent(); } protected void Start() { returnToPosition = this.transform.position; returnToRotation = this.transform.rotation; } void OnEnable() { if (m_GrabInteractable != null) { m_GrabInteractable.selectExited.AddListener(OnSelectExit); m_GrabInteractable.selectEntered.AddListener(OnSelect); } } void OnDisable() { if (m_GrabInteractable != null) { m_GrabInteractable.selectExited.RemoveListener(OnSelectExit); m_GrabInteractable.selectEntered.RemoveListener(OnSelect); } CancelInvoke(nameof(ReturnHome)); } protected virtual void OnSelect(SelectEnterEventArgs arg0) { CancelInvoke(nameof(ReturnHome)); } protected virtual void OnSelectExit(SelectExitEventArgs arg0) { Invoke(nameof(ReturnHome), resetDelayTime); if (downAudio != null) downAudio.Play(); } protected virtual void ReturnHome() { if (shouldReturnHome) { if (m_Rigidbody != null && !m_Rigidbody.isKinematic) { m_Rigidbody.velocity = Vector3.zero; m_Rigidbody.angularVelocity = Vector3.zero; } transform.position = returnToPosition; transform.rotation = returnToRotation; Debug.Log($"物体 '{gameObject.name}' 已瞬移重置到原点。", this); } } } }