_xiaofang/xiaofang/Assets/Script/Scheduled_03/Panel.cs
2024-12-01 22:36:41 +08:00

443 lines
16 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<GameObject> peopleList = new List<GameObject>(); // 存储所有已加载的人员预制体
private List<GameObject> filteredPeopleList = new List<GameObject>(); // 存储筛选后的人员列表
private GameObject selectedPerson = null; // 当前选中的角色
public SelectedInfo selectedInfo;
public Dictionary<string, List<SelectedInfo>> sceneDataDictionary = new Dictionary<string, List<SelectedInfo>>();//不同的场景存取不同的人员数据
public ManagerPanel managerPanel1;
public JSONReader jsonReader1;
public SelectScenePanel selectScenePanel;
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<GameObject>(peoplePrefab, peopleCountent);
PeopleItem peopleItem = item.GetComponent<PeopleItem>();
peopleList.Add(item);// 将每个实例化的角色添加到列表中
}
}
//动态加载职责
public void DynamicLoadingDuty()
{
Debug.Log("||||||||||||||||||||||||||||"+ selectScenePanel.eventId);
foreach (var npcData in jsonReader1.npcDictionary)
{
string[] nameSections = npcData.Value.Name.Split('|');
foreach (var section in nameSections)
{
string[] sectionParts = section.Split(',');
if (int.Parse(sectionParts[0])== 2001)
{
int key = int.Parse(sectionParts[1]);
if (jsonReader1.npcDictionary.ContainsKey(key))
{
var npcInfo = jsonReader1.npcDictionary[key];
// 在此处可以使用npcInfo做进一步的处理
Debug.Log("Found NPC: " + npcInfo.Name);
// 创建DutyItem实例
GameObject item = GameObject.Instantiate(dutyPrefab, dutyCount);
DutyItem dutyItem = item.GetComponent<DutyItem>();
dutyItem.dutyNameText.text = npcData.Value.Note;
dutyItem.leader = npcData.Value.GroupLeader;
peopleList.Add(item);
}
}
//GameObject item = GameObject.Instantiate<GameObject>(dutyPrefab, dutyCount);
//DutyItem dutyItem = item.GetComponent<DutyItem>();
//dutyItem.dutyNameText.text = npcData.Value.Note;
//dutyItem.leader = npcData.Value.GroupLeader;
//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<GameObject>(scenePrefab, sceneCount);
SceneItem sceneItem = item.GetComponent<SceneItem>();
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<ManagerPanel>();
Text sceneText= managerPanelInstance.transform.Find("top/sceneName").GetComponent<Text>();
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<SelectedInfo>();
}
// 需要判断是否达到了职责的人员上限
bool isLimitReached = false;
// 获取当前场景中的所有人员信息
List<SelectedInfo> 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<RaycastResult> results = new List<RaycastResult>();
// 射线检测 UI
raycaster.Raycast(pointerData, results);
// 遍历射线检测的结果
foreach (RaycastResult result in results)
{
// 检测到点击了按钮
Button clickedButton = result.gameObject.GetComponent<Button>();
if (clickedButton != null)
{
Text buttonText = clickedButton.GetComponentInChildren<Text>();
if (buttonText != null && buttonText.tag == Tags.people) // 获取标签为人员的信息
{
name = buttonText.text;
Debug.Log(name);
selectedInfo.name = name;
isPersonSelected = true; // 选择了人员
}
else if (buttonText != null && buttonText.tag == Tags.scene) // 获取标签为场景的信息
{
scene = buttonText.text;
Debug.Log(scene);
selectedInfo.scene = scene;
isSceneSelected = true; // 选择了场景
}
else if (buttonText != null && buttonText.tag == Tags.duty) // 获取标签为职责的信息
{
duty = buttonText.text;
Debug.Log(duty);
selectedInfo.duty = duty;
isDutySelected = true; // 选择了职责
}
}
}
// 根据选择情况,启用或禁用确认按钮
UpdateConfirmButtonState();
}
}
//==========================================================功能===========================================
//判断是否能够点击按钮
private void UpdateConfirmButtonState()
{
// 如果人员、职责和场景都已选择,则启用确认按钮,否则禁用
sureBtn.interactable = isPersonSelected && isDutySelected && isSceneSelected;
}
//设置安排文字
public void SetText()
{
arrangeText.text = "[" + name + "]担任[" + duty + "],位于[" + scene + "]";
}
//筛选
public void SetInputFile()
{
// 获取输入框内容
string filterText = shaixuaninputField.text.Trim();
// 遍历所有已实例化的人员预制体
foreach (Transform child in peopleCountent)
{
// 获取该子物体上的 Text 组件
Text personNameText = child.GetComponentInChildren<Text>();
if (personNameText != null)
{
// 比较输入框中的内容与人员姓名
if (personNameText.text.Contains(filterText))
{
// 如果匹配,显示该人员
child.gameObject.SetActive(true);
}
else
{
// 如果不匹配,隐藏该人员
child.gameObject.SetActive(false);
}
}
}
}
// 点击选中角色,改变视觉效果(可复用)
public void OnPeopleItemClicked(GameObject clickedItem)
{
// 如果有之前选中的角色,重置其视觉效果
if (selectedPerson != null)
{
Text prevText = selectedPerson.GetComponentInChildren<Text>();
if (prevText != null)
{
prevText.fontSize = 32; // 恢复原始字号
prevText.color = Color.white; // 恢复原始颜色
}
}
// 设置当前选中的角色为选中状态
selectedPerson = clickedItem;
Text personText = clickedItem.GetComponentInChildren<Text>();
if (personText != null)
{
// 字号变大和颜色变更(选中状态)
personText.fontSize = 36;
personText.color = Color.yellow; // 选中颜色
}
}
// 更新人员列表的显示颜色
private void UpdatePeopleListVisual()
{
// 遍历所有已加载的人员预制体,检查是否已添加到场景
foreach (GameObject personItem in peopleList)
{
// 获取人员的名字和显示文本
Text personText = personItem.GetComponentInChildren<Text>();
if (personText != null)
{
// 检查该人员是否已经添加到当前场景
bool isPersonAdded = sceneDataDictionary[selectedInfo.scene].Any(info => info.name == personText.text);
// 如果该人员已经被添加到场景,改变颜色为灰色
if (isPersonAdded)
{
personText.color = Color.blue; // 已添加人员的颜色
}
else
{
personText.color = Color.white; // 未添加人员的颜色
}
}
}
}
}