using Newtonsoft.Json; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using Unity.VisualScripting; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.SceneManagement; using UnityEngine.UI; public class SelectedInfo { public string name; public string duty; public string scene; public string leader; } public class Panel : MonoBehaviour { [Header("组件")] public Button choseJuBenSettingBtn; public Button emergencySettingBtn; public Button peoplePublishBtn; public Button materialReserveBtn; public Button dateSelectionBtn; public Button personnelmanagementBtn; public Button setName;//设置人员 public Button setDuty;//设置职责 public Button setScene;//设置场景 public Text arrangeText;//整体安排 public Button sureBtn;//确认信息按钮 public ToggleGroup scenetoggleGroup;//场景的ToggleGroup public InputField shaixuaninputField;//筛选输入框 public GraphicRaycaster raycaster; // 画布上的射线投射器 public EventSystem eventSystem; // 事件系统 [Header("物体")] public GameObject ManagerPanel;//人员管理界面 public Transform peopleCountent;//人员的窗口 public GameObject peoplePrefab;//人员的预制体 public Transform panelContent; public GameObject dutyPrefab;//职责预制体 public Transform dutyCount;//职责的窗口 public GameObject scenePrefab; public Transform sceneCount; public GameObject ManagerPanelPrefab; // 预制体,包含人员管理面板 [Header("数据")] public string name, duty, scene; private List peopleList = new List(); // 存储所有已加载的人员预制体 private List filteredPeopleList = new List(); // 存储筛选后的人员列表 private GameObject selectedPerson = null; // 当前选中的角色 public SelectedInfo selectedInfo; public Dictionary> sceneDataDictionary = new Dictionary>();//不同的场景存取不同的人员数据 public ManagerPanel managerPanel1; public JSONReader jsonReader1; private bool isPersonSelected = false; // 标志是否选择了人员 private bool isDutySelected = false; // 标志是否选择了职责 private bool isSceneSelected = false; // 标志是否选择了场景 // Start is called before the first frame update void Start() { selectedInfo = new SelectedInfo(); DynamicLoadingPeople(); DynamicLoadingDuty(); DynamicLoadingScene(); } // Update is called once per frame void Update() { GetData(); SetText(); //SetInputFile(); } //动态加载人员 public void DynamicLoadingPeople() { for (int i = 0; i < 20; i++) { GameObject item = GameObject.Instantiate(peoplePrefab, peopleCountent); PeopleItem peopleItem = item.GetComponent(); peopleList.Add(item);// 将每个实例化的角色添加到列表中 } } //动态加载职责 public void DynamicLoadingDuty() { foreach (var npcData in jsonReader1.npcDictionary) { GameObject item = GameObject.Instantiate(dutyPrefab, dutyCount); DutyItem dutyItem = item.GetComponent(); dutyItem.dutyNameText.text = npcData.Value.Note; dutyItem.leader = npcData.Value.GroupLeader; //Debug.Log("$$$$$$$$$$$$$$" + dutyItem.dutyNameText.text); peopleList.Add(item);// 将每个实例化的角色添加到列表中 } } //动态加载场景 public void DynamicLoadingScene() { foreach (var npcData in jsonReader1.locationDictionary) { // 解析角色限制字段 string roleLimit = npcData.Value.RoleLimit; if (!string.IsNullOrEmpty(roleLimit)) { // 先按“|”分隔 string[] roleLimitSections = roleLimit.Split('|'); // 遍历每个部分(按“|”分隔后得到的数组) bool shouldInstantiate = true; // 用于判断是否需要实例化 foreach (string section in roleLimitSections) { // 判断当前部分是否包含 "-1" 来决定是否跳过实例化 if (section.Contains("-1")) { // 判断职业ID或其他条件,决定是否跳过 string[] roleLimits = section.Split(','); // 这里假设职业ID在第一个位置,且为-1时表示不可作为出生点 if (roleLimits[0] == "-1") { //Debug.Log("该职业不能作为出生点,不在预订演练,跳过实例化!"); shouldInstantiate = false; // 不实例化该NPC break; // 跳出循环,直接处理下一个NPC } // 处理“-1”表示无限制人数的情况 if (roleLimits[2] == "-1") { //Debug.Log("角色限制为-1,区域限制人数为无限!"); // 可以选择设置limitNum为无限制 } } } // 如果不满足实例化条件,跳过当前NPC的实例化 if (!shouldInstantiate) { continue; } } // 实例化NPC预制体 GameObject item = GameObject.Instantiate(scenePrefab, sceneCount); SceneItem sceneItem = item.GetComponent(); sceneItem.sceneName.text = npcData.Value.Note; // 将每个实例化的角色添加到列表中 peopleList.Add(item); } } //处理人员管理按钮 public void ClickPersonnelManagement() { foreach (Transform child in panelContent) { Destroy(child.gameObject); } foreach (var sceneEntry in sceneDataDictionary) { //Debug.Log($"场景: {sceneEntry.Key},人数: {sceneEntry.Value.Count}"); GameObject managerPanelInstance = Instantiate(ManagerPanelPrefab, panelContent); //ManagerPanel managerPanelScript = managerPanelInstance.GetComponentInParent(); Text sceneText= managerPanelInstance.transform.Find("top/sceneName").GetComponent(); sceneText.text = sceneEntry.Key; managerPanel1.CreateScenePanel(sceneEntry.Key, sceneEntry.Value, managerPanelInstance); //managerPanel1.SetPlate(); ManagerPanel.gameObject.SetActive(true); } } //处理点击确认按钮 public void ClickSureBtn() { // 只有在选择了人员、职责和场景的情况下,才会执行后续操作 if (isPersonSelected && isDutySelected && isSceneSelected) { // 保存选中的人员信息到场景数据字典中 string sceneName = selectedInfo.scene; // 如果场景字典中没有这个场景,先创建一个空列表 if (!sceneDataDictionary.ContainsKey(sceneName)) { sceneDataDictionary[sceneName] = new List(); } // 需要判断是否达到了职责的人员上限 bool isLimitReached = false; // 获取当前场景中的所有人员信息 List currentSceneInfo = sceneDataDictionary[sceneName]; // 如果选中了“主持人”、“各组长”或“总指挥”,则限制数量为1 if (selectedInfo.duty == "主持人" || selectedInfo.duty == "组长" || selectedInfo.duty == "总指挥") { int count = currentSceneInfo.Count(info => info.duty == selectedInfo.duty); // 统计当前职责人数 if (count >= 1) // 如果已经有1个此职责的人选 { Debug.LogError($"{selectedInfo.duty} 已达最大人数限制"); isLimitReached = true; // 标记限制已达 } } // 如果没有达到上限,则可以添加人员信息 if (!isLimitReached) { // 通过创建一个新的 SelectedInfo 实例来避免引用同一个对象 SelectedInfo newSelectedInfo = new SelectedInfo { name = selectedInfo.name, duty = selectedInfo.duty, scene = selectedInfo.scene }; // 将当前选中的人员信息添加到对应场景的人员列表中 currentSceneInfo.Add(newSelectedInfo); // 打印当前场景人员信息 Debug.Log($"场景: {sceneName},选中的人员: {selectedInfo.name},职责: {selectedInfo.duty}"); // 禁用确认按钮并清空选择标志 sureBtn.interactable = false; // 禁用确认按钮 isPersonSelected = false; isDutySelected = false; isSceneSelected = false; // 改变已添加人员的显示颜色 UpdatePeopleListVisual(); } } else { Debug.LogError("请确保选择了人员、职责和场景!"); } // 可以在这里根据需求继续处理选中的数据 } //处理界面关闭按钮 public void ClickCloseBtn() { transform.gameObject.SetActive(false); } //获取鼠标点击位置的信息 public void GetData() { ManagerPanel managerPanel = new ManagerPanel(); // 当鼠标左键按下时进行检测 if (Input.GetMouseButtonDown(0)) { // 确保 raycaster 和 eventSystem 不为空 if (raycaster == null || eventSystem == null) { Debug.LogError("Raycaster 或 EventSystem 未正确分配,请在 Inspector 中进行分配。"); return; } // 创建 PointerEventData 来记录点击事件的数据 PointerEventData pointerData = new PointerEventData(eventSystem); pointerData.position = Input.mousePosition; // 获取鼠标点击的位置 // 用于存储射线检测的结果 List results = new List(); // 射线检测 UI raycaster.Raycast(pointerData, results); // 遍历射线检测的结果 foreach (RaycastResult result in results) { // 检测到点击了按钮 Button clickedButton = result.gameObject.GetComponent