创建Scroll View
设置Content锚点参数添加组件
创建预制体Item添加toggle组件
新建Content并添加组件和设置锚点
准备工作完成后开始编写代码
using System.Xml;
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
public class XMLToScrollView : MonoBehaviour
{
public RectTransform scrollContent;
public GameObject nodePrefab;
public GameObject leafPrefab;
public GameObject partPrefab;
private Dictionary<string, bool> selectedParts = new Dictionary<string, bool>();
void Start()
{
LoadXMLData(Application.streamingAssetsPath+ "/Configs/dataConfig_pz.xml");
}
void LoadXMLData(string xmlPath)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xmlPath);
XmlNode root = xmlDoc.DocumentElement;
foreach (XmlNode node in root.ChildNodes)
{
GameObject nodeObj = Instantiate(nodePrefab, scrollContent);
Toggle nodeToggle = nodeObj.GetComponent<Toggle>();
nodeObj.GetComponentInChildren<Text>().text = node.Attributes["name"].Value;
nodeToggle.onValueChanged.AddListener(delegate { OnNodeToggleChanged(nodeToggle, nodeObj.transform.Find("Content")); });
float nodeHeight = 0;
foreach (XmlNode leaf1 in node.ChildNodes)
{
GameObject leafObj1 = Instantiate(leafPrefab, nodeObj.transform.Find("Content"));
Toggle leafToggle1 = leafObj1.GetComponent<Toggle>();
leafObj1.GetComponentInChildren<Text>().text = leaf1.Attributes["name"].Value;
leafToggle1.onValueChanged.AddListener(delegate { OnLeafToggleChanged(leafToggle1, leafObj1.transform.Find("Content")); });
float leaf1Height = 0;
foreach (XmlNode leaf2 in leaf1.ChildNodes)
{
GameObject leafObj2 = Instantiate(leafPrefab, leafObj1.transform.Find("Content"));
Toggle leafToggle2 = leafObj2.GetComponent<Toggle>();
leafObj2.GetComponentInChildren<Text>().text = leaf2.Attributes["name"].Value;
leafToggle2.onValueChanged.AddListener(delegate { OnLeafToggleChanged(leafToggle2, leafObj2.transform.Find("Content")); });
float leaf2Height = 0;
XmlNodeList partList = leaf2.ChildNodes;
foreach (XmlNode part in partList[0].ChildNodes)
{
GameObject partObj = Instantiate(partPrefab, leafObj2.transform.Find("Content"));
Toggle partToggle = partObj.GetComponent<Toggle>();
partObj.GetComponentInChildren<Text>().text = part.Attributes["step"].Value;
string partId = part.Attributes["id"].Value;
partToggle.onValueChanged.AddListener(delegate { OnPartToggleChanged(node.Attributes["name"].Value + "&" + leaf1.Attributes["name"].Value + "&" + leaf2.Attributes["name"].Value + "&" + part.Attributes["id"].Value, partToggle.isOn); });
//selectedParts.Add(node.Attributes["name"].Value + "&"+ leaf1.Attributes["name"].Value+"&"+ leaf2.Attributes["name"].Value+ "&"+part.Attributes["id"].Value, partToggle);
leaf2Height += AdjustHeight(partObj);
}
leaf1Height += AdjustHeight(leafObj2, leaf2Height);
}
nodeHeight += AdjustHeight(leafObj1, leaf1Height);
}
AdjustHeight(nodeObj, nodeHeight);
// 设置 Toggle 选择状态时,子级同步
nodeToggle.onValueChanged.AddListener(isOn => SetChildrenToggleState(nodeObj.transform, isOn));
}
}
void OnNodeToggleChanged(Toggle nodeToggle, Transform nodeTransform)
{
SetChildrenToggles(nodeTransform, nodeToggle.isOn);
}
void OnLeafToggleChanged(Toggle leafToggle, Transform leafTransform)
{
SetChildrenToggles(leafTransform, leafToggle.isOn);
}
void OnPartToggleChanged(string partId, bool isOn)
{
if (selectedParts.ContainsKey(partId))
{
selectedParts[partId] = isOn;
}
else
{
selectedParts.Add(partId, isOn);
}
}
void SetChildrenToggles(Transform parent, bool isOn)
{
foreach (Transform child in parent)
{
Toggle childToggle = child.GetComponentInChildren<Toggle>();
if (childToggle != null)
{
childToggle.isOn = isOn;
SetChildrenToggles(child, isOn); // 递归设置子节点
}
}
}
float AdjustHeight(GameObject obj, float additionalHeight = 0f)
{
RectTransform rect = obj.GetComponent<RectTransform>();
float originalHeight = rect.rect.height;
float newHeight = originalHeight + additionalHeight;
rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, newHeight);
return newHeight;
}
void SetChildrenToggleState(Transform parent, bool isOn)
{
foreach (Transform child in parent)
{
Toggle toggle = child.GetComponent<Toggle>();
if (toggle != null)
{
toggle.isOn = isOn;
SetChildrenToggleState(child, isOn); // 递归设置子级状态
}
}
}
//获取当前选中ID
public List<string> GetSelectedPartIds()
{
List<string> selectedPartIds = new List<string>();
foreach (var partToggle in selectedParts)
{
if (partToggle.Value)
{
selectedPartIds.Add(partToggle.Key);
}
}
return selectedPartIds;
}
}
编写好脚本按需求添加变量值
测试调用GetSelectedPartIds()方法,遍历可以查看选中的数据