提交场景2交互

This commit is contained in:
YXY
2026-03-06 12:10:15 +08:00
parent eb9306ba2c
commit ad3cc8e142
14 changed files with 1318 additions and 60 deletions

View File

@@ -0,0 +1,154 @@
using System.Collections;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
using UnityEngine.XR.Interaction.Toolkit.Interactables;
/// <summary>
/// S1 天命玄鸟 - 悬浮甲骨交互
///
/// 同一 GameObject 需要同时挂 XRGrabInteractable。
///
/// 交互逻辑:
/// hover触摸/靠近,未抓取)→ 播放文字显示动画
/// selectEntered抓取 → 隐藏文字,取消归位计时
/// selectExited松手 → 延迟后溶解消失 → 瞬间归位 → 溶解出现
/// </summary>
[RequireComponent(typeof(XRGrabInteractable))]
public class S1_OracleBoneInteract : MonoBehaviour
{
[Header("文字动画")]
[SerializeField] private Animator textAnimator;
[SerializeField] private string showAnimName = "Open"; // 文字出现
[SerializeField] private string hideAnimName = "Translate"; // 文字消失
[SerializeField] private AudioSource touchAudio;
[Header("归位溶解效果")]
[SerializeField] private EffectHideAndShowCtr effectCtr;
[SerializeField] private float resetDelayTime = 2f; // 松手后多久开始归位
[SerializeField] private float dissolveDuration = 1f; // 溶解动画时长
// ── 内部状态 ─────────────────────────────────────────────
private XRGrabInteractable m_grab;
private Rigidbody m_rb;
private Vector3 m_returnPos;
private Quaternion m_returnRot;
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.hoverEntered.AddListener(OnHoverEntered);
m_grab.selectEntered.AddListener(OnSelectEntered);
m_grab.selectExited.AddListener(OnSelectExited);
}
private void OnDisable()
{
m_grab.hoverEntered.RemoveListener(OnHoverEntered);
m_grab.selectEntered.RemoveListener(OnSelectEntered);
m_grab.selectExited.RemoveListener(OnSelectExited);
StopReset();
}
// ── XRI 事件 ──────────────────────────────────────────────
/// <summary>手靠近/触摸(未抓取)→ 显示文字</summary>
private void OnHoverEntered(HoverEnterEventArgs args)
{
if (m_grab.isSelected) return; // 已被抓取中,不重复触发
ShowText();
}
/// <summary>抓取 → 隐藏文字,取消归位计时</summary>
private void OnSelectEntered(SelectEnterEventArgs args)
{
StopReset();
HideText();
}
/// <summary>松手 → 延迟后溶解归位</summary>
private void OnSelectExited(SelectExitEventArgs args)
{
m_resetCoroutine = StartCoroutine(DelayThenReturn());
}
// ── 归位协程 ──────────────────────────────────────────────
private IEnumerator DelayThenReturn()
{
yield return new WaitForSeconds(resetDelayTime);
// 归位期间禁止被重新抓取
m_grab.enabled = false;
// 1. 停止物理运动(避免归位时还在飞)
if (m_rb != null)
{
m_rb.velocity = Vector3.zero;
m_rb.angularVelocity = Vector3.zero;
m_rb.isKinematic = true;
}
// 2. 溶解消失
if (effectCtr != null)
effectCtr.Hide();
yield return new WaitForSeconds(dissolveDuration);
// 3. 瞬间归位
transform.position = m_returnPos;
transform.rotation = m_returnRot;
// 4. 溶解出现
if (effectCtr != null)
effectCtr.Show();
yield return new WaitForSeconds(dissolveDuration);
// 5. 恢复交互
m_grab.enabled = true;
m_resetCoroutine = null;
}
private void StopReset()
{
if (m_resetCoroutine != null)
{
StopCoroutine(m_resetCoroutine);
m_resetCoroutine = null;
}
// 确保归位中断时交互器恢复可用
if (m_grab != null)
m_grab.enabled = true;
}
// ── 文字动画 ──────────────────────────────────────────────
private void ShowText()
{
if (textAnimator != null)
textAnimator.Play(showAnimName);
if (touchAudio != null)
touchAudio.Play();
}
private void HideText()
{
if (textAnimator != null)
textAnimator.Play(hideAnimName);
}
}

View File

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