Files
XMen/Assets/Scripts/HUD/HUD.cs
2025-07-10 14:49:53 +08:00

567 lines
14 KiB
C#

using DG.Tweening;
using DragonLi.Core;
using DragonLi.Frame;
using DragonLi.Frame.Events;
using Mirror;
using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class HUD : MonoBehaviour
{
public GameObject hitEffect;
public TMP_Text countDown;
public float second;
public GameObject[] teachUIs;
public GameObject star;
public GameObject HitDir;
public Transform HitDirParent;
private Transform player;
public GameObject crack;
public Text restartCountDownText;
public TMP_Text info;
public Text TextAmount;
public GameObject UIHudDie;
public GameObject AliveUI;
public GameObject WinUI;
public GameObject Radar;
public TextMeshProUGUI enemyName;
public TextMeshProUGUI enemyDesc;
public GameObject WeaponIcons;
public TextMeshProUGUI bulletAmount;
/// <summary>
/// 怪物信息面板
/// </summary>
public GameObject enemyInfoUI;
public Animator animator;
public List<GameObject> showDieUI = new List<GameObject>();
public List<GameObject> showAliveUI = new List<GameObject>();
private bool IsAlive = true;
public List<GameObject> gunIcons;
public float fadeInDuration = 1.0f;
private CanvasGroup canvasGroup;
public void RefreshRestartCountDown(int number)
{
restartCountDownText.text = number.ToString();
}
public Image blood1;
public Image blood2;
public Image EnergyPumpUI;
private int currentIndex = 0; // 当前对话索引
private string[] dialogueTexts; // 存储对话文本的数组
public void StartDialogue(string[] texts)
{
currentIndex = 0;
dialogueTexts = texts;
ShowNextDialogue();
}
private void ShowNextDialogue()
{
if (currentIndex < dialogueTexts.Length)
{
info.gameObject.SetActive(true);
info.text = dialogueTexts[currentIndex];
currentIndex++;
// 在这里使用回调函数等待一定时间后执行下一段对话的显示
CoroutineTaskManager.Instance.WaitSecondTodo(ShowNextDialogue, 2.0f);
}
else
{
// 所有对话已经显示完毕,可以在这里添加逻辑处理
info.gameObject.SetActive(false);
}
}
private void CoroutineTaskCallback(Action action, float time)
{
StartCoroutine(WaitAndExecute(action, time));
}
private IEnumerator WaitAndExecute(Action action, float time)
{
yield return new WaitForSeconds(time);
action?.Invoke();
}
public void ChangeEnergyPumpUI(float percent)
{
DOTween.To(() => EnergyPumpUI.fillAmount, x => EnergyPumpUI.fillAmount = x, percent, 0.5f);//血量变化
}
/// <summary>
/// 一个UI淡入效果
/// </summary>
/// <returns></returns>
IEnumerator EnemyPlaneFadeIn(float atk, float dee, float speed)
{
for (int i = 0; i < enemyInfoUI.transform.childCount; i++)
{
GameObject node = enemyInfoUI.transform.GetChild(i).gameObject;
CanvasGroup canvasGroup = node.GetComponent<CanvasGroup>();
canvasGroup.DOFade(1.0f, 0.4f);
if (i == 6)
{
//Image bar = node.transform.GetChild(1).GetComponent<Image>();
//DOTween.To(() => bar.fillAmount, x => bar.fillAmount = x, atk, 0.5f);//血量变化
BarDoTween(node, atk);
}
else if (i == 7)
{
//Image bar = node.transform.GetChild(1).GetComponent<Image>();
//DOTween.To(() => bar.fillAmount, x => bar.fillAmount = x, dee, 0.5f);//血量变化
BarDoTween(node, dee);
}
else if (i == 8)
{
BarDoTween(node, speed);
}
yield return new WaitForSeconds(0.15f); // 在每次迭代之后等待1秒
}
}
public void BarDoTween(GameObject node, float fillAmount)
{
Image bar = node.transform.GetChild(1).GetComponent<Image>();
DOTween.To(() => bar.fillAmount, x => bar.fillAmount = x, fillAmount, 0.5f);//血量变化
}
/// <summary>
/// 淡出效果
/// </summary>
/// <returns></returns>
IEnumerator EnemyPlaneFadeOut()
{
for (int i = enemyInfoUI.transform.childCount - 1; i >= 0; i--)
{
GameObject node = enemyInfoUI.transform.GetChild(i).gameObject;
CanvasGroup canvasGroup = node.GetComponent<CanvasGroup>();
canvasGroup.DOFade(0f, 0.5f);
if (i == 6 || i == 7 || i == 8)
{
Image bar = node.transform.GetChild(1).GetComponent<Image>();
DOTween.To(() => bar.fillAmount, x => bar.fillAmount = x, 0, 0.5f);//血量变化
}
yield return new WaitForSeconds(0.15f); // 在每次迭代之后等待1秒
}
}
public void ChangeGun(int id)
{
gunIcons[id].SetActive(true);
for (int i = 0; i < gunIcons.Count; i++)
{
if (i != id)
{
gunIcons[i].SetActive(false);
}
}
}
public void Awake()
{
GameInit.Ins.Win = WinUI;
GameInit.Ins.HitUI = hitEffect;
GameInit.Ins.UIHudDie = UIHudDie;
GameInit.Ins.AliveUI = AliveUI;
GameInit.Ins.restartCountDownText = restartCountDownText;
}
void Start()
{
EventDispatcher.AddEventListener<float, float>("HpChange", HpChange);
EventDispatcher.AddEventListener<Transform>("ShowHitDir", ShowHitDir);
EventDispatcher.AddEventListener<Transform>("PlayerDeath", PlayerDeath);
EventDispatcher.AddEventListener<Transform>("PlayerAlive", PlayerAlive);
EventDispatcher.AddEventListener<int>("PromptMessage", PromptMessage);
EventDispatcher.AddEventListener<int, float>("ShowTeachUI", ShowTeachUI);
EventDispatcher.AddEventListener<float>("ChangeEnergyPumpUI", ChangeEnergyPumpUI);
//怪物第一次出现时HUD接收消息,打开信息面板播放对应动画
EventDispatcher.AddEventListener<int>("PlayEnemyInfo", PlayEnemyInfo);
EventDispatcher.AddEventListener<WeaponType, int>("ChangeWeaponIcon", ChangeWeaponIcon);
EventDispatcher.AddEventListener<float>("ShowBulletAmount", ShowBulletAmount);
canvasGroup = GetComponent<CanvasGroup>();
// 设置初始透明度为0
canvasGroup.alpha = 0f;
// 使用DoTween实现透明度从0到1的渐显效果
canvasGroup.DOFade(1f, fadeInDuration);
}
public void ShowBulletAmount(float amount)
{
if (amount == 0)
{
bulletAmount.text = "";
}
else
{
bulletAmount.text = amount.ToString();
}
}
public void ChangeWeaponIcon(WeaponType weaponType, int amount)
{
switch (weaponType)
{
case WeaponType.DoubleGun:
ShowWeaponIcon(0, amount);
break;
case WeaponType.LargeGun:
ShowWeaponIcon(1, amount);
break;
case WeaponType.RocketGun:
ShowWeaponIcon(2, amount);
break;
case WeaponType.ShotGun:
ShowWeaponIcon(3, amount);
break;
case WeaponType.GrenadeGun:
ShowWeaponIcon(5, amount);
break;
case WeaponType.SuperGun:
ShowWeaponIcon(4, amount);
break;
default:
break;
}
}
public void ShowWeaponIcon(int index, int amount)
{
for (int i = 0; i < WeaponIcons.transform.childCount; i++)
{
GameObject weaponIcon = WeaponIcons.transform.GetChild(i).gameObject;
if (i == index)
{
weaponIcon.SetActive(true);
//weaponIcon.transform.GetChild(0).GetComponent<TextMeshPro>().text = amount.ToString();
}
else
{
weaponIcon.SetActive(false);
}
}
}
public void PlayEnemyInfo(int index)
{
StoryInfo storyInfo = GameManager.Ins.StoryDescInfos[index];
EnemyInfo enemyInfo = GameManager.Ins.EnemyDescInfos[storyInfo.type];
int starAmount = enemyInfo.DescInfos[0];
enemyName.text = enemyInfo.NameCN;
enemyDesc.text = enemyInfo.EnemyDesc;
StartCoroutine(EnemyPlaneFadeIn(enemyInfo.DescInfos[1] / 10.0f, enemyInfo.DescInfos[2] / 10.0f, enemyInfo.DescInfos[3] / 10.0f));
for (int i = 0; i < this.star.transform.childCount; i++)
{
GameObject star = this.star.transform.GetChild(i).gameObject;
if (i <= starAmount)
{
star.SetActive(true);
}
else
{
star.SetActive(false);
}
}
animator.SetInteger("index", index);
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
StartCoroutine(EnemyPlaneFadeOut());
}, 4.0f);
}
public void PlayerDeath(Transform transform)
{
IsAlive = false;
Debug.Log("玩家死亡");
}
public void PlayerAlive(Transform transform)
{
IsAlive = true;
Debug.Log("玩家复活");
}
public void HudUIDie()
{
IsAlive = false;
countDown.color = new Color(174 / 255f, 189 / 255f, 193 / 255f, 255 / 255f);
}
public void HudAlive()
{
IsAlive = true;
countDown.color = new Color(0 / 255f, 207 / 255f, 253 / 255f, 255 / 255f);
}
public void ShowHitDir(Transform target)
{
if (IsAlive)
{
GameObject dir = Instantiate(HitDir, HitDirParent);
Transform B = target;
Transform A = player;
Vector3 from = A.transform.forward;
Vector3 to = new Vector3(B.transform.position.x - A.transform.position.x, 0,
B.transform.position.z - A.transform.position.z);
Vector3 nordir = Vector3.Cross(from, to);
float dot = Vector3.Dot(nordir, Vector3.down);
float angle = Vector3.Angle(from, to);
if (dot < 0)
{
angle *= -1;
angle += 360;
}
dir.transform.localEulerAngles = new Vector3(0, 0, angle);
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
GameObject.Destroy(dir);
}, 1f, this);
}
}
public void HpChange(float currentHp, float maxHp)
{
// Debug.Log("玩家当前血量为" + currentHp + "最大生命上限" + maxHp);
blood2.fillAmount = currentHp / maxHp;
DOTween.To(() => blood1.fillAmount, x => blood1.fillAmount = x, currentHp / maxHp, 0.5f);//血量变化
}
// [Server]
//HUD消息
public void PromptMessage(int index)
{
switch (index)
{
case 0:
Step("看到目标后按下扳机键发射子弹", 0, 2.0f, "playerVoice_02");
ShowTeachUI(0, 0);
ShowTeachUI(1, 0.0f);
ShowTeachUI(2, 3.0f);
break;
case 1:
Step("太好了,你们收集到了能源魔方!", 0, 2.0f, "playerVoice_03");
Step("机械哨兵:检测到入侵者,执行高速接近协议", 3.0f, 2.0f, "esky_dialogue_1");
break;
case 2:
Step("第二个能源魔方成功到手!", 0, 2.0f, "playerVoice_04");
break;
case 3:
Step("沉睡的黑暗……终将苏醒!", 3.0f, 2.0f, "spider_boss_01");
break;
case 4:
Step("干得好,还差2个能力泵就能使用超级武器了", 0, 2.0f, "playerVoice_05");
Step("岩石重兵:下一步就是直接碾碎", 6.0f, 2.0f, "robotMesh_01");
break;
case 5:
Step("只剩最后一个能源魔方了,就差一步!", 0, 2.0f, "playerVoice_05");
Step("幻影者:虚实之间你的死亡早已注定", 2.0f, 2.0f, "shadow_01");
break;
case 6:
AudioManager.Ins?.SoundPlay("bgm4", true);
Step("能源魔方已经集齐,启用终极武器使用权限", 0, 2.0f, "playerVoice_07");
Step("我:降临者现身了,准备决战!", 4.0f, 2.0f, "playerVoice_08");
ShowTeachUI(3, 6.0f);
Step("深渊领主:你的恐惧,让我欣慰", 8.0f, 2.0f, "boss_dialongue_01");
Step("我:永不放弃,永不退缩,人类的命运不由你说了", 11.0f, 3.0f, "playerVoice_09");
break;
}
}
//显示消息,按间隔消失
private void Step(string text, float wait, float time, string clipName)
{
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
info.gameObject.SetActive(true);
info.text = text;
AudioManager.Ins?.SoundPlayOneShot(clipName, false);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
info.gameObject.SetActive(false);
}, time);
}, wait);
}
//显示教学UI
public void ShowTeachUI(int index, float wait)
{
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
teachUIs[index].SetActive(true);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
teachUIs[index].SetActive(false);
}, 2.0f);
}, wait);
}
private void Update()
{
player = World.GetPlayer();
if (!GameManager.Ins.GameStart) return;
if (second > 0)
{
second = second - Time.deltaTime;
if (second / 60 < 1)
{
if (second < 4)
{
}
countDown.text = string.Format("00:{0:d2}", (int)second % 60);
}
else
{
countDown.text = string.Format("{0:d2}:{1:d2}", (int)second / 60, (int)second % 60);
}
}
else
{
GameManager.Ins.isWithinTime = false;
countDown.text = "00:00";
}
//显示枪支Icon
}
}