提交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

@@ -1,154 +1,67 @@
using System.Collections;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
using UnityEngine.XR.Interaction.Toolkit.Interactables;
/// <summary>
/// S1 天命玄鸟 - 悬浮甲骨交互
/// S1 天命玄鸟 - 悬浮甲骨文字交互(仅负责文字显示/隐藏)
/// 归位逻辑由同一 GameObject 上的 ReturnPosition 负责。
///
/// 同一 GameObject 需要同时挂 XRGrabInteractable。
///
/// 交互逻辑:
/// hover触摸/靠近,未抓取)→ 播放文字显示动画
/// selectEntered抓取 → 隐藏文字,取消归位计时
/// selectExited松手 → 延迟后溶解消失 → 瞬间归位 → 溶解出现
/// hover触摸/靠近,未抓取)→ 播放文字出现动画
/// selectEntered抓取 → 播放文字消失动画
/// </summary>
[RequireComponent(typeof(XRGrabInteractable))]
public class S1_OracleBoneInteract : MonoBehaviour
{
[Header("文字动画")]
[SerializeField] private Animator textAnimator;
[SerializeField] private string showAnimName = "Open"; // 文字出现
[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; // 溶解动画时长
[Header("音效")]
public AudioSource touchAudio;
public AudioSource lightEffect;
// ── 内部状态 ─────────────────────────────────────────────
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; // 已被抓取中,不重复触发
if (m_grab.isSelected) return;
if (lightEffect != null) lightEffect.Play();
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();
if (textAnimator != null) textAnimator.Play(showAnimName);
if (touchAudio != null) touchAudio.Play();
}
private void HideText()
{
if (textAnimator != null)
textAnimator.Play(hideAnimName);
if (textAnimator != null) textAnimator.Play(hideAnimName);
}
}