using UnityEngine.Events; using UnityEngine.UI; using UnityEngine; using System; using System.Collections.Generic; using TMPro; namespace SceneView { [Serializable] public struct RectTransformConfig { public Vector2 AnchorMin; public Vector2 AnchorMax; public Vector2 AnchoredPosition; public Vector2 SizeDelta; public Vector2 OffsetMin; public Vector2 OffsetMax; public Vector2 Pivot; // 默认配置 public static readonly RectTransformConfig Default = new RectTransformConfig( Vector2.up, // 锚点最小:左上角 (0, 1) Vector2.up, // 锚点最大:左上角 (0, 1) Vector2.zero, Vector2.zero, Vector2.zero, Vector2.zero, new Vector2(0.5f, 0.5f) // 默认居中轴心点 ); // 填充父级的配置 public static readonly RectTransformConfig FillParent = new RectTransformConfig( Vector2.zero, // 锚点最小:左下角 (0, 0) Vector2.one, // 锚点最大:右上角 (1, 1) Vector2.zero, Vector2.zero, // sizeDelta为零表示通过offsetMin/Max来控制尺寸 Vector2.zero, Vector2.zero, new Vector2(0.5f, 0.5f) ); public RectTransformConfig( Vector2 anchorMin, Vector2 anchorMax, Vector2 anchoredPosition, Vector2 sizeDelta, Vector2 offsetMin, Vector2 offsetMax, Vector2 pivot) { AnchorMin = anchorMin; AnchorMax = anchorMax; AnchoredPosition = anchoredPosition; SizeDelta = sizeDelta; OffsetMin = offsetMin; OffsetMax = offsetMax; Pivot = pivot; } } [Serializable] public struct ButtonConfig { public RectTransformConfig RectConfig; public Color BackgroundColor; public string Text; public int FontSize; public Color TextColor; public bool RaycastTarget; public static readonly ButtonConfig Default = new ButtonConfig( RectTransformConfig.Default, new Color(0.2f, 0.2f, 0.2f, 1f), "Button", 18, Color.white, true ); public ButtonConfig( RectTransformConfig rectConfig, Color backgroundColor, string text, int fontSize, Color textColor, bool raycastTarget = true) { RectConfig = rectConfig; BackgroundColor = backgroundColor; Text = text; FontSize = fontSize; TextColor = textColor; RaycastTarget = raycastTarget; } } [Serializable] public struct TextConfig { public RectTransformConfig RectConfig; public string Text; public int FontSize; public Color TextColor; public TextAlignmentOptions Alignment; public bool RaycastTarget; public static readonly TextConfig Default = new TextConfig( rectConfig: RectTransformConfig.Default, text: "New Text", fontSize: 18, textColor: Color.white, alignment: TextAlignmentOptions.Center, raycastTarget: false ); public TextConfig( string text, int fontSize, Color textColor, TextAlignmentOptions alignment, bool raycastTarget, RectTransformConfig rectConfig) { RectConfig = rectConfig; Text = text; FontSize = fontSize; TextColor = textColor; Alignment = alignment; RaycastTarget = raycastTarget; } } [Serializable] public struct ScrollViewConfig { public RectTransformConfig RectConfig; // 新增:ScrollView自身的RectTransform配置 public bool Vertical; public bool Horizontal; public Color BackgroundColor; public Vector2 ContentPadding; // 内容区域的内边距(上下左右) public static readonly ScrollViewConfig Default = new ScrollViewConfig { RectConfig = new RectTransformConfig( new Vector2(0.5f, 0.5f), // 锚点最小:中心 (0.5, 0.5) new Vector2(0.5f, 0.5f), // 锚点最大:中心 (0.5, 0.5) Vector2.zero, new Vector2(400, 300), // 默认尺寸 Vector2.zero, Vector2.zero, new Vector2(0.5f, 0.5f) ), Vertical = true, Horizontal = false, BackgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.8f), ContentPadding = new Vector2(10, 10) // (horizontal, vertical) }; } [Serializable] public struct InputFieldConfig { public RectTransformConfig RectConfig; public Color BackgroundColor; public string PlaceholderText; public int PlaceholderFontSize; public Color PlaceholderTextColor; public Color TextColor; public int FontSize; public TextAlignmentOptions TextAlignment; public TMP_InputField.CharacterValidation CharacterValidation; public int CharacterLimit; public static readonly InputFieldConfig Default = new InputFieldConfig( RectTransformConfig.Default, new Color(0.2f, 0.2f, 0.2f, 1f), "Enter text here", 14, new Color(0.7f, 0.7f, 0.7f, 1f), Color.white, 18, TextAlignmentOptions.Left, TMP_InputField.CharacterValidation.None, 0 ); public InputFieldConfig( RectTransformConfig rectConfig, Color backgroundColor, string placeholderText, int placeholderFontSize, Color placeholderTextColor, Color textColor, int fontSize, TextAlignmentOptions textAlignment, TMP_InputField.CharacterValidation characterValidation = TMP_InputField.CharacterValidation.None, int characterLimit = 0) { RectConfig = rectConfig; BackgroundColor = backgroundColor; PlaceholderText = placeholderText; PlaceholderFontSize = placeholderFontSize; PlaceholderTextColor = placeholderTextColor; TextColor = textColor; FontSize = fontSize; TextAlignment = textAlignment; CharacterValidation = characterValidation; CharacterLimit = characterLimit; } } [Serializable] public struct LabeledInputFieldConfig { public RectTransformConfig RectConfig; // 整个控件(标签+输入框)的配置 public string LabelText; public int LabelFontSize; public Color LabelTextColor; public float LabelWidth; // 标签部分的固定宽度 public float Spacing; // 标签和输入框之间的间距 public InputFieldConfig InputFieldConfig; // 复用已有的输入框配置 public static readonly LabeledInputFieldConfig Default = new LabeledInputFieldConfig { RectConfig = new RectTransformConfig( Vector2.up, // 锚点最小:左上角 (0, 1) Vector2.one, // 锚点最大:右上角 (1, 1),默认水平拉伸 Vector2.zero, new Vector2(0, 30), // 默认高度30 Vector2.zero, Vector2.zero, new Vector2(0.5f, 1) // 轴心点:顶部居中 ), LabelText = "Label", LabelFontSize = 18, LabelTextColor = Color.white, LabelWidth = 100f, Spacing = 10f, InputFieldConfig = InputFieldConfig.Default }; } [Serializable] public struct DropdownConfig { public RectTransformConfig RectConfig; public List Options; public Color BackgroundColor; public int CaptionFontSize; // 下拉框当前选中项的文本大小 public Color CaptionTextColor; public int ItemFontSize; // 下拉列表每一项的文本大小 public Color ItemTextColor; public static readonly DropdownConfig Default = new DropdownConfig( new RectTransformConfig( new Vector2(0.5f, 0.5f), // 锚点最小:中心 (0.5, 0.5) new Vector2(0.5f, 0.5f), // 锚点最大:中心 (0.5, 0.5) Vector2.zero, new Vector2(160, 30), Vector2.zero, Vector2.zero, new Vector2(0.5f, 0.5f) ), new List { "Option A", "Option B", "Option C" }, new Color(0.2f, 0.2f, 0.2f, 1f), 18, Color.white, 16, Color.white ); public DropdownConfig(RectTransformConfig rectConfig, List options, Color backgroundColor, int captionFontSize, Color captionTextColor, int itemFontSize, Color itemTextColor) { RectConfig = rectConfig; Options = options; BackgroundColor = backgroundColor; CaptionFontSize = captionFontSize; CaptionTextColor = captionTextColor; ItemFontSize = itemFontSize; ItemTextColor = itemTextColor; } } [Serializable] public struct LabeledDropdownConfig { public RectTransformConfig RectConfig; public string LabelText; public int LabelFontSize; public Color LabelTextColor; public float LabelWidth; public float Spacing; public DropdownConfig DropdownConfig; public static readonly LabeledDropdownConfig Default = new LabeledDropdownConfig { RectConfig = new RectTransformConfig( Vector2.up, // 锚点最小:左上角 (0, 1) Vector2.one, // 锚点最大:右上角 (1, 1) Vector2.zero, new Vector2(0, 30), Vector2.zero, Vector2.zero, new Vector2(0.5f, 1) ), LabelText = "Label", LabelFontSize = 18, LabelTextColor = Color.white, LabelWidth = 100f, Spacing = 10f, DropdownConfig = DropdownConfig.Default }; } [Serializable] public struct ToggleConfig { public RectTransformConfig RectConfig; public string LabelText; public int LabelFontSize; public Color LabelTextColor; public Color BackgroundColor; public Color CheckmarkColor; public float Spacing; // 开关图形和标签之间的间距 public bool IsOnByDefault; public static readonly ToggleConfig Default = new ToggleConfig { RectConfig = new RectTransformConfig( Vector2.up, // 锚点最小:左上角 (0, 1) Vector2.up, // 锚点最大:左上角 (0, 1) Vector2.zero, new Vector2(160, 20), Vector2.zero, Vector2.zero, new Vector2(0.5f, 0.5f) ), LabelText = "Toggle", LabelFontSize = 18, LabelTextColor = Color.white, BackgroundColor = new Color(0.2f, 0.2f, 0.2f, 1f), CheckmarkColor = new Color(0.1f, 0.6f, 1f, 1f), Spacing = 10f, IsOnByDefault = false }; } public static class ControlUtilities { // 通用方法:将 RectTransformConfig 应用于 RectTransform private static void ApplyRectTransformConfig(RectTransform rectTransform, RectTransformConfig config) { rectTransform.anchorMin = config.AnchorMin; rectTransform.anchorMax = config.AnchorMax; rectTransform.pivot = config.Pivot; // 当sizeDelta为Vector2.zero时,我们假定用户希望通过offsetMin/Max来拉伸元素 // 否则使用anchoredPosition和sizeDelta来定位和设置尺寸 if (config.SizeDelta == Vector2.zero && (config.OffsetMin != Vector2.zero || config.OffsetMax != Vector2.zero || (config.AnchorMin == Vector2.zero && config.AnchorMax == Vector2.one))) { rectTransform.offsetMin = config.OffsetMin; rectTransform.offsetMax = config.OffsetMax; } else { rectTransform.anchoredPosition = config.AnchoredPosition; rectTransform.sizeDelta = config.SizeDelta; } } // ======================== // 矩形对象创建 // ======================== /// /// 创建一个带有 RectTransform 组件的空 GameObject。 /// /// 父级 Transform。 /// GameObject 的名称。 /// RectTransform 的配置。 /// 创建的 RectTransform 组件。 public static RectTransform CreateRect(Transform parent, string name, RectTransformConfig config) { var obj = new GameObject(name); var rect = obj.AddComponent(); rect.SetParent(parent, false); // false表示不保留世界坐标,而是以父级为基准 ApplyRectTransformConfig(rect, config); return rect; } // ======================== // 按钮创建 // ======================== public static (Button? button, TextMeshProUGUI? text) CreateButton(RectTransform? parent, ButtonConfig config, UnityAction? onClick) { // 使用 CreateRect 创建按钮根对象并应用配置 var btnRect = CreateRect(parent, config.Text + "Button", config.RectConfig); var button = btnRect.gameObject.AddComponent