using DG.Tweening; using JetBrains.Annotations; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text.RegularExpressions; using Unity.VisualScripting; using UnityEngine; using UnityEngine.UI; public class ZZUIManager : MonoBehaviour { [Header("面板")] /// /// 点击可以弹出右边框 /// public GameObject Right_Box; /// /// 总指挥框 /// public GameObject Warn_Tip; /// /// 学生疏散情况 /// public GameObject Right_Situation; /// /// 撤离方案选择框 /// public GameObject DiaLogBox; /// /// 下楼梯队形选着 /// public GameObject DiaLogBox2; /// /// 已经安全撤离框 /// public GameObject Right_Message; /// /// 为能安全撤离的框 /// public GameObject Right_Message2; ///// ///// 下拉框 ///// //public Dropdown dropdwn; /// /// 撤离方案选择 /// public ToggleGroup Tip123; /// /// 地图上的四个点 /// public GameObject MapTapPanel; /// /// 疏散提示 /// public GameObject Command02; //右边框框创建紧急任务 //创建的父对象 public GameObject content; //创建的东西 public GameObject TextPrefab; //疏散情况 //创建的任务 public GameObject content2; //创建的东西 public GameObject TextPrefab2; /// /// 提示疏散时间面板 /// public GameObject TipPanel; /// /// 起火点的标题 /// public GameObject TipTilte; /// /// 三个楼梯 /// [Header("按钮")] public Button Icn_Stairway_1; public Button Icn_Stairway_2; public Button Icn_Stairway_3; /// /// 疏散顺序 /// public Button Warn; /// /// 呼出队形机 /// public Button Flee; /// /// 死亡图标的一号电梯 /// public Button Die; /// /// 电梯图标的二号电梯 /// public Button Phone; /// /// 地图F4 /// public Button TP_1; public Button TP_2; public Button TP_3; public Button TP_4; /// /// 对讲机 /// public Button Intercom; /// /// 撤离方案确定 /// public Button DialogboxSure; /// /// 梯队队形选择AB /// public Button Dialogbox2A; public Button Dialogbox2B; /// /// 梯队选择确定 /// public Button Dialogbox2Sure; /// /// 加减号 /// public Button Minus; public Button Plus; /// /// 上报按钮 /// public Button Sumbit; public Button Sumbit2; /// /// 确定起火点按钮 /// public Button FireButton; /// /// 右边的框 /// public Button Right_BoxButton; //两个叉叉 public Button Close1; public Button Close2; public GameObject Close1Panel; public GameObject FreePanel; /// /// 楼梯口 /// [Header("文本")] public Text icn_stairway_text_1; public Text icn_stairway_text_2; public Text icn_stairway_text_3; /// /// 右边框框紧急任务 /// public Text Tip_1; public Text Tip_2; public Text Tip_3; public Text Tip_4; /// /// 现场总指挥 /// public Text Head_Text; /// /// 总指挥介绍 /// public Text WarnTip_Text; /// /// 疏散情况文本 /// public Text Situation_Tip_1; public Text Situation_Tip_2; public Text Situation_Tip_3; public Text Situation_Tip_4; /// /// 撤离方案ABC /// public Text LeftText1; /// /// 撤离方案介绍 /// public Text RightText1; /// /// 楼梯梯队介绍 /// public Text LeftLT_Text1; public Text RightLT_Text1; /// /// 梯队介绍 /// public Text LeftLT_Text2; public Text RightLT_Text; /// /// 撤离班级 /// public Text Right_MessageText; /// /// 学生人数 /// public InputField Student_Number; /// /// 未撤离班级 /// public Text NO_Left_MessageText; public Text NO_Right_MessageText; /// /// 未撤离学生人数 /// public Text NO_Student; /// /// 时间文本 /// public Text TimeText; /// /// 道具数量左->右 /// public Text PropText1; public Text PropText2; public Text PropText3; public Text PropText4; public Text PropText5; public Text PropText6; /// /// 网络延迟 /// public Text WLYC; /// /// 标题文本 /// public Text TileText; /// /// 起火点按钮文本 /// public Text FireText; /// /// 提示疏散时间文本 /// public Text TipText; /// /// 危险提示按钮文本 /// public Text WartipText; /// /// 地图两个不知名的图标文本 /// public Text MessageText; public Text MessageText2; /// /// 清点人数的时候 /// public Text Area; public Text NPCName; /// /// 撤离方案选择框文本信息 /// public Text DiaLogBoxTitle; public Sprite Image1; public Sprite Image2; #region 淡入淡出效果 //计时器 private float timeElapsed = 0f; public float fadeInDuration = 1f; // 淡出时间 public float fadeOutDuration = 1f; // 淡出持续时间 public float displayDuration = 2f; // 2秒后自己淡出 private bool isFadingIn = true; private bool isFadingOut = false; // 指示文本当前是否正在淡入或淡出 private bool isFading = false; // 运行中的淡入淡出协程引用 private Coroutine fadeCoroutine; //淡入淡出计时器 private float elapsedTime = 0f; #endregion #region 图标动效 ////计数器 //private float ContinueTime = 100000000000f; ////记录 //private float tempTime = 0f; //感叹号 [Header("图片")] //提示疏散时间的背景图 public Image TipBg; public Image HeadImage; public Image Bg; //右边 public Image Bg1; //结束标志 private bool isEnd; public JSONReader jsonReader; #endregion #region 实现撤离方案的随机 public GameObject content3; // Scroll View 的 Content 物体 public GridLayoutGroup gridLayoutGroup2; // Grid Layout Group 组件 public GameObject itemPrefab; // 子物体的预制件 public ToggleGroup toggleGroup;//父对象的组件 public Text itemPrefabTextLeft;//标题 public Text itemPrefabTextRight;//内容 public int itemCount = 2; // 要创建的物体数量 List createdItems = new List();//保存用的列表 int ToggleCount = 0; #endregion #region 弹出的效果(包含推开疏散情况) public RectTransform panelA; public float panelAMoveDistance; public float moveDuration = 0.5f; // 动画持续时间 public RectTransform buttonRect; // 你的按钮 RectTransform public bool isHidden = true; public float showPositionX; public float hidePositionX; #endregion //记录 int num = 0; public Image bg; public bool isFrist=false; #region 疏散情况班级排序 public GridLayoutGroup gridLayoutGroup; private List textFields = new List(); #endregion public static ZZUIManager instert; public void Awake() { isHidden = true; instert = this; //TimeText.text = "00.00"; num = 0; } private void Start() { //测试 Frist(); //FixWarn(1,jsonReader.SetUIText(50102)); //string str = jsonReader.SetUIText(50102); //Debug.Log(jsonReader.SetUIText(50102)); //Debug.Log(str); InitializeFlee(10813); //动画位移位置数据 hidePositionX = 337f; showPositionX = 1.159973f; panelAMoveDistance = 382f; //传呼机 Intercom.onClick.AddListener(() => { }); //右边框框弹出来 Right_BoxButton.onClick.AddListener(() => { OnClickHideButton(); }); #region 地标点击事件(地图那四个点) TP_1.onClick.AddListener(() => { MapTP(1); }); TP_2.onClick.AddListener(() => { MapTP(2); }); TP_3.onClick.AddListener(() => { MapTP(3); }); TP_4.onClick.AddListener(() => { MapTP(4); }); #endregion //关闭总指挥框 if (Warn_Tip.activeSelf && (Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1) || Input.GetMouseButtonDown(2))) { Warn_Tip.SetActive(false); } //人物的加减 Minus.onClick.AddListener(() => { int currentValue = int.Parse(Student_Number.text); // 增加1 currentValue--; // 更新 InputField 的文本 Student_Number.text = currentValue.ToString(); }); Plus.onClick.AddListener(() => { int currentValue = int.Parse(Student_Number.text); // 增加1 currentValue++; // 更新 InputField 的文本 Student_Number.text = currentValue.ToString(); }); //打开队形 Flee.onClick.AddListener(() => { if (!isFrist) { DiaLogBox2.SetActive(true); Close1Panel.SetActive(true); } else { Frist(); } }); Close1.onClick.AddListener(() => { Close(); }); Close2.onClick.AddListener(() => { Close(); }); //下拉列表(人物选着) //dropdwn.onValueChanged.AddListener(delegate //{ // DropdownValueChanged(dropdwn); //}); ////默认开一次这样开局就能默认第一个选项一次 //DropdownValueChanged(dropdwn); //右边框框 上报总指 (已经安全撤离的) Sumbit.onClick.AddListener(() => { SumbitButton(); }); //右边框框 上报总指 (未安全撤离的) Sumbit2.onClick.AddListener(() => { Sumbit2Button(); }); //撤离方案确定 DialogboxSure.onClick.AddListener(() => { DiaLogBox.SetActive(false); }); //梯队选择队形 Dialogbox2A.onClick.AddListener(() => { num = 1; }); Dialogbox2B.onClick.AddListener(() => { num = 2; }); //梯队队形确定 Dialogbox2Sure.onClick.AddListener(() => { if (num == 1) { num = 0; DiaLogBox2.SetActive(false); } if (num == 2) { num = 0; DiaLogBox2.SetActive(false); } }); FireButton.onClick.AddListener(() => { FireText.color = new Color(0.75f, 0.75f, 0.75f); }); //疏散顺序按钮 Warn.onClick.AddListener(() => { WarnPanel(); }); #region 数字动效 Number(NO_Student); #endregion } private void Update() { } /// /// 字体动效实现 /// /// 传入文本 public void Number(Text num) { StartCoroutine(Num(num)); } /// /// 字体动效的携程 /// /// 文本信息 /// IEnumerator Num(Text num) { while (true) { num.fontSize = 42; yield return new WaitForSeconds(0.5f); num.fontSize = 35; yield return new WaitForSeconds(0.1f); num.fontSize = 30; yield return new WaitForSeconds(0.3f); } } /// /// 第一次弹出楼梯队形 /// public void Frist() { isFrist=true; DiaLogBox2?.SetActive(true); Close1Panel.SetActive(false); FreePanel.SetActive(true); } /// /// 创建疏散情况内容 /// /// 文本内容 public void CreateSituation(string str) { GameObject newText = Instantiate(TextPrefab2); newText.transform.SetParent(content2.transform, false); Text text = newText.GetComponentInChildren(); text.text = str; // 按照班级排序 initialized(); } #region 疏散情况按班级排序功能实现 //数据初始化 public void initialized() { foreach (Transform child in gridLayoutGroup.transform) { // 初始化时获取所有子文本框 textFields.Clear(); Text textComponent = child.GetComponent(); if (textComponent != null) { textFields.Add(textComponent); } // 按照班级排序 SortByClass(); } } // 按照班级号排序 public void SortByClass() { // 排序之前先解析班级数字 textFields = textFields.OrderBy(t => ParseClassNumber(t.text)).ToList(); // 重新排列文本框的位置(GridLayoutGroup 会自动处理) for (int i = 0; i < textFields.Count; i++) { textFields[i].transform.SetSiblingIndex(i); // 更新顺序 } } // 解析班级号,例如 "4-1班" 变为 4-1 int ParseClassNumber(string classText) { // 使用正则表达式提取类似 "4-1" 的班级号 Match match = Regex.Match(classText, @"(\d+)-(\d+)"); if (match.Success) { int part1 = int.Parse(match.Groups[1].Value); // 提取第一个数字 int part2 = int.Parse(match.Groups[2].Value); // 提取第二个数字 return part1 * 100 + part2; // 返回合成数值,用于排序 } Debug.LogError($"无法解析班级号: {classText}"); return 0; // 默认返回 0,表示无法解析 } #endregion //动画部分 public void OnClickHideButton() { // 如果按钮已隐藏,点击后显示 if (isHidden) { // 恢复按钮到原位置 buttonRect.DOAnchorPosX(showPositionX, moveDuration).SetEase(Ease.InOutCubic); // 让面板B滑动到显示位置,同时面板A向左移动 panelA.DOAnchorPosX(-panelAMoveDistance, moveDuration).SetEase(Ease.InOutCubic); // 面板A同时移动 bg.transform.Rotate(0, 0, 180f); isHidden = false; // 更新状态为未隐藏 } else { // 隐藏按钮 // 让面板B滑动到隐藏位置,同时面板A恢复原位 buttonRect.DOAnchorPosX(hidePositionX, moveDuration).SetEase(Ease.InOutCubic); panelA.DOAnchorPosX(-45f, moveDuration).SetEase(Ease.InOutCubic); // 面板A恢复原位 bg.transform.Rotate(0, 0, 180f); isHidden = true; // 更新状态为隐藏 } } /// /// 道具需要执行的 /// /// 从左->右 public void Prop(int a) { switch (a) { case 1: break; case 2: break; case 3: break; case 4: break; case 5: break; case 6: break; } } /// /// 地图地点 /// /// 1-操场 2-教室 3-厨房 4-楼道 public void MapTP(int a) { switch (a) { case 1: FireText.color = new Color(1f, 1f, 1f); TileText.text = "请选择无法用于疏散的楼道"; break; case 2: FireText.color = new Color(1f, 1f, 1f); TileText.text = "请选择无法用于疏散的楼道"; break; case 3: FireText.color = new Color(1f, 1f, 1f); TileText.text = "请选择无法用于疏散的楼道"; break; case 4: FireText.color = new Color(1f, 1f, 1f); TileText.text = "请选择无法用于疏散的楼道"; break; } } /// /// 下拉列表执行的事件 /// /// void DropdownValueChanged(Dropdown change) { int index = change.value; switch (index) { case 0: // 执行 Option 1 相关的事件 Debug.Log("Option 1 selected"); break; case 1: // 执行 Option 2 相关的事件 Debug.Log("Option 2 selected"); break; case 2: // 执行 Option 3 相关的事件 Debug.Log("Option 3 selected"); break; case 3: break; case 4: break; case 5: break; } } /// /// 打开起火点面板 /// public void OpenFirePanel() { TipTilte.SetActive(true); MapTapPanel.SetActive(true); } /// /// 关闭起火点面板 /// public void CloseFirePanel() { TipTilte.SetActive(false); MapTapPanel.SetActive(false); } /// /// 撤离方案框的初始化 /// /// public void InitializeFlee(int ID) { // 动态创建指定数量的子物体并保存它们 for (int i = 0; i < itemCount; i++) { GameObject newItem = Instantiate(itemPrefab, content3.transform); Text left = newItem.transform.Find("Choose_Bg/Choose_BgLeft/Left").GetComponent(); Text Right = newItem.transform.Find("Choose_Bg/Choose_BgLeft/Right").GetComponent(); left.text = jsonReader.SetUIText("20000"); Right.text = jsonReader.SetUIText((ID+i).ToString()); Toggle toggle = newItem.gameObject.GetComponent(); Choose1 chooseScript = newItem.GetComponent(); toggle.group = toggleGroup; // 绑定点击事件 int index = i; // 保证每个 Toggle 有不同的 index toggle.onValueChanged.AddListener((bool isOn) => OnToggleClicked(isOn, index, chooseScript)); // left.text=js createdItems.Add(newItem); // 将新创建的物体添加到列表中 ToggleCount++; } RandomPos(); } /// /// 用于打乱选项顺序 /// public void RandomPos() { // 打乱顺序(使用 Fisher-Yates 算法) System.Random rand = new System.Random(); int n = createdItems.Count; for (int i = n - 1; i > 0; i--) { int j = rand.Next(i + 1); GameObject temp = createdItems[i]; createdItems[i] = createdItems[j]; createdItems[j] = temp; } // 按照打乱后的顺序重新排列物体 foreach (GameObject item in createdItems) { item.transform.SetSiblingIndex(createdItems.IndexOf(item)); // 设置物体的兄弟索引 } // 强制刷新布局 LayoutRebuilder.ForceRebuildLayoutImmediate(content3.GetComponent()); } public void GcreationSelect(int ID) { GameObject newItem = Instantiate(itemPrefab, content3.transform); Text left = newItem.transform.Find("Choose_Bg/Choose_BgLeft/Left").GetComponent(); Text Right = newItem.transform.Find("Choose_Bg/Choose_BgLeft/Right").GetComponent(); left.text = jsonReader.SetUIText("20000"); Right.text = jsonReader.SetUIText(ID.ToString()); Toggle toggle = newItem.gameObject.GetComponent(); Choose1 chooseScript = newItem.GetComponent(); toggle.group = toggleGroup; // 绑定点击事件 int index = ++ToggleCount; // 保证每个 Toggle 有不同的 index toggle.onValueChanged.AddListener((bool isOn) => OnToggleClicked(isOn, index,chooseScript)); createdItems.Add(newItem); // 将新创建的物体添加到列表中 RandomPos(); } /// /// 已经安全撤离的班级 上报总指 按钮事件 /// public void SumbitButton() { } /// /// 未安全撤离的班级 上报总指 按钮事件 /// public void Sumbit2Button() { } /// /// 打开关闭点火界面 /// public void FirePanel() { FireText.color = new Color(0.75f, 0.75f, 0.75f); if (MapTapPanel.activeSelf) { MapTapPanel.SetActive(false); } else { MapTapPanel.SetActive(true); } } /// /// 疏散提示 /// public void WarnPanel() { if (Command02.activeSelf) { Command02.SetActive(false); isEnd = false; StopCoroutine(Flicker()); } else { Command02.SetActive(true); isEnd = true; StartCoroutine(Flicker()); } } /// /// 动效的携程 /// /// IEnumerator Flicker() { while (isEnd) { //Bg1.color= new Color(1f, 1f, 1f); Bg1.sprite = Image1; //Bg.color = new Color(1f, 0f, 0f); yield return new WaitForSeconds(0.6f); //Bg.color = new Color(1f, 1f, 1f); //Bg1.color = new Color(1f, 0f, 0f); Bg1.sprite = Image2; yield return new WaitForSeconds(0.6f); } } public void FixWarnPanelText(string str) { WartipText.text = str; } /// /// 撤离方案选着 /// public void DialogboxPanel() { if (DiaLogBox.activeSelf) { DiaLogBox.SetActive(false); } else { DiaLogBox.SetActive(true); } } /// /// 下楼梯队形选择 /// public void DialogBoxPanel2Panel() { if (DiaLogBox2.activeSelf) { DiaLogBox2.SetActive(false); } else { DiaLogBox2.SetActive(true); } } /// /// 创建紧急通告 /// /// 文本内容 public void CreateWarn(string str) { GameObject newText = Instantiate(TextPrefab); newText.transform.SetParent(content.transform, false); Text text = newText.GetComponentInChildren(); text.text = str; } /// /// 弹出提示框 /// public void PopTip() { TipPanel.SetActive(true); TipText.text = "用时" + TimeText.text + "学生疏散完毕"; //从透明开始 TipText.color = new Color(TipText.color.r, TipText.color.g, TipText.color.b, 0f); TipBg.color = new Color(TipText.color.r, TipText.color.g, TipText.color.b, 0f); StartCoroutine(FadeInOutRoutine()); } /// /// 提示面板淡入淡出的携程 /// /// IEnumerator FadeInOutRoutine() { isFading = true; // 设置正在淡入淡出标志 // 淡入 float elapsedTime = 0f; while (elapsedTime < fadeInDuration) { elapsedTime += Time.deltaTime; Color textColor = TipText.color; textColor.a = elapsedTime / fadeInDuration; // 根据时间计算alpha值 TipText.color = textColor; TipBg.color = textColor; yield return null; // 等待下一帧 } // 显示文本一段时间 yield return new WaitForSeconds(displayDuration); // 淡出 elapsedTime = 0f; while (elapsedTime < fadeOutDuration) { elapsedTime += Time.deltaTime; Color textColor = TipText.color; textColor.a = 1f - (elapsedTime / fadeOutDuration); // 根据时间计算alpha值 TipText.color = textColor; TipBg.color = textColor; yield return null; // 等待下一帧 } isFading = false; // 重置正在淡入淡出标志 fadeCoroutine = null; // 重置协程引用 TipPanel.SetActive(false); } #region 修改文本 /// /// 修改楼梯口的三个文本信息 /// /// 1-第一个,2第二个,3第三个 /// 楼梯口信息 public void FixStairway(int a, string str) { switch (a) { case 1: icn_stairway_text_1.text = str; break; case 2: icn_stairway_text_2.text = str; break; case 3: icn_stairway_text_3.text = str; break; } } /// /// 修改总指挥头像,名字,内容 /// /// 头像图片 /// 名字 /// 内容 public void FixWarn_Tip(Image headImage, string name, string Message) { HeadImage = headImage; Head_Text.text = name; WarnTip_Text.text = Message; } /// /// 给我张三geigei看的(偷懒的,我错了HYLgeigei) /// /// public void CSZS(string ID) { switch (ID) { case "8000": Head_Text.text = "主持人"; break; case "8001": Head_Text.text = "总指挥"; break; case "8002": Head_Text.text = "抢险救援组"; break; case "8003": Head_Text.text = "(组长)抢险救援组"; break; case "8004": Head_Text.text = "医疗救护组"; break; case "8005": Head_Text.text = "(组长)医疗救援组"; break; case "8006": Head_Text.text = "疏散引导组1"; break; case "8007": Head_Text.text = "疏散引导组2"; break; case "8008": Head_Text.text = "后勤保障组"; break; case "8009": Head_Text.text = "(组长)后勤保障组"; break; case "8010": Head_Text.text = "搜寻组"; break; case "8011": Head_Text.text = "学生寝室长"; break; } } /// /// 修改总指挥框框 无图像,名字,内容 /// /// 名字 /// 内容 public void FixWarn_Tip(string name, string Message) { Head_Text.text = name; WarnTip_Text.text = Message; } /// /// 修改地图上两个带图标的(骷髅头,电话) /// /// 1-骷髅头,2-电话 /// 修改的文本内容 public void FixMessage(int a, string Message) { switch (a) { case 1: MessageText.text = Message; break; case 2: MessageText2.text = Message; break; } } /// /// 修改右边框框内容 /// /// 内容 /// 从上到下 public void FixWarn(int a, string str) { switch (a) { case 1: Tip_1.text = str; break; case 2: Tip_2.text = str; break; case 3: Tip_3.text = str; break; case 4: Tip_4.text = str; break; } } /// /// 修改网络延迟 /// /// 网络延迟的数字部分 public void FixDelay(string str) { WLYC.text = "网络延迟:" + str; } /// /// 修改疏散班级情况 /// /// 班级撤离情况 /// 更新第几条消息从上往下 public void FixSituation(int a, string str) { switch (a) { case 1: Situation_Tip_1.text = str; break; case 2: Situation_Tip_2.text = str; break; case 3: Situation_Tip_3.text = str; break; case 4: Situation_Tip_4.text = str; break; } } /// /// 修改成功撤离班级的信息 /// /// 撤离班级的名字 /// 人数 public void FixFledOk(int a, string str) { Right_MessageText.text = str; int currentValue = int.Parse(Student_Number.text); currentValue = a; // 更新 InputField 的文本 Student_Number.text = currentValue.ToString(); } /// /// 修改未撤离成功 /// /// 人数 /// 班级 /// 共多少名学生 public void FixNo(int a, string str, string str2) { NO_Left_MessageText.text = str; NO_Right_MessageText.text = str2; NO_Student.text = a.ToString(); } /// /// 清点人数时 修改管理区域 /// /// 区域名 public void FixArea(string str) { Area.text = str; } /// /// 清点人数时 修改NPC名 /// /// NPC名 public void FixNPCName(string str) { NPCName.text = str; } public void FixTitle(string str) { str= DiaLogBoxTitle.text; } #endregion /// /// 撤离教室的方案选择 /// /// /// private void OnToggleClicked(bool isOn, int index, Choose1 chooseScript) { switch(index) { case 0: chooseScript.isShow = isOn; break; case 1: chooseScript.isShow = isOn; break; case 2: chooseScript.isShow = isOn; break; } } private void Close() { DiaLogBox2?.SetActive(false); DiaLogBox?.SetActive(false); } }