Files
FutureMen2/Assets/_FutureMen2/Scripts/Player/Player.cs

262 lines
7.6 KiB
C#

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;
/// <summary>
/// 玩家控制脚本:
/// - 管理生命值、拾取道具;
/// - 监听 VR 摇杆左右切换武器;
/// - 移除“右键瞄准放大”相关逻辑,仅保留后坐力接口与摇杆切换。
/// </summary>
public class Player : MonoBehaviour
{
[Header("手")]
public Transform LeftHand;
public Transform RightHand;
[Header("导航")]
public RVOController rvo;
public AIPath aiPath;
[Header("玩家最大血量")]
private float maxHp = 50;
private float currentHp;
public float Health
{
get => currentHp;
set => currentHp = value;
}
[Header("玩家手部武器管理")]
public PlayerHands playerHands;
[NonSerialized]
public int CurGunId;
private bool debugSwitch = false;
public bool IsAlive = true;
private float time = 0;
#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;
CurGunId = 1;
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<WeaponProp>();
if (prop != null)
{
GameInit.Ins.PlayAudio("2.34道具",transform,true);
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)
{
float curDamage = (GameManager.Ins.buffDef > 0) ? (damage / GameManager.Ins.buffDef) : damage;
SetBlood(-curDamage);
GameManager.Ins.PlaySound2D("1.12");
#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;
GameManager.Ins.GameStart = false;
GameInit.Ins.DieUI.SetActive(true);
EventDispatcher.TriggerEvent("PlayerDeath",transform);
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
IsAlive = true;
GameInit.Ins.DieUI.SetActive(false);
GameManager.Ins.GameStart = true;
currentHp = maxHp;
EventDispatcher.TriggerEvent("HpChange", currentHp, maxHp);
time = 0f;
if (!isFirstDie)
{
isFirstDie = true;
GameInit.Ins.PlayAudio("1.6",transform,true);
}
}, 3f, this);
}
else if (currentHp > 0)
{
GameInit.Ins.HitUI.SetActive(true);
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
GameInit.Ins.HitUI.SetActive(false), 1f, this);
}
return currentHp;
}
private int weaponIdx;
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 (rightHandDevice.isValid && GameManager.Ins.GameStart)
{
Vector2 stick;
rightHandDevice.TryGetFeatureValue(CommonUsages.primary2DAxis, out stick);
if (!isClickSwitch)
{
if (stick.x > 0.5f)
{
isClickSwitch = true;
//GameManager.Ins.PlaySwitchGunSound();
playerHands.SwitchToNextAvailable();
}
else if (stick.x < -0.5f)
{
isClickSwitch = true;
//GameManager.Ins.PlaySwitchGunSound();
playerHands.SwitchToPreviousAvailable();
}
}
if (stick.magnitude < 0.1f)
{
isClickSwitch = false;
}
}
// 同步手柄位置(仅在 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;
}
#region
/// <summary>
/// WeaponHands.OnFire 回调的后坐力数据
/// </summary>
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);
}
}
/// <summary>
/// 升级枪
/// </summary>
public void Upgrade()
{
CurGunId++;
playerHands.PickUpAndSwitchTo(CurGunId, 10000);
}
public void UserZeroGun()
{
CurGunId = 1;
playerHands.PickUpAndSwitchTo(1, 10000);
}
#endregion
}