添加缺失插件

This commit is contained in:
YXY
2026-03-03 18:24:17 +08:00
parent d43882c5cf
commit c979cd2a92
90 changed files with 5269 additions and 0 deletions

View 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);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e3033df7ea093054e9c40a63f316e687
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7877962557443e34f8190e3278bd4a5d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: