提交场景2交互
This commit is contained in:
154
Assets/Scripts/Scene_01/S1_OracleBoneInteract.cs
Normal file
154
Assets/Scripts/Scene_01/S1_OracleBoneInteract.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Scene_01/S1_OracleBoneInteract.cs.meta
Normal file
11
Assets/Scripts/Scene_01/S1_OracleBoneInteract.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9152e17a14030344e9700283f159c637
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user