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
}