622 lines
18 KiB
C#
622 lines
18 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Numerics;
|
||
using JetBrains.Annotations;
|
||
using Newtonsoft.Json;
|
||
using TMPro;
|
||
using Unity.VisualScripting;
|
||
using UnityEditor.Rendering.LookDev;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
public class FreePanelManager : MonoBehaviour
|
||
{
|
||
[Header("测试")]
|
||
public Sprite TestImage;
|
||
[Header("面板")]
|
||
//职业选择面板
|
||
public GameObject OccupationPanel;
|
||
//特殊情况弹窗
|
||
public GameObject TipPanel;
|
||
public GameObject AccidentIPanel;
|
||
//职业介绍框框
|
||
public List<GameObject> OpcList;
|
||
//疏散顺序的确定按钮
|
||
public GameObject EvacuateSurePanel;
|
||
//疏散顺序面板
|
||
public GameObject EvacuatePanel;
|
||
//次级面板
|
||
public GameObject minPanel1;
|
||
public GameObject minPanel2;
|
||
public GameObject minPanel3;
|
||
public GameObject minPanel4;
|
||
public GameObject minPanel5;
|
||
public GameObject minPanel6;
|
||
public GameObject minPanel7;
|
||
public GameObject minPanel8;
|
||
public GameObject minPanel9;
|
||
[Header("图像")]
|
||
//特殊情况弹窗背景图
|
||
public Image TipBg;
|
||
//事故点截图
|
||
public Image AccidentImage;
|
||
[Header("按钮")]
|
||
public Button AccidentButton;
|
||
public Button OpcLeft;
|
||
public Button OpcRight;
|
||
public Button EvacuateButton;
|
||
public Button EvacuateSure;
|
||
public Button Evacuate1Button;
|
||
public Button Evacuate2Button;
|
||
public Button Evacuate3Button;
|
||
public Button Evacuate4Button;
|
||
[Header("文本")]
|
||
//特殊情况弹窗文本
|
||
public Text TipText;
|
||
//疏散顺序描述
|
||
public Text EvacuateText1;
|
||
public Text EvacuateText2;
|
||
public Text EvacuateText3;
|
||
public Text EvacuateText4;
|
||
[Header("一些奇奇怪怪的东西")]
|
||
#region 特殊情况淡入淡出效果
|
||
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 bool isFadeEnd = false;
|
||
// 运行中的淡入淡出协程引用
|
||
private Coroutine fadeCoroutine;
|
||
#endregion
|
||
|
||
#region 创建职业介绍
|
||
public List<GameObject> createdItems = new List<GameObject>();//保存内容用的列表
|
||
public List<string> Order = new List<string>();//保存底板的字段
|
||
public GameObject content1; // Scroll View 的 Content 物体
|
||
public List<string> OpcName = new List<string>(); //保存职业任务介绍
|
||
public Sprite InfoBg;//介绍的底板
|
||
private int itemCount = 1; // 要创建的物体数量
|
||
public GameObject itemPrefab; // 子物体的预制件
|
||
public GameObject Order2Prefab;//带有次级面板
|
||
public JSONReader JSONReader;
|
||
#endregion
|
||
|
||
#region 创建职业面板
|
||
public List<string> OpcItems = new List<string>(); //保存需要创建几个职业
|
||
public List<Transform> DirectChildren = new List<Transform>();//用于保存Item的子物体 方便左右
|
||
public List<GameObject> TagChildren = new List<GameObject>();//用于保存Item子物体带有标签的,用与放职业介绍
|
||
public GameObject Item;//创建在谁的jio下
|
||
public List<string> TaskId = new List<string>();//保存玩家接取的任务
|
||
public GameObject OpcPrefab;//职业预制体
|
||
public Image OpcImage;//预制体图片
|
||
public Text OpcText;//预制体文本内容
|
||
#endregion
|
||
private static int a = 0;
|
||
private static int bb = 5;
|
||
public static FreePanelManager Z;
|
||
public void Start()
|
||
{
|
||
Z = this;
|
||
ContainsValue(11002);
|
||
if (DirectChildren.Count>=5)
|
||
{
|
||
OpcRight.gameObject.SetActive(true);
|
||
}
|
||
#region 初始化的东西
|
||
InitializeChild();
|
||
#endregion
|
||
//职业介绍框左按钮
|
||
OpcLeft.onClick.AddListener(() =>
|
||
{
|
||
LeftRight(a, -1);
|
||
});
|
||
//职业介绍框右按钮
|
||
OpcRight.onClick.AddListener(() =>
|
||
{
|
||
LeftRight(a, 1);
|
||
});
|
||
//疏散顺序的选项
|
||
#region 疏散顺序选项
|
||
Evacuate1Button.onClick.AddListener(() =>
|
||
{
|
||
|
||
EvacuateSurePanel.SetActive(true);
|
||
});
|
||
Evacuate2Button.onClick.AddListener(() =>
|
||
{
|
||
|
||
EvacuateSurePanel.SetActive(true);
|
||
});
|
||
Evacuate3Button.onClick.AddListener(() =>
|
||
{
|
||
|
||
EvacuateSurePanel.SetActive(true);
|
||
});
|
||
Evacuate4Button.onClick.AddListener(() =>
|
||
{
|
||
|
||
EvacuateSurePanel.SetActive(true);
|
||
});
|
||
#endregion
|
||
|
||
//疏散顺序的箭头
|
||
EvacuateButton.onClick.AddListener(() =>
|
||
{
|
||
|
||
EvacuatePanel.SetActive(false);
|
||
EvacuateSurePanel.SetActive(false);
|
||
});
|
||
//职业面板点击事件
|
||
#region 面板点击
|
||
#endregion
|
||
}
|
||
public void Update()
|
||
{
|
||
#region 测试
|
||
if (Input.GetKeyDown("j"))
|
||
{
|
||
// PopAccident(TestImage);
|
||
}
|
||
#endregion
|
||
if (isFadeEnd)
|
||
{
|
||
StopCoroutine(FadeInOutRoutine());
|
||
isFadeEnd = false;
|
||
}
|
||
|
||
}
|
||
public void FixedUpdate()
|
||
{
|
||
if (bb == DirectChildren.Count)
|
||
{
|
||
OpcRight.gameObject.SetActive(false);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 打开特殊情况弹窗
|
||
/// </summary>
|
||
public void PopTipPanel()
|
||
{
|
||
TipPanel.SetActive(true);
|
||
StopCoroutine(FadeInOutRoutine());
|
||
}
|
||
/// <summary>
|
||
/// 弹出事故框框并且修改图片
|
||
/// </summary>
|
||
/// <param name="image">传入一张事故图片(Spite)</param>
|
||
public void PopAccident(Sprite image)
|
||
{
|
||
AccidentImage.sprite = image;
|
||
AccidentIPanel.SetActive(true);
|
||
}
|
||
/// <summary>
|
||
/// 提示面板淡入淡出的携程
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
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; // 重置正在淡入淡出标志
|
||
isFadeEnd = true;//这个携程结束的标志
|
||
TipPanel.SetActive(false);
|
||
}
|
||
/// <summary>
|
||
/// 打开关闭职业选择面板
|
||
/// </summary>
|
||
public void OpenOccupation()
|
||
{
|
||
bool isActive = OccupationPanel.activeSelf;
|
||
// 如果面板已激活,则关闭,否则打开
|
||
OccupationPanel.SetActive(!isActive);
|
||
}
|
||
/// <summary>
|
||
/// 获取职业名字并且赋值到面板上
|
||
/// </summary>
|
||
/// <param name="ID">职业的ID</param>
|
||
/// <param name="a">第几个面板(从1开始)</param>
|
||
public void OcpNameChoose(int ID)
|
||
{
|
||
string str = JSONReader.GetOcpName(ID);
|
||
OpcText.text = str;
|
||
|
||
}
|
||
/// <summary>
|
||
/// 创建职业介绍内容(这个方法要联动OcpNameChoose方法的)
|
||
/// </summary>
|
||
/// <param name="ID">职业的ID</param>
|
||
/// <param name="content">放在那个一个子物体下</param>
|
||
public void CreateOcpText(string ID, GameObject content)
|
||
{
|
||
OpcName.Clear();
|
||
Order.Clear();
|
||
createdItems.Clear(); // 确保 createdItems 清空,避免重复数据
|
||
|
||
// 遍历 SelectDictionary
|
||
foreach (var kvp in JSONReader.ZZSelectsDictionary)
|
||
{
|
||
// 这里 kvp.Key 是字典的键,kvp.Value 是 Select 对象
|
||
Select select = kvp.Value;
|
||
|
||
// 判断 UIDetails 是否匹配,并且填充数据
|
||
if (select.UIDetails == ID.ToString())
|
||
{
|
||
// 将 Note 添加到 OpcName 列表
|
||
OpcName.Add(select.Note);
|
||
Order.Add(select.AppliedUI);
|
||
}
|
||
}
|
||
|
||
// 动态创建指定数量的子物体并保存它们
|
||
for (int i = 0; i < OpcName.Count; i++)
|
||
{
|
||
GameObject newItem;
|
||
|
||
// 如果 Order[i] 是 "order2",使用 Order2Prefab 创建
|
||
if (i < Order.Count && Order[i] == "order2")
|
||
{
|
||
newItem = Instantiate(Order2Prefab, content.transform);
|
||
Image image = newItem.GetComponent<Image>();
|
||
if (image != null)
|
||
{
|
||
image.sprite = InfoBg; // 设置背景图片
|
||
}
|
||
else
|
||
{
|
||
Debug.LogWarning($"未找到 Image 组件,无法设置背景图片,索引: {i}");
|
||
}
|
||
|
||
#region 废案
|
||
//// 找到新创建物体的子物体中的 Toggle
|
||
//Toggle toggle = newItem.transform.Find("Item")?.GetComponent<Toggle>();
|
||
//if (toggle != null)
|
||
//{
|
||
// int index = i; // 用局部变量保存当前索引,避免 Lambda 捕获问题
|
||
// Debug.Log($"绑定 Toggle 点击事件,索引: {index},文本: {OpcName[index]}");
|
||
|
||
// toggle.onValueChanged.AddListener((isOn) =>
|
||
// {
|
||
// if (isOn)
|
||
// {
|
||
// HandleToggleClick(index, newItem); // 调用通用处理方法
|
||
// }
|
||
// });
|
||
//}
|
||
//else
|
||
//{
|
||
// Debug.LogWarning($"未找到 Toggle 组件或子物体,索引: {i}");
|
||
//}
|
||
#endregion
|
||
}
|
||
else
|
||
{
|
||
// 否则使用默认的 itemPrefab 创建
|
||
newItem = Instantiate(itemPrefab, content.transform);
|
||
}
|
||
|
||
// 找到子物体的文本组件并设置内容
|
||
Text left = newItem.transform.Find("Text")?.GetComponent<Text>();
|
||
if (left != null)
|
||
{
|
||
left.text = OpcName[i]; // 设置文本内容
|
||
}
|
||
else
|
||
{
|
||
Debug.LogWarning($"未找到 Text 组件,索引: {i}");
|
||
}
|
||
|
||
// 将创建的物体添加到列表中
|
||
createdItems.Add(newItem);
|
||
}
|
||
}
|
||
#region 废案
|
||
|
||
|
||
//public void ToggleManger()
|
||
//{
|
||
// for (int i = 0; i < Order.Count; i++)
|
||
// {
|
||
// // 找到新创建物体的子物体中的 Toggle
|
||
// Toggle toggle= FindToggleInChildren();
|
||
// if (toggle != null)
|
||
// {
|
||
// int index = i; // 用局部变量保存当前索引,避免 Lambda 捕获问题
|
||
|
||
// toggle.onValueChanged.AddListener((isOn) =>
|
||
// {
|
||
// if (isOn)
|
||
// {
|
||
// HandleToggleClick(index, toggle.gameObject); // 调用通用处理方法
|
||
// }
|
||
// });
|
||
// }
|
||
// else
|
||
// {
|
||
// Debug.LogWarning($"未找到 Toggle 组件或子物体,索引: {i}");
|
||
// }
|
||
// }
|
||
//}
|
||
//// 处理 Toggle 点击逻辑(次级面板)
|
||
//private void HandleToggleClick(int index, GameObject toggleObject)
|
||
//{
|
||
// Debug.Log("进不啊来啦啊啊啊啊啊啊");
|
||
// if (index == 0 || index == 1) // 错误选项
|
||
// {
|
||
// Debug.Log($"错误选项被点击,删除 Toggle {index}, 文本内容: {OpcName[index]}");
|
||
// DeleteToggle(toggleObject); // 删除 Toggle
|
||
// }
|
||
// else if (index == 2) // 正确选项
|
||
// {
|
||
// Debug.Log($"正确选项被点击,执行正确逻辑,文本内容: {OpcName[index]}");
|
||
// HandleCorrectOption(); // 执行正确选项的逻辑
|
||
// }
|
||
//}
|
||
//// 删除 Toggle 的方法(次级面板)
|
||
//private void DeleteToggle(GameObject toggleObject)
|
||
//{
|
||
// if (toggleObject != null)
|
||
// {
|
||
// Debug.Log($"删除 Toggle: {toggleObject.name}");
|
||
|
||
// // 从父容器中移除
|
||
// Destroy(toggleObject);
|
||
|
||
// // 如果在 createdItems 列表中,移除它
|
||
// if (createdItems.Contains(toggleObject))
|
||
// {
|
||
// createdItems.Remove(toggleObject);
|
||
// }
|
||
// }
|
||
//}
|
||
// 正确选项的逻辑(次级面板)
|
||
//private void HandleCorrectOption()
|
||
//{
|
||
// Debug.Log("正确答案被选择,执行相关逻辑!");
|
||
// // 在这里添加正确选项的逻辑,例如显示提示、播放音效等
|
||
//}
|
||
// 方法:递归查找 newItem 下的所有子物体中带有 Toggle 组件的子物体
|
||
//public Toggle FindToggleInChildren()
|
||
//{
|
||
// // 遍历 createdItems 列表中的所有物体
|
||
// foreach (GameObject parent in createdItems)
|
||
// {
|
||
// // 确保父物体不为空
|
||
// if (parent == null) continue;
|
||
|
||
// // 创建一个队列,用于非递归查找子物体中的 Toggle
|
||
// Queue<Transform> queue = new Queue<Transform>();
|
||
// queue.Enqueue(parent.transform);
|
||
|
||
// while (queue.Count > 0)
|
||
// {
|
||
// Transform current = queue.Dequeue();
|
||
|
||
// // 检查当前子物体是否有 Toggle 组件
|
||
// Toggle toggle = current.GetComponent<Toggle>();
|
||
// if (toggle != null)
|
||
// {
|
||
// return toggle; // 找到第一个 Toggle 组件,立即返回
|
||
// }
|
||
|
||
// // 将当前物体的所有子物体加入队列
|
||
// foreach (Transform child in current)
|
||
// {
|
||
// queue.Enqueue(child);
|
||
// }
|
||
// }
|
||
// }
|
||
// // 如果没有找到 Toggle,返回 null
|
||
// return null;
|
||
//}
|
||
#endregion
|
||
//职业介绍界面左右按钮
|
||
private void LeftRight(int a, int b)
|
||
{
|
||
|
||
if (b > 0)
|
||
{
|
||
DirectChildren[a].gameObject.SetActive(false);
|
||
a += 1;
|
||
bb += 1;
|
||
}
|
||
if (b < 0)
|
||
{
|
||
DirectChildren[a].gameObject.SetActive(true);
|
||
|
||
a -= 1;
|
||
bb-=1;
|
||
}
|
||
//判断按钮是否显示
|
||
if (DirectChildren[0].gameObject.activeSelf)
|
||
{
|
||
OpcRight.gameObject.SetActive(true);
|
||
}
|
||
|
||
if (DirectChildren[0].gameObject.activeSelf)
|
||
{
|
||
OpcLeft.gameObject.SetActive(false);
|
||
}
|
||
else
|
||
{
|
||
OpcLeft.gameObject.SetActive(true);
|
||
}
|
||
|
||
}
|
||
//初始化职业的左右滑动
|
||
private void InitializeChild()
|
||
{
|
||
// 确保清空列表,避免重复数据
|
||
DirectChildren.Clear();
|
||
TagChildren.Clear();
|
||
//将子物体都存起来
|
||
Transform parent = Item.transform;
|
||
// 遍历所有直接子物体
|
||
for (int i = 0; i < parent.childCount; i++)
|
||
{
|
||
Transform child = parent.GetChild(i);
|
||
|
||
// 将子物体添加到 DirectChildren 列表
|
||
DirectChildren.Add(child);
|
||
}
|
||
//在子物体里找东西
|
||
for (int i = 0; i < DirectChildren.Count; i++)
|
||
{
|
||
Transform child = DirectChildren[i];
|
||
// 递归查找子物体中带标签的物体
|
||
FindChildrenWithTag(child, "Content");
|
||
}
|
||
|
||
}
|
||
//寻找Tap对应的物体
|
||
private void FindChildrenWithTag(Transform parent, string tag)
|
||
{
|
||
foreach (Transform child in parent)
|
||
{
|
||
|
||
|
||
if (child.CompareTag(tag))
|
||
{
|
||
TagChildren.Add(child.gameObject);
|
||
|
||
}
|
||
|
||
// 递归检查子物体的子物体
|
||
FindChildrenWithTag(child, tag);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 读取疏散路线
|
||
/// </summary>
|
||
/// <param name="ID">表内相对ID</param>
|
||
public void ReadEvacuateInfo(int ID)
|
||
{
|
||
|
||
}
|
||
/// <summary>
|
||
/// 动态分配职业地板颜色
|
||
/// </summary>
|
||
/// <param name="ID"></param>
|
||
public void LoadAndSetImage(int ID)
|
||
{
|
||
// 从 Resources 文件夹中加载图片
|
||
Sprite sprite = Resources.Load<Sprite>("ZZZOpcImage/" + ID.ToString());
|
||
|
||
if (sprite != null)
|
||
{
|
||
// 获取物体 A 上的 Image 组件
|
||
Image imageComponent = OpcImage;
|
||
if (imageComponent != null)
|
||
{
|
||
imageComponent.sprite = sprite;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("Image not found in Resources at: " + "颠仔没有快滚啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊");
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 判断创建那几个职业
|
||
/// </summary>
|
||
/// <param name="target">接取的任务ID</param>
|
||
public void ContainsValue(int target)
|
||
{
|
||
foreach (var kvp in JSONReader.ZZFindTaskID)
|
||
{
|
||
// 获取 Select 对象的列表
|
||
List<Select> selectList = kvp.Value;
|
||
|
||
foreach (var select in selectList)
|
||
{
|
||
// 确保 Precondition 不为空
|
||
if (string.IsNullOrEmpty(select.Precondition))
|
||
continue;
|
||
|
||
// 拆分字符串为多组
|
||
var groups = select.Precondition.Split(new char[] { '#', '|' }, StringSplitOptions.RemoveEmptyEntries);
|
||
|
||
foreach (var group in groups)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(group)) // 跳过空分组
|
||
continue;
|
||
|
||
// 拆分每一组数据为 `,` 分隔的项
|
||
var items = group.Split(',');
|
||
|
||
foreach (var item in items)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(item)) // 跳过空项
|
||
continue;
|
||
|
||
string trimmedItem = item.Trim(); // 去掉空格
|
||
if (int.TryParse(trimmedItem, out int value) && value == target)
|
||
{
|
||
if (!OpcItems.Contains(select.UIDetails))
|
||
{
|
||
OpcItems.Add(select.UIDetails); // 添加到结果集合
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
CreatOpc();
|
||
}
|
||
/// <summary>
|
||
/// 创建职业底板
|
||
/// </summary>
|
||
public void CreatOpc()
|
||
{
|
||
|
||
// 动态创建指定数量的子物体并保存它们
|
||
for (int i = 0; i < OpcItems.Count; i++)
|
||
{
|
||
GameObject newItem = Instantiate(OpcPrefab, Item.transform);
|
||
OcpNameChoose(int.Parse(OpcItems[i]));
|
||
newItem.SetActive(true);
|
||
LoadAndSetImage(int.Parse(OpcItems[i]));
|
||
|
||
OpcList.Add(newItem); // 将新创建的物体添加到列表中
|
||
}
|
||
InitializeChild();
|
||
for (int i = 1; i < OpcItems.Count + 1; i++)
|
||
{
|
||
CreateOcpText("8006", TagChildren[i]);
|
||
}
|
||
|
||
}
|
||
}
|