添加缺失插件
This commit is contained in:
79
Assets/YOMOV Access/Scripts/ResetObject.cs
Normal file
79
Assets/YOMOV Access/Scripts/ResetObject.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
// 假设命名空间是 LevelUp.GrabInteractions
|
||||
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;
|
||||
|
||||
[Tooltip("指示物体是否应该被重置。子类可用于逻辑判断。")]
|
||||
public bool shouldReturnHome { get; protected set; } = true;
|
||||
|
||||
protected void Awake()
|
||||
{
|
||||
m_GrabInteractable = GetComponent<UnityEngine.XR.Interaction.Toolkit.Interactables.XRGrabInteractable>();
|
||||
}
|
||||
|
||||
protected void Start()
|
||||
{
|
||||
// 记录物体在场景中的初始位置
|
||||
returnToPosition = this.transform.position;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// 抓取时取消任何待执行的 ReturnHome 调用
|
||||
CancelInvoke(nameof(ReturnHome));
|
||||
}
|
||||
|
||||
protected virtual void OnSelectExit(SelectExitEventArgs arg0)
|
||||
{
|
||||
// 松手时延迟调用 ReturnHome
|
||||
Invoke(nameof(ReturnHome), resetDelayTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 核心重置函数。设置为 virtual 以便子类重写。
|
||||
/// 默认实现为瞬移。
|
||||
/// </summary>
|
||||
protected virtual void ReturnHome()
|
||||
{
|
||||
if (shouldReturnHome)
|
||||
{
|
||||
// 父类的默认实现是瞬移
|
||||
transform.position = returnToPosition;
|
||||
Debug.Log($"物体 '{gameObject.name}' 已瞬移重置到原点。", this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/YOMOV Access/Scripts/ResetObject.cs.meta
Normal file
11
Assets/YOMOV Access/Scripts/ResetObject.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3033df7ea093054e9c40a63f316e687
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
110
Assets/YOMOV Access/Scripts/ResetObjectSmooth.cs
Normal file
110
Assets/YOMOV Access/Scripts/ResetObjectSmooth.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
using System.Collections;
|
||||
|
||||
namespace LevelUp.GrabInteractions
|
||||
{
|
||||
public class ResetObjectSmooth : ResetObject
|
||||
{
|
||||
[Header("平滑重置设置")]
|
||||
[SerializeField] private float resetSpeed = 5f;
|
||||
[SerializeField] private float stopDistance = 0.01f;
|
||||
|
||||
private Quaternion returnToRotation;
|
||||
private Rigidbody rb;
|
||||
private Coroutine smoothMoveCoroutine;
|
||||
private bool initialIsKinematic;
|
||||
// 新增:用于备份物理插值设置
|
||||
private RigidbodyInterpolation initialInterpolation;
|
||||
|
||||
protected new void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
rb = GetComponent<Rigidbody>();
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
base.Start();
|
||||
returnToRotation = transform.rotation;
|
||||
|
||||
if (rb != null)
|
||||
{
|
||||
initialIsKinematic = rb.isKinematic;
|
||||
initialInterpolation = rb.interpolation; // 记录初始插值状态
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestroy() => StopAllCoroutinesAndCancelInvoke();
|
||||
|
||||
private void StopAllCoroutinesAndCancelInvoke()
|
||||
{
|
||||
CancelInvoke(nameof(ReturnHome));
|
||||
if (smoothMoveCoroutine != null)
|
||||
{
|
||||
StopCoroutine(smoothMoveCoroutine);
|
||||
smoothMoveCoroutine = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnSelect(SelectEnterEventArgs arg0) => StopAllCoroutinesAndCancelInvoke();
|
||||
|
||||
protected override void OnSelectExit(SelectExitEventArgs arg0)
|
||||
{
|
||||
StopAllCoroutinesAndCancelInvoke();
|
||||
if (rb != null)
|
||||
{
|
||||
rb.isKinematic = false;
|
||||
rb.WakeUp();
|
||||
}
|
||||
base.OnSelectExit(arg0);
|
||||
}
|
||||
|
||||
protected override void ReturnHome()
|
||||
{
|
||||
if (shouldReturnHome)
|
||||
smoothMoveCoroutine = StartCoroutine(SmoothMoveToHome());
|
||||
}
|
||||
|
||||
private IEnumerator SmoothMoveToHome()
|
||||
{
|
||||
if (rb != null)
|
||||
{
|
||||
// 【关键优化 1】禁用物理插值,防止物理引擎尝试预测物体的 Transform 更新
|
||||
rb.interpolation = RigidbodyInterpolation.None;
|
||||
rb.isKinematic = true;
|
||||
rb.velocity = Vector3.zero;
|
||||
rb.angularVelocity = Vector3.zero;
|
||||
}
|
||||
|
||||
float stopDistanceSqr = stopDistance * stopDistance;
|
||||
|
||||
while ((transform.position - returnToPosition).sqrMagnitude > stopDistanceSqr)
|
||||
{
|
||||
float lerpFactor = 1f - Mathf.Exp(-resetSpeed * Time.deltaTime);
|
||||
|
||||
transform.position = Vector3.Lerp(transform.position, returnToPosition, lerpFactor);
|
||||
transform.rotation = Quaternion.Slerp(transform.rotation, returnToRotation, lerpFactor);
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
transform.position = returnToPosition;
|
||||
transform.rotation = returnToRotation;
|
||||
|
||||
// 【关键优化 2】在恢复物理属性前,等待一个物理帧,确保位置同步完成
|
||||
yield return new WaitForFixedUpdate();
|
||||
|
||||
if (rb != null)
|
||||
{
|
||||
rb.isKinematic = initialIsKinematic;
|
||||
// 【关键优化 3】恢复初始插值设置
|
||||
rb.interpolation = initialInterpolation;
|
||||
rb.velocity = Vector3.zero;
|
||||
rb.angularVelocity = Vector3.zero;
|
||||
}
|
||||
|
||||
smoothMoveCoroutine = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/YOMOV Access/Scripts/ResetObjectSmooth.cs.meta
Normal file
11
Assets/YOMOV Access/Scripts/ResetObjectSmooth.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7877962557443e34f8190e3278bd4a5d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user