using System.Linq; using TMPro; using UnityEditor; using UnityEngine; using UnityEngine.UI; public class UIParamCreatorWindow : EditorWindow { enum UIType { 单选, 多选, 输入框, 滑动条, 下拉菜单 } private UIType uiType; private bool showConfig; private TMP_FontAsset tmpFont; private string paramName; private string optionContent; private float toggleWidth = 140; private float toggleHeight = 36; private float inputWidth = 200; private float inputHeight = 36; private string unit; // Slider private float sliderMin = 0; private float sliderMax = 100; private float sliderWidth = 200; private float sliderHeight = 36; // Dropdown private float dropdownWidth = 200; private float dropdownHeight = 36; private GameObject dropdownPrefab; private GameObject singleTogglePrefab; private GameObject multiTogglePrefab; private GameObject inputPrefab; private GameObject sliderPrefab; [MenuItem("Tools/UI 参数生成器(预制体终版)")] static void Open() { GetWindow("UI 参数生成器"); } private void OnGUI() { uiType = (UIType)EditorGUILayout.EnumPopup("UI 类型", uiType); if (GUILayout.Button("确定")) { if (Selection.activeGameObject == null) { EditorUtility.DisplayDialog("错误", "请先选中父节点", "OK"); return; } showConfig = true; } if (!showConfig) return; EditorGUILayout.Space(); tmpFont = (TMP_FontAsset)EditorGUILayout.ObjectField("TMP 字体", tmpFont, typeof(TMP_FontAsset), false); paramName = EditorGUILayout.TextField("参数名称", paramName); if (uiType == UIType.单选 || uiType == UIType.多选 || uiType == UIType.下拉菜单) { optionContent = EditorGUILayout.TextField("选项(-分割)", optionContent); } if (uiType == UIType.单选 || uiType == UIType.多选) { toggleWidth = EditorGUILayout.FloatField("Toggle 宽", toggleWidth); toggleHeight = EditorGUILayout.FloatField("Toggle 高", toggleHeight); if (uiType == UIType.单选) singleTogglePrefab = (GameObject)EditorGUILayout.ObjectField("单选 Toggle 预制", singleTogglePrefab, typeof(GameObject), false); else multiTogglePrefab = (GameObject)EditorGUILayout.ObjectField("多选 Toggle 预制", multiTogglePrefab, typeof(GameObject), false); } if (uiType == UIType.输入框) { unit = EditorGUILayout.TextField("单位", unit); inputWidth = EditorGUILayout.FloatField("输入框宽", inputWidth); inputHeight = EditorGUILayout.FloatField("输入框高", inputHeight); inputPrefab = (GameObject)EditorGUILayout.ObjectField("输入框预制", inputPrefab, typeof(GameObject), false); } if (uiType == UIType.滑动条) { sliderMin = EditorGUILayout.FloatField("最小值", sliderMin); sliderMax = EditorGUILayout.FloatField("最大值", sliderMax); sliderWidth = EditorGUILayout.FloatField("Slider 宽", sliderWidth); sliderHeight = EditorGUILayout.FloatField("Slider 高", sliderHeight); sliderPrefab = (GameObject)EditorGUILayout.ObjectField("Slider 预制", sliderPrefab, typeof(GameObject), false); } if (uiType == UIType.下拉菜单) { dropdownWidth = EditorGUILayout.FloatField("Dropdown 宽", dropdownWidth); dropdownHeight = EditorGUILayout.FloatField("Dropdown 高", dropdownHeight); dropdownPrefab = (GameObject)EditorGUILayout.ObjectField("Dropdown 预制", dropdownPrefab, typeof(GameObject), false); } EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("生成")) { switch (uiType) { case UIType.单选: CreateSingle(); break; case UIType.多选: CreateMulti(); break; case UIType.输入框: CreateInput(); break; case UIType.滑动条: CreateSlider(); break; case UIType.下拉菜单: CreateDropdown(); break; } showConfig = false; } if (GUILayout.Button("取消")) { showConfig = false; } EditorGUILayout.EndHorizontal(); } #region 单选 void CreateSingle() { Transform parent = Selection.activeGameObject.transform; CreateLabel(parent, paramName); CreateHorizontalLayout2Parent(parent.gameObject); GameObject row = CreateHorizontalLayout(parent, "SingleGroup"); ToggleGroup group = row.AddComponent(); foreach (var opt in optionContent.Split('-').Where(o => !string.IsNullOrEmpty(o))) { GameObject toggle = InstantiateToggle(singleTogglePrefab, row.transform, opt); toggle.GetComponent().group = group; } } #endregion #region 多选 void CreateMulti() { Transform parent = Selection.activeGameObject.transform; CreateLabel(parent, paramName); CreateHorizontalLayout2Parent(parent.gameObject); GameObject gridGO = new GameObject("MultiGroup"); gridGO.transform.SetParent(parent, false); GridLayoutGroup grid = gridGO.AddComponent(); grid.cellSize = new Vector2(toggleWidth, toggleHeight); grid.constraint = GridLayoutGroup.Constraint.FixedColumnCount; grid.constraintCount = 3; grid.childAlignment = TextAnchor.UpperLeft; ContentSizeFitter fitter = gridGO.AddComponent(); fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; foreach (var opt in optionContent.Split('-').Where(o => !string.IsNullOrEmpty(o))) { InstantiateToggle(multiTogglePrefab, gridGO.transform, opt); } } #endregion #region 输入框 void CreateInput() { Transform parent = Selection.activeGameObject.transform; CreateHorizontalLayout2Parent(parent.gameObject); CreateLabel(parent, paramName); GameObject input = (GameObject)PrefabUtility.InstantiatePrefab(inputPrefab, parent); LayoutElement le = input.GetComponent() ?? input.AddComponent(); le.preferredWidth = inputWidth; le.preferredHeight = inputHeight; if (!string.IsNullOrEmpty(unit)) CreateLabel(parent, unit); } #endregion #region 滑动条 void CreateSlider() { Transform parent = Selection.activeGameObject.transform; CreateHorizontalLayout2Parent(parent.gameObject); CreateLabel(parent, paramName); GameObject sliderGO = (GameObject)PrefabUtility.InstantiatePrefab(sliderPrefab, parent); Slider slider = sliderGO.GetComponent(); slider.minValue = sliderMin; slider.maxValue = sliderMax; slider.value = sliderMin; LayoutElement le = sliderGO.GetComponent() ?? sliderGO.AddComponent(); le.preferredWidth = sliderWidth; le.preferredHeight = sliderHeight; // 数值显示 GameObject valueGO = new GameObject("Value_TMP"); valueGO.transform.SetParent(parent, false); TextMeshProUGUI valueText = valueGO.AddComponent(); valueText.font = tmpFont; valueText.fontSize = 22; valueText.color = Color.black; valueText.text = sliderMin.ToString("0"); ContentSizeFitter fitter = valueGO.AddComponent(); fitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize; fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; slider.onValueChanged.AddListener(v => { valueText.text = Mathf.RoundToInt(v).ToString(); }); } #endregion #region 工具方法 GameObject InstantiateToggle(GameObject prefab, Transform parent, string label) { GameObject go = (GameObject)PrefabUtility.InstantiatePrefab(prefab, parent); LayoutElement le = go.GetComponent() ?? go.AddComponent(); le.preferredWidth = toggleWidth; le.preferredHeight = toggleHeight; var text = go.GetComponentInChildren(); if (text) text.text = label; return go; } GameObject CreateHorizontalLayout(Transform parent, string name) { GameObject go = new GameObject(name); go.transform.SetParent(parent, false); HorizontalLayoutGroup layout = go.AddComponent(); layout.childControlWidth = false; layout.childControlHeight = false; layout.childForceExpandWidth = true; layout.childForceExpandHeight = true; ContentSizeFitter fitter = go.AddComponent(); fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; return go; } GameObject CreateHorizontalLayout2Parent(GameObject parent) { HorizontalLayoutGroup layout = parent.GetComponent(); if (layout == null) layout = parent.AddComponent(); layout.childControlWidth = false; layout.childControlHeight = false; layout.childForceExpandWidth = true; layout.childForceExpandHeight = true; ContentSizeFitter fitter = parent.GetComponent(); if (fitter == null) fitter = parent.AddComponent(); fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; return parent; } void CreateLabel(Transform parent, string text) { GameObject go = new GameObject(text + "_TMP"); go.transform.SetParent(parent, false); TextMeshProUGUI tmp = go.AddComponent(); tmp.font = tmpFont; tmp.text = text; tmp.fontSize = 22; tmp.color = Color.black; ContentSizeFitter fitter = go.AddComponent(); fitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize; fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; } #endregion #region 下拉菜单 void CreateDropdown() { Transform parent = Selection.activeGameObject.transform; CreateHorizontalLayout2Parent(parent.gameObject); CreateLabel(parent, paramName); GameObject dropdownGO = (GameObject)PrefabUtility.InstantiatePrefab(dropdownPrefab, parent); TMP_Dropdown dropdown = dropdownGO.GetComponent(); dropdown.options.Clear(); foreach (var opt in optionContent.Split('-').Where(o => !string.IsNullOrEmpty(o))) { dropdown.options.Add(new TMP_Dropdown.OptionData(opt)); } dropdown.value = 0; dropdown.RefreshShownValue(); LayoutElement le = dropdownGO.GetComponent() ?? dropdownGO.AddComponent(); le.preferredWidth = dropdownWidth; le.preferredHeight = dropdownHeight; } #endregion }