Files
Zombie/Assets/_Zombie/Scripts/Player.cs
2026-03-14 14:47:44 +08:00

542 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using DragonLi.Core;
using DragonLi.Frame;
using Mirror;
using UnityEngine;
using UnityEngine.XR;
using Random = UnityEngine.Random;
/// <summary>
/// 手类型
/// </summary>
public enum HandType
{
Left,
Right
}
/// <summary>
/// 手状态
/// </summary>
public enum HandState
{
/// <summary>
/// 空手
/// </summary>
Empty,
/// <summary>
/// 有武器
/// </summary>
HaveWeapon
}
public class Player : NetworkRoomPlayer,IDamagable
{
public Transform LeftHand;
public Transform RightHand;
public Transform Aim;
public Collider Collider;
public LayerMask AimLayer;
[SyncVar]
public bool isDie;
private bool IsAlive = true;
private float time = 0;
[Header("玩家最大血量")]
public float maxHp = 150;
private float currentHp;
public float Health
{
get => currentHp;
set => currentHp = value;
}
#if UNITY_EDITOR
[DisplayOnly]
#endif
public Vector3 AimVec = Vector3.zero;
#region
/// <summary>
/// 双手状态
/// </summary>
public HandState NowHandState = HandState.Empty;
/// <summary>
/// 手上的枪械
/// </summary>
private List<Launcher> Guns = new List<Launcher>();
/// <summary>
/// 现在手上的武器
/// </summary>
public int NowGunIndex = -1;
/// <summary>
/// 左手上的枪
/// </summary>
private Transform leftGun;
/// <summary>
/// 右手上的枪
/// </summary>
private Transform rightGun;
public GameObject[] guns;
#endregion
public new void Start()
{
base.Start();
if (isLocalPlayer)
{
GameLocal.Ins.self = this;
Collider.enabled = false;
}
if (isServer)
{
GameManager.Ins.AddData(index);
Collider.enabled = true;
}
currentHp = maxHp;
// 添加空引用保护和重复添加检查
if (GameManager.Ins != null && !GameManager.Ins.players.ContainsKey(index))
{
GameManager.Ins.players.Add(index, this);
}
IsAlive = true;
}
public void SetBlood(float num)
{
currentHp += num;
EventDispatcher.TriggerEvent("HpChange", currentHp, maxHp);
}
public float OnReceiveDamage(float damage, object info, Transform _sender)
{
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);
if(TrueGearEffectManager.Ins!=null)
TrueGearEffectManager.Ins.OnHit(angle > 90,index,false);
}
#endif
if (currentHp <= 0 && IsAlive)
{
IsAlive = false;
isDie = true;
GameLocal.Ins.DieUI.SetActive(true);
GameManager.Ins.PlaySound2DRPC("1.35");
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
IsAlive = true;
isDie = false;
GameLocal.Ins.DieUI.SetActive(false);
currentHp = maxHp;
EventDispatcher.TriggerEvent("HpChange", currentHp, maxHp);
time = 0f;
}, 5f, this);
}
else if (currentHp > 0)
{
GameLocal.Ins.HitUI.SetActive(true);
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
GameLocal.Ins.HitUI.SetActive(false), 1f, this);
}
return currentHp;
}
public void Update()
{
// 添加空引用保护防止从机因GameLocal未初始化而掉线
if (GameLocal.Ins == null || GameLocal.Ins.MRCamera == null ||
GameLocal.Ins.Aim == null || GameLocal.Ins.MRLeftControl == null ||
GameLocal.Ins.MRRightControl == null)
{
return;
}
Transform mainCamera = GameLocal.Ins.MRCamera.transform;
Transform aim = GameLocal.Ins.Aim.transform;
Transform leftControl = GameLocal.Ins.MRLeftControl;
Transform rightControl = GameLocal.Ins.MRRightControl;
if (isLocalPlayer)
{
// 同步相机
transform.position = mainCamera.position;
transform.rotation = mainCamera.rotation;
// 同步注视点
Aim.position = aim.position;
Aim.rotation = aim.rotation;
#if !UNITY_EDITOR && UNITY_ANDROID && PICO
// 同步手柄
LeftHand.transform.position = leftControl.position;
LeftHand.transform.rotation = leftControl.rotation;
RightHand.transform.position = rightControl.position;
RightHand.transform.rotation = rightControl.rotation;
#endif
// 秒杀当前场上的怪
if (Input.GetKeyDown(KeyCode.Q))
{
GameManager.Ins.DamageAllEnemy();
}
}
if (isServer)
{
// 发射射线
if (Physics.Raycast(transform.position, transform.forward, out RaycastHit handlingHit, 20f, AimLayer))
{
AimVec = handlingHit.point;
}
else
{
AimVec = Aim.position;
}
}
}
[TargetRpc]
public void ApplyDamage(float value, object info, Transform _sender)
{
OnReceiveDamage(value, info, _sender);
}
[ServerCallback]
public void OnTriggerEnter(Collider other)
{
// 开始游戏
if (other.tag == "Door")
{
Debug.Log("触碰开始");
other.gameObject.GetComponent<Collider>().enabled = false;
other.gameObject.SetActive(false);
NetworkServer.Destroy(other.gameObject);
GameManager.Ins.StopGuide();
GameManager.Ins.GameStart();
}
if (other.tag == "WeaponProp")
{
WeaponProp prop = other.transform.GetComponent<WeaponProp>();
if(NowGunIndex==(int)prop.weaponType)
return;
PickUpGun(prop.weaponType, prop.amount);
}
// if (other.tag == "ItemProp")
// {
// ItemProp prop = other.transform.GetComponent<ItemProp>();
// if (prop.itemPropType == ItemPropType.Hp)
// {
// GetProp(prop);
// GameManager.Ins.DesItemProp(prop.gameObject);
// }
// }
}
[TargetRpc]
public void GetProp(ItemProp prop)
{
SetBlood(prop.addHpIndex);
}
#region
/// <summary>
/// 创建武器
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
[Server]
public GameObject CreateWeapon(GunType type)
{
GameObject gun = null;
gun= Instantiate(guns[(int)type]);
return gun;
}
/// <summary>
/// 装载武器
/// </summary>
/// <param name="handType"></param>
/// <param name="gunType"></param>
/// <returns></returns>
[Server]
public Launcher LoadGun(HandType handType, GunType gunType)
{
GameObject gun = CreateWeapon(gunType);
Launcher launcher = gun.GetComponent<Launcher>();
launcher.hand = handType;
launcher.type = gunType;
return launcher;
}
[TargetRpc]
public void TriggerEvent(GunType gunType)
{
EventDispatcher.TriggerEvent("ChangeWeaponIcon", gunType, 0);
}
[TargetRpc]
public void TriggerEventAmount(float amount)
{
if (amount == -999) amount = 0;
EventDispatcher.TriggerEvent("ShowBulletAmount", amount);
}
/// <summary>
/// 拾取枪械
/// </summary>
/// <param name="gunType"></param>
/// <param name="owner"></param>
[Command(requiresAuthority = false)]
public void PickUpGun(GunType gunType, int amount)
{
Debug.Log("创建武器");
Launcher find = null;
for (int i = 0; i < Guns.Count; i++)
{
Launcher launcher = Guns[i];
if (launcher != null && launcher.type == gunType)
{
find = launcher;
break;
}
}
if (find != null)
{
Debug.Log("添加弹药 - " + gunType);
find.StuffBullet(amount);
//Swith2TargetGun(gunType);
}
else
{
Debug.Log("增加新武器 - " + gunType);
Launcher right = null;
right = LoadGun(HandType.Right, gunType);
Launcher launchers = right;
launchers.SetBulletAmount(amount,index);
Guns.Add(launchers);
Swith2TargetGun(gunType);
}
}
/// <summary>
/// 切换到下个武器
/// </summary>
[Command]
public void Switch2NextWeaponCmd()
{
Switch2NextWeapon();
}
[Command]
public void Switch2BeforeWeaponCmd()
{
Switch2BeforeWeapon();
}
/// <summary>
/// 切换到下个武器
/// </summary>
[Server]
public void Switch2NextWeapon()
{
Debug.Log("切换到下个武器");
// 空手
if (NowHandState == HandState.Empty)
{
Debug.Log("空手->可有武器状态");
NowHandState = HandState.HaveWeapon;
}
// 无武器
if (Guns.Count <= 0)
{
Debug.Log("无武器");
PickUpGun(GunType.Pistol,-999);
return;
}
NowGunIndex++;
if (NowGunIndex > Guns.Count - 1)
{
NowGunIndex = 0;
}
UpdateWeapons();
}
/// <summary>
/// 切换到上个武器
/// </summary>
[Server]
public void Switch2BeforeWeapon()
{
Debug.Log("切换到下个武器");
// 空手
if (NowHandState == HandState.Empty)
{
Debug.Log("空手->可有武器状态");
NowHandState = HandState.HaveWeapon;
}
// 无武器
if (Guns.Count <= 0)
{
Debug.Log("无武器");
return;
}
NowGunIndex--;
if (NowGunIndex < 0)
{
NowGunIndex = Guns.Count - 1;
}
UpdateWeapons();
}
/// <summary>
/// 切换到指定枪械
/// </summary>
[Server]
public void Swith2TargetGun(GunType type)
{
Debug.Log("切换到指定枪械");
int find = -1;
for (int i = 0; i < Guns.Count; i++)
{
Launcher launcher = Guns[i];
if (launcher != null && launcher.type == type)
{
find = i;
break;
}
}
if (find != -1)
{
NowGunIndex = find;
}
UpdateWeapons();
}
[Command]
public void EntertTurret(NetworkIdentity turret)
{
turret.AssignClientAuthority(connectionToClient);
}
[Command]
public void ExitTurret(NetworkIdentity turret)
{
turret.RemoveClientAuthority();
}
/// <summary>
/// 武器更新
/// </summary>
[Server]
public void UpdateWeapons()
{
if (rightGun != null)
{
rightGun.gameObject.SetActive(false);
NetworkServer.Destroy(rightGun.gameObject);
rightGun = null;
}
for (int i = 0; i < Guns.Count; i++)
{
if (i == NowGunIndex)
{
Launcher l1 = Guns[i];
if (l1 != null)
{
rightGun = l1.transform;
rightGun.gameObject.SetActive(true);
NetworkServer.Spawn(l1.gameObject, gameObject);
}
}
}
EventDispatcher.TriggerEvent("ChangeGunIcon", Guns[NowGunIndex].bullet_amount);
}
/// <summary>
/// 删除武器
/// </summary>
[Command(requiresAuthority = false)]
public void DelWeapon()
{
bool change = false;
for (int i = 0; i < Guns.Count; i++)
{
Launcher launcher = Guns[i];
if (launcher != null && launcher.bullet_amount <= 0 && launcher.bullet_amount != -999)
{
change = true;
Guns[i] = null;
break;
}
}
if (change)
{
Guns.RemoveAll(x => x == null);
Switch2NextWeapon();
}
}
[Command]
public void Switch2EmptyCmd()
{
Switch2Empty();
}
/// <summary>
/// 切换为空手
/// </summary>
[Server]
public void Switch2Empty()
{
NowHandState = HandState.Empty;
NowGunIndex = -1;
UpdateWeapons();
}
public Launcher CurUserGun()
{
return Guns[NowGunIndex];
}
#endregion
}