提交S1交互

This commit is contained in:
YXY
2026-03-06 16:12:16 +08:00
parent ad3cc8e142
commit 3e39007e2c
12 changed files with 6760 additions and 2637 deletions

View File

@@ -685,7 +685,6 @@ GameObject:
- component: {fileID: 8509482752666057137}
- component: {fileID: 8509482752666057138}
- component: {fileID: 627173790550441048}
- component: {fileID: 5834868979677824056}
m_Layer: 0
m_Name: one
m_TagString: Untagged
@@ -706,9 +705,8 @@ Transform:
m_LocalScale: {x: 0.1456549, y: 0.22635013, z: 0.43100396}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 4555733331637449516}
- {fileID: 1681761156176125940}
- {fileID: 7729090350392879857}
- {fileID: 4555733331637449516}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &8509482752666057134
@@ -931,20 +929,6 @@ BoxCollider:
serializedVersion: 3
m_Size: {x: 1, y: 1, z: 1}
m_Center: {x: 0, y: 0, z: 0}
--- !u!114 &5834868979677824056
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8509482752666057141}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e3033df7ea093054e9c40a63f316e687, type: 3}
m_Name:
m_EditorClassIdentifier:
resetDelayTime: 2
downAudio: {fileID: 374519139915588587}
--- !u!1 &8596264351910424411
GameObject:
m_ObjectHideFlags: 0
@@ -1079,13 +1063,28 @@ PrefabInstance:
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 8509482752666057140}
m_TransformParent: {fileID: 7729090350392879857}
m_Modifications:
- target: {fileID: 314259139610439016, guid: 9a5f820ee9c46b64294ae756b459a681,
type: 3}
propertyPath: m_RootOrder
value: 1
objectReference: {fileID: 0}
- target: {fileID: 314259139610439016, guid: 9a5f820ee9c46b64294ae756b459a681,
type: 3}
propertyPath: m_LocalScale.x
value: 0.1456549
objectReference: {fileID: 0}
- target: {fileID: 314259139610439016, guid: 9a5f820ee9c46b64294ae756b459a681,
type: 3}
propertyPath: m_LocalScale.y
value: 0.22635016
objectReference: {fileID: 0}
- target: {fileID: 314259139610439016, guid: 9a5f820ee9c46b64294ae756b459a681,
type: 3}
propertyPath: m_LocalScale.z
value: 0.43100402
objectReference: {fileID: 0}
- target: {fileID: 314259139610439016, guid: 9a5f820ee9c46b64294ae756b459a681,
type: 3}
propertyPath: m_LocalPosition.x
@@ -1094,7 +1093,7 @@ PrefabInstance:
- target: {fileID: 314259139610439016, guid: 9a5f820ee9c46b64294ae756b459a681,
type: 3}
propertyPath: m_LocalPosition.y
value: 0
value: -0.0016000271
objectReference: {fileID: 0}
- target: {fileID: 314259139610439016, guid: 9a5f820ee9c46b64294ae756b459a681,
type: 3}
@@ -1109,17 +1108,17 @@ PrefabInstance:
- target: {fileID: 314259139610439016, guid: 9a5f820ee9c46b64294ae756b459a681,
type: 3}
propertyPath: m_LocalRotation.x
value: 0
value: -0
objectReference: {fileID: 0}
- target: {fileID: 314259139610439016, guid: 9a5f820ee9c46b64294ae756b459a681,
type: 3}
propertyPath: m_LocalRotation.y
value: 0
value: -0
objectReference: {fileID: 0}
- target: {fileID: 314259139610439016, guid: 9a5f820ee9c46b64294ae756b459a681,
type: 3}
propertyPath: m_LocalRotation.z
value: 0
value: -0
objectReference: {fileID: 0}
- target: {fileID: 314259139610439016, guid: 9a5f820ee9c46b64294ae756b459a681,
type: 3}
@@ -1280,6 +1279,10 @@ PrefabInstance:
type: 3}
insertIndex: -1
addedObject: {fileID: 8770507455043884786}
- targetCorrespondingSourceObject: {fileID: 4595984943260027875, guid: d6447efa977a5af4581b3cd2b345dfb2,
type: 3}
insertIndex: -1
addedObject: {fileID: 1681761156176125940}
m_AddedComponents:
- targetCorrespondingSourceObject: {fileID: 2291043302450215876, guid: d6447efa977a5af4581b3cd2b345dfb2,
type: 3}
@@ -1293,6 +1296,14 @@ PrefabInstance:
type: 3}
insertIndex: -1
addedObject: {fileID: 2578186882713754604}
- targetCorrespondingSourceObject: {fileID: 2291043302450215876, guid: d6447efa977a5af4581b3cd2b345dfb2,
type: 3}
insertIndex: -1
addedObject: {fileID: 5890687175110443383}
- targetCorrespondingSourceObject: {fileID: 2291043302450215876, guid: d6447efa977a5af4581b3cd2b345dfb2,
type: 3}
insertIndex: -1
addedObject: {fileID: 858447791395049142}
m_SourcePrefab: {fileID: 100100000, guid: d6447efa977a5af4581b3cd2b345dfb2, type: 3}
--- !u!1 &5422442747364301526 stripped
GameObject:
@@ -1343,9 +1354,9 @@ Rigidbody:
m_Bits: 0
m_ImplicitCom: 1
m_ImplicitTensor: 1
m_UseGravity: 0
m_UseGravity: 1
m_IsKinematic: 0
m_Interpolate: 0
m_Interpolate: 1
m_Constraints: 0
m_CollisionDetection: 0
--- !u!114 &2578186882713754604
@@ -1368,6 +1379,149 @@ MonoBehaviour:
cathcAudio: {fileID: 5272202333828909323}
downAudio: {fileID: 374519139915588587}
effectHideAndShowCtr: {fileID: 8608594464241683254}
--- !u!114 &5890687175110443383
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5422442747364301526}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0ad34abafad169848a38072baa96cdb2, type: 3}
m_Name:
m_EditorClassIdentifier:
m_InteractionManager: {fileID: 0}
m_Colliders: []
m_InteractionLayers:
m_Bits: 1
m_DistanceCalculationMode: 1
m_SelectMode: 0
m_FocusMode: 1
m_CustomReticle: {fileID: 0}
m_AllowGazeInteraction: 0
m_AllowGazeSelect: 0
m_OverrideGazeTimeToSelect: 0
m_GazeTimeToSelect: 0.5
m_OverrideTimeToAutoDeselectGaze: 0
m_TimeToAutoDeselectGaze: 3
m_AllowGazeAssistance: 0
m_FirstHoverEntered:
m_PersistentCalls:
m_Calls: []
m_LastHoverExited:
m_PersistentCalls:
m_Calls: []
m_HoverEntered:
m_PersistentCalls:
m_Calls: []
m_HoverExited:
m_PersistentCalls:
m_Calls: []
m_FirstSelectEntered:
m_PersistentCalls:
m_Calls: []
m_LastSelectExited:
m_PersistentCalls:
m_Calls: []
m_SelectEntered:
m_PersistentCalls:
m_Calls: []
m_SelectExited:
m_PersistentCalls:
m_Calls: []
m_FirstFocusEntered:
m_PersistentCalls:
m_Calls: []
m_LastFocusExited:
m_PersistentCalls:
m_Calls: []
m_FocusEntered:
m_PersistentCalls:
m_Calls: []
m_FocusExited:
m_PersistentCalls:
m_Calls: []
m_Activated:
m_PersistentCalls:
m_Calls: []
m_Deactivated:
m_PersistentCalls:
m_Calls: []
m_StartingHoverFilters: []
m_StartingSelectFilters: []
m_StartingInteractionStrengthFilters: []
m_AttachTransform: {fileID: 4555733331637449516}
m_SecondaryAttachTransform: {fileID: 0}
m_UseDynamicAttach: 1
m_MatchAttachPosition: 1
m_MatchAttachRotation: 1
m_SnapToColliderVolume: 1
m_ReinitializeDynamicAttachEverySingleGrab: 1
m_AttachEaseInTime: 0.15
m_MovementType: 2
m_VelocityDamping: 1
m_VelocityScale: 1
m_AngularVelocityDamping: 1
m_AngularVelocityScale: 1
m_TrackPosition: 1
m_SmoothPosition: 1
m_SmoothPositionAmount: 5
m_TightenPosition: 0.1
m_TrackRotation: 1
m_SmoothRotation: 1
m_SmoothRotationAmount: 5
m_TightenRotation: 0.1
m_TrackScale: 1
m_SmoothScale: 1
m_SmoothScaleAmount: 5
m_TightenScale: 0.1
m_ThrowOnDetach: 1
m_ThrowSmoothingDuration: 0.25
m_ThrowSmoothingCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 1
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
m_ThrowVelocityScale: 1.5
m_ThrowAngularVelocityScale: 1
m_ForceGravityOnDetach: 0
m_RetainTransformParent: 1
m_StartingSingleGrabTransformers: []
m_StartingMultipleGrabTransformers: []
m_AddDefaultGrabTransformers: 1
m_FarAttachMode: 0
--- !u!65 &858447791395049142
BoxCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5422442747364301526}
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_IsTrigger: 0
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 3
m_Size: {x: 1, y: 1, z: 1}
m_Center: {x: 0, y: 0, z: 0}
--- !u!4 &7729090350392879857 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 4595984943260027875, guid: d6447efa977a5af4581b3cd2b345dfb2,

View File

@@ -1,110 +0,0 @@
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,141 @@
using System.Collections;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
using UnityEngine.XR.Interaction.Toolkit.Interactables;
/// <summary>
/// 抓取后松手归回原位(替代 ResetObjectSmooth避免模型拉伸
/// 同一 GameObject 需要挂 XRGrabInteractable。
/// 可选:挂 EffectHideAndShowCtr 实现溶解消失/出现效果。
/// </summary>
[RequireComponent(typeof(XRGrabInteractable))]
public class ReturnPosition : MonoBehaviour
{
[Header("归位设置")]
[SerializeField] private float resetDelayTime = 2f; // 松手后延迟归位秒数
[SerializeField] private EffectHideAndShowCtr effectCtr; // 溶解效果(可为空)
[SerializeField] private float dissolveDuration = 1f; // 溶解动画时长
[Header("音效")]
public AudioSource grabAudio;
public AudioSource releaseAudio;
// 归位目标(启动时记录)
private Vector3 m_returnPos;
private Quaternion m_returnRot;
private XRGrabInteractable m_grab;
private Rigidbody m_rb;
private Coroutine m_resetCoroutine;
private void Awake()
{
m_grab = GetComponent<XRGrabInteractable>();
m_rb = GetComponent<Rigidbody>();
}
private void Start()
{
// 记录初始世界坐标作为归位目标
m_returnPos = transform.position;
m_returnRot = transform.rotation;
}
private void OnEnable()
{
m_grab.selectEntered.AddListener(OnSelectEntered);
m_grab.selectExited.AddListener(OnSelectExited);
}
private void OnDisable()
{
m_grab.selectEntered.RemoveListener(OnSelectEntered);
m_grab.selectExited.RemoveListener(OnSelectExited);
}
// ── XRI 事件 ──────────────────────────────────────────────
private void OnSelectEntered(SelectEnterEventArgs args)
{
// 抓取时取消正在进行的归位
StopReset();
if (grabAudio != null) grabAudio.Play();
}
private void OnSelectExited(SelectExitEventArgs args)
{
if (releaseAudio != null) releaseAudio.Play();
m_resetCoroutine = StartCoroutine(DelayThenReturn());
}
// ── 归位协程 ──────────────────────────────────────────────
private IEnumerator DelayThenReturn()
{
yield return new WaitForSeconds(resetDelayTime);
// 归位期间禁止被重新抓取
m_grab.enabled = false;
// 停止物理运动
StopPhysics();
if (effectCtr != null)
{
// 有溶解效果:消失 → 归位 → 出现
effectCtr.Hide();
yield return new WaitForSeconds(dissolveDuration);
ReturnPositionAndRotation();
effectCtr.Show();
yield return new WaitForSeconds(dissolveDuration);
}
else
{
// 无溶解效果:直接瞬移归位
ReturnPositionAndRotation();
}
m_grab.enabled = true;
m_resetCoroutine = null;
}
// ── 公共方法 ──────────────────────────────────────────────
/// <summary>立即归回初始位置和旋转</summary>
public void ReturnPositionAndRotation()
{
transform.position = m_returnPos;
transform.rotation = m_returnRot;
StopPhysics();
}
/// <summary>更新归位目标为当前位置(需要重新记录原点时调用)</summary>
public void RecordCurrentAsHome()
{
m_returnPos = transform.position;
m_returnRot = transform.rotation;
}
// ── 内部工具 ──────────────────────────────────────────────
private void StopPhysics()
{
if (m_rb == null) return;
m_rb.velocity = Vector3.zero;
m_rb.angularVelocity = Vector3.zero;
m_rb.isKinematic = true;
}
private void StopReset()
{
if (m_resetCoroutine != null)
{
StopCoroutine(m_resetCoroutine);
m_resetCoroutine = null;
}
if (m_grab != null)
m_grab.enabled = true;
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 7877962557443e34f8190e3278bd4a5d
guid: 7cf98a8d188845e4b9cca594d4776f95
MonoImporter:
externalObjects: {}
serializedVersion: 2