567 lines
14 KiB
C#
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
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|