using System; using System.Collections.Generic; using DragonLi.Core; using DragonLi.Frame; using Pathfinding; using Pathfinding.RVO; using UnityEngine; using UnityEngine.XR; using Random = UnityEngine.Random; public enum handState { Hand, Gun, } /// /// 玩家控制脚本: /// - 管理生命值、拾取道具; /// - 监听 VR 摇杆左右切换武器; /// - 移除“右键瞄准放大”相关逻辑,仅保留后坐力接口与摇杆切换。 /// public class Player : MonoBehaviour { [Header("手")] public Transform LeftHand; public Transform RightHand; [Header("导航")] public RVOController rvo; public AIPath aiPath; [NonSerialized] public int CoinCount; [NonSerialized] public int GetCoinIndex; [NonSerialized] public int Score; [NonSerialized] public handState handState; [Header("玩家最大血量")] private float maxHp = 50; private float currentHp; public float Health { get => currentHp; set => currentHp = value; } [Header("玩家手部武器管理")] public PlayerHands playerHands; private bool debugSwitch = false; public bool IsAlive = true; private float time = 0; private int weaponIdx; [NonSerialized] public int GunId; #if UNITY_ANDROID && PICO private InputDevice leftHandDevice; private InputDevice rightHandDevice; private bool isClickSwitch = false; #endif void Start() { #if UNITY_ANDROID && PICO // 只在 Start 时获取设备,避免每帧 GetDevice leftHandDevice = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand); rightHandDevice = InputDevices.GetDeviceAtXRNode(XRNode.RightHand); #endif currentHp = maxHp; GameInit.Ins.self = this; GetCoinIndex = 1; handState = handState.Gun; EventDispatcher.TriggerEvent("GetHand", LeftHand, RightHand); } public void SetBlood(float num) { currentHp += num; EventDispatcher.TriggerEvent("HpChange", currentHp, maxHp); } public void OnTriggerEnter(Collider other) { string tag = other.tag; if(!IsAlive|| GameManager.Ins.isGameEnd) return; switch (tag) { case "WeaponProp": var prop = other.GetComponent(); if (prop != null) { int idx = (int)prop.weaponType; // 对应 WeaponsObjects 下标 int ammo = prop.amount; prop.Collider(); // 播放道具捡起效果 playerHands.PickUpAndSwitchTo(idx, ammo); } break; case "GameStartPoint": Destroy(other.gameObject); GameManager.Ins.GamePlay(); break; } } public bool isFirstDie; public float OnReceiveDamage(float damage, object info, Transform _sender) { return 0; float curDamage = damage; SetBlood(-curDamage); #if !UNITY_EDITOR && UNITY_ANDROID && PICO if (_sender != null) { Vector3 forward = transform.forward; Vector3 directionFormHit=(transform.position-_sender.position).normalized; float angle = Vector3.Angle(forward, directionFormHit); int index = Random.Range(0, 4); TrueGearEffectManager.Ins.OnHit(angle > 90,index,false); } #endif if (currentHp <= 0 && IsAlive) { IsAlive = false; GameInit.Ins.DieUI.SetActive(true); EventDispatcher.TriggerEvent("PlayerDeath",transform); MonoSingleton.Instance.WaitSecondTodo(() => { IsAlive = true; GameInit.Ins.DieUI.SetActive(false); currentHp = maxHp; EventDispatcher.TriggerEvent("HpChange", currentHp, maxHp); time = 0f; if (!isFirstDie) { isFirstDie = true; } }, 3f, this); } else if (currentHp > 0) { GameInit.Ins.HitUI.SetActive(true); MonoSingleton.Instance.WaitSecondTodo(() => GameInit.Ins.HitUI.SetActive(false), 1f, this); } return currentHp; } void Update() { // 同步玩家位置到摄像机(仅在游戏开始时) if ( GameInit.Ins.playerCam != null) { var camTrans = GameInit.Ins.playerCam.transform; transform.position = camTrans.position; transform.rotation = camTrans.rotation; } if (!IsAlive) { //time += Time.deltaTime; // if (time >= 1f) GameInit.Ins.dieTxt.text = "4"; // if (time >= 2f) GameInit.Ins.dieTxt.text = "3"; // if (time >= 3f) GameInit.Ins.dieTxt.text = "2"; // if (time >= 4f) GameInit.Ins.dieTxt.text = "1"; return; } if (Input.GetKeyDown(KeyCode.Q)) { playerHands.PickUpAndSwitchTo(weaponIdx, 1000); weaponIdx++; if (weaponIdx >= playerHands.WeaponsObjects.Length) { weaponIdx = 0; } } #if !UNITY_EDITOR && UNITY_ANDROID && PICO // 同步手柄位置(仅在 PICO 平台) if (GameInit.Ins.leftHand != null) { LeftHand.position = GameInit.Ins.leftHand.position; LeftHand.rotation = GameInit.Ins.leftHand.rotation; } if (GameInit.Ins.rightHand != null) { RightHand.position = GameInit.Ins.rightHand.position; RightHand.rotation = GameInit.Ins.rightHand.rotation; } #endif } public void SetAiPath(bool isShow) { aiPath.enabled = isShow; rvo.enabled = isShow; } public void AddCoin(int amount) { CoinCount += (amount*GetCoinIndex); EventDispatcher.TriggerEvent("RefreshPlayerCoin",CoinCount); } public void UserCoin(int amount) { CoinCount -= amount; EventDispatcher.TriggerEvent("RefreshPlayerCoin",CoinCount); } public int GetCoinCount() { return CoinCount; } public void SetGetCoinIndex(float userTime) { GetCoinIndex = 2; CoroutineTaskManager.Instance.WaitSecondTodo(() => { GetCoinIndex = 1; }, userTime); } public void AddScore(int score) { Score += score; } #region 后坐力与切换 /// /// WeaponHands.OnFire 回调的后坐力数据 /// public void ApplyRecoil(Vector2 recoilDelta) { // TODO: 将 recoilDelta 传给玩家的 Look 脚本或摄像机做后坐力反馈 } public void ApplyDamage(float value, object info, Transform _sender) { OnReceiveDamage(value, info, _sender); } public void End() { foreach (var item in playerHands.WeaponsObjects) { item.SetActive(false); } } /// /// 升级枪 /// public void Upgrade(int curGunId) { GunId = curGunId; playerHands.PickUpAndSwitchTo(curGunId, 10000); } public void UserHand() { GameManager.Ins.rightHand.Show(); playerHands.gunPent.SetActive(false); handState = handState.Hand; } public void UserGun() { playerHands.gunPent.SetActive(true); playerHands.RefreshGun(GunId); GameManager.Ins.rightHand.Hide(); handState = handState.Gun; } #endregion }