349 lines
11 KiB
C#
349 lines
11 KiB
C#
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<UIParamCreatorWindow>("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<ToggleGroup>();
|
|
|
|
foreach (var opt in optionContent.Split('-').Where(o => !string.IsNullOrEmpty(o)))
|
|
{
|
|
GameObject toggle = InstantiateToggle(singleTogglePrefab, row.transform, opt);
|
|
toggle.GetComponent<Toggle>().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<GridLayoutGroup>();
|
|
grid.cellSize = new Vector2(toggleWidth, toggleHeight);
|
|
grid.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
|
|
grid.constraintCount = 3;
|
|
grid.childAlignment = TextAnchor.UpperLeft;
|
|
|
|
ContentSizeFitter fitter = gridGO.AddComponent<ContentSizeFitter>();
|
|
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<LayoutElement>() ?? input.AddComponent<LayoutElement>();
|
|
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>();
|
|
|
|
slider.minValue = sliderMin;
|
|
slider.maxValue = sliderMax;
|
|
slider.value = sliderMin;
|
|
|
|
LayoutElement le = sliderGO.GetComponent<LayoutElement>() ?? sliderGO.AddComponent<LayoutElement>();
|
|
le.preferredWidth = sliderWidth;
|
|
le.preferredHeight = sliderHeight;
|
|
|
|
// 数值显示
|
|
GameObject valueGO = new GameObject("Value_TMP");
|
|
valueGO.transform.SetParent(parent, false);
|
|
|
|
TextMeshProUGUI valueText = valueGO.AddComponent<TextMeshProUGUI>();
|
|
valueText.font = tmpFont;
|
|
valueText.fontSize = 22;
|
|
valueText.color = Color.black;
|
|
valueText.text = sliderMin.ToString("0");
|
|
|
|
ContentSizeFitter fitter = valueGO.AddComponent<ContentSizeFitter>();
|
|
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<LayoutElement>() ?? go.AddComponent<LayoutElement>();
|
|
le.preferredWidth = toggleWidth;
|
|
le.preferredHeight = toggleHeight;
|
|
|
|
var text = go.GetComponentInChildren<TextMeshProUGUI>();
|
|
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<HorizontalLayoutGroup>();
|
|
layout.childControlWidth = false;
|
|
layout.childControlHeight = false;
|
|
layout.childForceExpandWidth = true;
|
|
layout.childForceExpandHeight = true;
|
|
|
|
ContentSizeFitter fitter = go.AddComponent<ContentSizeFitter>();
|
|
fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
|
|
|
return go;
|
|
}
|
|
|
|
GameObject CreateHorizontalLayout2Parent(GameObject parent)
|
|
{
|
|
HorizontalLayoutGroup layout = parent.GetComponent<HorizontalLayoutGroup>();
|
|
if (layout == null)
|
|
layout = parent.AddComponent<HorizontalLayoutGroup>();
|
|
|
|
layout.childControlWidth = false;
|
|
layout.childControlHeight = false;
|
|
layout.childForceExpandWidth = true;
|
|
layout.childForceExpandHeight = true;
|
|
|
|
ContentSizeFitter fitter = parent.GetComponent<ContentSizeFitter>();
|
|
if (fitter == null)
|
|
fitter = parent.AddComponent<ContentSizeFitter>();
|
|
|
|
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<TextMeshProUGUI>();
|
|
tmp.font = tmpFont;
|
|
tmp.text = text;
|
|
tmp.fontSize = 22;
|
|
tmp.color = Color.black;
|
|
|
|
ContentSizeFitter fitter = go.AddComponent<ContentSizeFitter>();
|
|
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<TMP_Dropdown>();
|
|
|
|
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<LayoutElement>() ?? dropdownGO.AddComponent<LayoutElement>();
|
|
le.preferredWidth = dropdownWidth;
|
|
le.preferredHeight = dropdownHeight;
|
|
}
|
|
|
|
#endregion
|
|
}
|