using System.Globalization; using System.Collections; using System.Collections.Generic; using Pico.Platform; using UnityEngine; using System; using DG.Tweening; using DragonLi.Core; using UnityEngine.XR.Interaction.Toolkit; using TrackedPoseDriver = UnityEngine.SpatialTracking.TrackedPoseDriver; /// /// 击打结果 /// public enum HitResult { None, // 无效击打 Hit, // 击中雕像 TargetBreak, // 击碎目标雕像 WrongBreak // 击碎错误雕像 } public class RightHand : MonoBehaviour { public TrackedPoseDriver tracked; private HandState _cachePlayerState; // 射线 public LayerMask layerMask; public Transform ray; [Tooltip("手模型")] public GameObject hand; public GameObject hit; private int _cacheTargetId = -1; private Vector3 _curPos; private bool _isStartTrigger; public bool isTrigger; public float triggerDis; public bool _isOpenLine = false; //拼图Id public int puzzleId; private Collider _collider = null; public Collider selfCollider { get { if (_collider == null) { _collider = GetComponentInChildren(); } return _collider; } } public void Start() { tracked.enabled = true; selfCollider.enabled = true; GameManager.Ins.playerRightHand=this; MRInput.Ins.RegisterClickRrightTrigger(ClickRrightTrigger); Init(); } public void Init() { hand.SetActive(true); statueEventHandObject.SetActive(false); _isOpenLine = true; } public void Update() { if (Input.GetKeyDown(KeyCode.Space)) { } #if UNITY_EDITOR Transform camera = GameLocal.Ins.MRCamera.transform; transform.position = camera.position + camera.forward * 0.5f + camera.right * 0.2f + camera.up * -0.1f; transform.rotation = camera.rotation; #endif ray.gameObject.SetActive(_isOpenLine); isTrigger = MRInput.Ins.pressRightTrigger; if (isTrigger&& !_isStartTrigger) { _isStartTrigger = true; _curPos = transform.position; } else { _isStartTrigger = false; } triggerDis=isTrigger?transform.position.y-_curPos.y:0; // 射线检测 if (_isOpenLine) { if (Physics.Raycast(transform.position, transform.forward, out RaycastHit handlingHit, 100F, layerMask)) { } else { hit = null; } } // 雕像事件击打检测 if (isInStatueEventMode && enableStatueHitDetection) { UpdateStatueHitDetection(); } // 更新手部速度(用于挥拳检测) handVelocity = Vector3.Distance(transform.position, lastPosition) / Time.deltaTime; lastPosition = transform.position; } /// /// 更新雕像击打检测 /// private void UpdateStatueHitDetection() { // 检查击打时间间隔 if (Time.time - lastHitTime < hitInterval) { return; // 还在冷却时间内 } // 方法1:基于手部速度的挥拳检测 if (handVelocity > swingVelocityThreshold) { HitResult result = CheckAndHitStatue(); if (result != HitResult.None) { lastHitTime = Time.time; // 更新上次击打时间 Debug.Log($"[RightHand] 挥拳击打雕像结果: {result}"); } } // 方法2:如果当前有碰撞的雕像,按扳机键击打 if (currentHitStatue != null && isTrigger) { HitResult result = HitCurrentStatue(); if (result != HitResult.None) { lastHitTime = Time.time; // 更新上次击打时间 Debug.Log($"[RightHand] 扳机击打雕像结果: {result}"); } } } public void ClickRrightTrigger() { if(hit==null) return; } /// /// 合成宝石钥匙 /// public void CreateGemKey() { StartCoroutine(StartGemEnd()); } IEnumerator StartGemEnd() { GameManager.Ins.PlaySound2DRPC("1.13"); yield return new WaitForSeconds(3f); } public void ChangeHand() { hand.SetActive(true); _isOpenLine = true; } #region 水晶雕像击打方法 [Header("雕像击打配置")] public float hitDistance = 1.5f; // 击打检测距离 public float hitRadius = 0.3f; // 击打检测半径 public LayerMask statueLayerMask; // 雕像层级 /// /// 当前击中的雕像 /// private CrystalStatue currentHitStatue; /// /// 检测并击打水晶雕像 /// public HitResult CheckAndHitStatue() { // 使用球形检测 Collider[] hits = Physics.OverlapSphere(transform.position, hitRadius, statueLayerMask); if (hits.Length > 0) { foreach (var collider in hits) { CrystalStatue statue = collider.transform.parent.GetComponent(); if (statue != null && !statue.IsBroken()) { return HitStatue(statue); } } } return HitResult.None; } /// /// 击打指定水晶雕像 /// public HitResult HitStatue(CrystalStatue statue) { if (statue == null || statue.IsBroken()) { return HitResult.None; } int healthBefore = statue.GetCurrentHealth(); statue.OnPlayerHit(); int healthAfter = statue.GetCurrentHealth(); // 判断击打结果 if (healthAfter <= 0) { // 雕像碎裂 if (statue.isTarget) { return HitResult.TargetBreak; } else { return HitResult.WrongBreak; } } else if (healthAfter < healthBefore) { // 成功击打但未碎裂 return HitResult.Hit; } return HitResult.None; } /// /// 获取视线前方的水晶雕像 /// public CrystalStatue GetStatueInFront() { if (Physics.Raycast(transform.position, transform.forward, out RaycastHit hitInfo, hitDistance, statueLayerMask)) { CrystalStatue statue = hitInfo.collider.GetComponent(); if (statue != null && !statue.IsBroken()) { return statue; } } return null; } /// /// 挥拳检测击打雕像(基于手部速度) /// /// 速度阈值 public HitResult CheckSwingHit(float velocityThreshold = 2f) { // 检测手部速度是否超过阈值 float handSpeed = tracked ? tracked.transform.GetComponent()?.velocity.magnitude ?? 0f : 0f; if (handSpeed < velocityThreshold) { return HitResult.None; } return CheckAndHitStatue(); } /// /// 设置当前击中的雕像(用于碰撞检测) /// public void SetCurrentHitStatue(CrystalStatue statue) { currentHitStatue = statue; } /// /// 击打当前碰撞的雕像 /// public HitResult HitCurrentStatue() { if (currentHitStatue != null) { return HitStatue(currentHitStatue); } return HitResult.None; } #endregion #region 雕像事件道具切换 [Header("道具配置")] public GameObject normalHandObject; // 普通手部道具 public GameObject statueEventHandObject; // 雕像事件专用道具(如手套) [Header("击打检测配置")] public bool enableStatueHitDetection = false; // 是否启用雕像击打检测 public float swingVelocityThreshold = 2f; // 挥拳速度阈值 public float hitInterval = 0.5f; // 击打时间间隔(秒) /// /// 是否处于雕像事件模式 /// private bool isInStatueEventMode = false; /// /// 上次击打时间 /// private float lastHitTime = 0f; /// /// 上一次的位置(用于计算速度) /// private Vector3 lastPosition; /// /// 手部速度 /// private float handVelocity; /// /// 进入水晶雕像事件模式 /// public void EnterStatueEventMode() { isInStatueEventMode = true; enableStatueHitDetection = true; // 隐藏射线 _isOpenLine = false; if (ray != null) ray.gameObject.SetActive(false); // 切换道具 if (normalHandObject != null) normalHandObject.SetActive(false); if (statueEventHandObject != null) statueEventHandObject.SetActive(true); // 初始化位置追踪 lastPosition = transform.position; handVelocity = 0f; Debug.Log("[RightHand] 进入雕像事件模式,启用击打检测"); } /// /// 退出水晶雕像事件模式 /// public void ExitStatueEventMode() { isInStatueEventMode = false; enableStatueHitDetection = false; // 清空当前碰撞的雕像 currentHitStatue = null; // 恢复射线 _isOpenLine = true; if (ray != null) ray.gameObject.SetActive(true); // 切换道具 if (statueEventHandObject != null) statueEventHandObject.SetActive(false); if (normalHandObject != null) normalHandObject.SetActive(true); Debug.Log("[RightHand] 退出雕像事件模式,禁用击打检测"); } #endregion }