添加缺失插件
This commit is contained in:
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user