Files
Loong/Assets/_Loong/Scripts/Player.cs

326 lines
9.3 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using DarkTonic.MasterAudio;
using DG.Tweening;
using DragonLi.Core;
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 : MonoBehaviour, Damagable
{
public Transform LeftHand;
public Transform RightHand;
public InputDevice leftHandDevice;
private InputDevice rightHandDevice;
public bool isClickSwith = false;
public PullHand pullHand;
[Header("经验系统")] public int exp; // 当前经验值
private int[] levelThresholds = { 1000, 2000, 3000 }; // 每级经验阈值
private int bowLevel = 0;
[Header("弓管理")] public Bow[] bows; // 不同等级的弓
public GameObject levelUpEffect; // 升级特效预制体
public GameObject expEffect; //经验特效
public GameObject expEndEffect; // 升级爆炸特效预制体
//private Bow currentBow;
[SoundGroup] public string bgmSound;
public bool isDie;
public bool IsAlive = true;
private float time = 0;
[Header("玩家最大血量")]
public float maxHp = 1;
private float currentHp;
public float Health
{
get => currentHp;
set => currentHp = value;
}
public void Start()
{
GameLocal.Ins.self = this;
maxHp = 100;
currentHp = maxHp;
// 默认装备第一把弓
EquipBow(0);
levelUpEffect.SetActive(false);
MasterAudio.PlaySound(bgmSound);
#if !UNITY_EDITOR && UNITY_ANDROID && PICO
leftHandDevice = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand);
rightHandDevice = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);
#endif
}
// 增加经验
public void GetEx(int amount, Vector3 fromPos)
{
// 生成经验特效飞向弓
StartCoroutine(ShowExpEffect(fromPos));
exp += amount;
Debug.Log($"获得经验:{amount},当前经验:{exp}");
// 检查是否升级
CheckLevelUp();
}
private IEnumerator ShowExpEffect(Vector3 fromPos)
{
GameObject expFx = Instantiate(expEffect, fromPos, Quaternion.identity);
expFx.transform.localScale = Vector3.one;
Transform target = LeftHand != null ? LeftHand : transform;
float duration = 1f;
float elapsed = 0f;
Vector3 startPos = fromPos;
// 在 duration 时间内,动态跟踪目标位置
while (elapsed < duration)
{
elapsed += Time.deltaTime;
float t = Mathf.Clamp01(elapsed / duration);
// 实时目标位置(弓可能在移动)
Vector3 targetPos = target.position;
// 使用插值平滑移动
expFx.transform.position = Vector3.Lerp(startPos, targetPos, t);
yield return null;
}
// 抵达弓位置后生成结束特效
if (pullHand.bow != null && expEndEffect != null)
{
GameObject expEndFx = Instantiate(expEndEffect, pullHand.bow.transform.position, Quaternion.identity);
CoroutineTaskManager.Instance.WaitSecondTodo(() => { Destroy(expEndFx); }, 2f);
}
Destroy(expFx);
}
private void CheckLevelUp()
{
if (bowLevel < levelThresholds.Length && exp >= levelThresholds[bowLevel])
{
bowLevel++;
EquipBow(bowLevel);
levelUpEffect.SetActive(true);
Debug.Log($"弓升级到 Lv{bowLevel + 1}");
}
}
private void EquipBow(int index)
{
for (int i = 0; i < bows.Length; i++)
{
bows[i].gameObject.SetActive(i == index);
}
pullHand.bow = bows[index];
}
public void UserBow(bool isUser)
{
pullHand.IsUserBow(isUser);
}
public void PlaySwitchBowSound()
{
MasterAudio.PlaySound("获取");
}
private void Update()
{
// 滚轮切换弓
if (Input.mouseScrollDelta.y > 0&&IsAlive)
{
// 摇杆朝左
isClickSwith = true;
int prev = Mathf.Max(0, bowLevel - 1);
EquipBow(prev);
PlaySwitchBowSound();
}
else if (Input.mouseScrollDelta.y < 0&IsAlive)
{
// 摇杆朝右
isClickSwith = true;
int next = Mathf.Min(bows.Length - 1, bowLevel);
EquipBow(next);
PlaySwitchBowSound();
}
#if !UNITY_EDITOR && UNITY_ANDROID && PICO
if (rightHandDevice != null)
{
Vector2 value;
rightHandDevice.TryGetFeatureValue(CommonUsages.primary2DAxis, out value);
if (value.magnitude > 0)
{
// 根据轴的值判断摇杆朝向
if (!isClickSwith && value.x < 0 && GameManager.Ins.isGameStart)
{
// 摇杆朝左
isClickSwith = true;
int prev = Mathf.Max(0, bowLevel - 1);
EquipBow(prev);
PlaySwitchBowSound();
}
else if (!isClickSwith && value.x > 0 && GameManager.Ins.isGameStart)
{
// 摇杆朝右
isClickSwith = true;
int next = Mathf.Min(bows.Length - 1, bowLevel);
EquipBow(next);
PlaySwitchBowSound();
}
}
else if (value.magnitude == 0)
{
isClickSwith = false;
}
if (value.Equals(Vector2.zero))
{
isClickSwith = false;
}
}
#endif
if (!IsAlive)
{
time += Time.deltaTime;
if (time >= 1f) GameLocal.Ins.dieTxt.text = "4";
if (time >= 2f) GameLocal.Ins.dieTxt.text = "3";
if (time >= 3f) GameLocal.Ins.dieTxt.text = "2";
if (time >= 4f) GameLocal.Ins.dieTxt.text = "1";
return;
}
Transform mainCamera = GameLocal.Ins.MRCamera.transform;
Transform leftControl = GameLocal.Ins.MRLeftControl;
Transform rightControl = GameLocal.Ins.MRRightControl;
LeftHand.transform.position = leftControl.position;
LeftHand.transform.rotation = leftControl.rotation;
RightHand.transform.position = rightControl.position;
RightHand.transform.rotation = rightControl.rotation;
// 同步相机
transform.position = mainCamera.position; transform.rotation = mainCamera.rotation;
if (Input.GetKeyDown(KeyCode.Q))
{
GameManager.Ins.CloseCurBoss();
}
}
private void OnTriggerEnter(Collider other)
{
Debug.LogError("触碰开始:"+other.gameObject.name);
// 开始游戏
if (other.tag == "Door")
{
Debug.Log("触碰开始");
other.gameObject.GetComponent<Collider>().enabled = false;
other.gameObject.SetActive(false);
Destroy(other.gameObject);
GameManager.Ins.GameStart();
}
}
public void ApplyDamage(float value, int ownerIndex, Vector3 hitPos, Transform sender)
{
OnReceiveDamage(value,hitPos,sender);
}
public void SetBlood(float num)
{
currentHp += num;
EventDispatcher.TriggerEvent("HpChange", currentHp, maxHp);
}
public float OnReceiveDamage(float damage,Vector3 hitPos,Transform _sender)
{
float curDamage = damage;
SetBlood(-curDamage);
#if !UNITY_EDITOR && UNITY_ANDROID && PICO
if (_sender != null)
{
Vector3 forward = transform.forward;
Vector3 directionFormHit=(transform.position-hitPos).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;
UserBow(false);
GameLocal.Ins.DieUI.SetActive(true);
GameLocal.Ins.dieTxt.text = "";
GameManager.Ins.PlaySound2DRPC("1.35");
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
IsAlive = true;
isDie = false;
UserBow(true);
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 End()
{
Debug.Log("游戏结束");
IsAlive = false;
pullHand.bow.gameObject.SetActive(false);
}
}