From 28874ac17d59e4fe7376b0eed75b6961eb9f8553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=80=9D=E6=B5=B7?= <1464576565@qq.com> Date: Fri, 20 Mar 2026 17:22:23 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BB=A7=E6=89=BF=E9=93=BE?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E7=9A=84=E6=97=A0=E6=B3=95=E6=AD=A3=E7=A1=AE?= =?UTF-8?q?=E7=94=9F=E6=88=90ui?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Editor/UI/Helper/UIScriptGeneratorHelper.cs | 79 ++++++++++++++++--- Editor/UI/Res/default.txt | 87 ++++++++++++++++++++- 2 files changed, 153 insertions(+), 13 deletions(-) diff --git a/Editor/UI/Helper/UIScriptGeneratorHelper.cs b/Editor/UI/Helper/UIScriptGeneratorHelper.cs index 6449036..798b927 100644 --- a/Editor/UI/Helper/UIScriptGeneratorHelper.cs +++ b/Editor/UI/Helper/UIScriptGeneratorHelper.cs @@ -119,11 +119,6 @@ namespace AlicizaX.UI.Editor return null; } - if (_componentTypeCache.TryGetValue(uiName, out var componentType)) - { - return componentType; - } - var componentTypeName = UIConfiguration.UIElementRegexConfigs ?.Where(pair => !string.IsNullOrEmpty(pair?.uiElementRegex)) .FirstOrDefault(pair => uiName.StartsWith(pair.uiElementRegex, StringComparison.Ordinal)) @@ -134,9 +129,12 @@ namespace AlicizaX.UI.Editor return null; } - componentType = componentTypeName == nameof(GameObject) - ? typeof(GameObject) - : AlicizaX.Utility.Assembly.GetType(componentTypeName); + if (_componentTypeCache.TryGetValue(componentTypeName, out var componentType)) + { + return componentType; + } + + componentType = ResolveConfiguredComponentType(componentTypeName); if (componentType == null) { @@ -144,10 +142,39 @@ namespace AlicizaX.UI.Editor return null; } - _componentTypeCache[uiName] = componentType; + _componentTypeCache[componentTypeName] = componentType; return componentType; } + private static Type ResolveConfiguredComponentType(string componentTypeName) + { + if (string.IsNullOrWhiteSpace(componentTypeName)) + { + return null; + } + + if (componentTypeName == nameof(GameObject)) + { + return typeof(GameObject); + } + + Type componentType = AlicizaX.Utility.Assembly.GetType(componentTypeName); + if (componentType != null && typeof(Component).IsAssignableFrom(componentType)) + { + return componentType; + } + + return AlicizaX.Utility.Assembly.GetTypes() + .Where(type => type != null && !type.IsAbstract && !type.IsInterface) + .Where(type => typeof(Component).IsAssignableFrom(type)) + .Where(type => string.Equals(type.FullName, componentTypeName, StringComparison.Ordinal) + || string.Equals(type.Name, componentTypeName, StringComparison.Ordinal)) + .OrderBy(type => string.Equals(type.FullName, componentTypeName, StringComparison.Ordinal) ? 0 : 1) + .ThenBy(type => string.Equals(type.Namespace, "UnityEngine.UI", StringComparison.Ordinal) ? 0 : 1) + .ThenBy(type => type.FullName, StringComparer.Ordinal) + .FirstOrDefault(); + } + private static string[] SplitComponentName(string name) { if (string.IsNullOrEmpty(name)) return null; @@ -242,7 +269,7 @@ namespace AlicizaX.UI.Editor continue; } - if (componentType != typeof(GameObject) && node.GetComponent(componentType) == null) + if (componentType != typeof(GameObject) && ResolveAssignableComponent(node.gameObject, componentType) == null) { Debug.LogError($"{node.name} does not have component of type {componentType.FullName}"); continue; @@ -338,7 +365,7 @@ namespace AlicizaX.UI.Editor foreach (var node in orderedNodes) { var isGameObject = componentType == typeof(GameObject); - var component = isGameObject ? null : node.GetComponent(componentType); + var component = isGameObject ? null : ResolveAssignableComponent(node.gameObject, componentType); if (component != null || isGameObject) { @@ -443,6 +470,7 @@ namespace AlicizaX.UI.Editor _uiBindDatas.Clear(); _arrayComponents.Clear(); + _componentTypeCache.Clear(); } private static UIGenerationValidationResult ValidateGeneration(UIGenerationContext context) @@ -578,6 +606,7 @@ namespace AlicizaX.UI.Editor EditorPrefs.DeleteKey(GenerateAssetPathKey); _uiBindDatas.Clear(); _arrayComponents.Clear(); + _componentTypeCache.Clear(); } private static bool BindScriptPropertyField(GameObject targetObject, string scriptTypeName) @@ -711,7 +740,33 @@ namespace AlicizaX.UI.Editor return null; } - return componentType == typeof(GameObject) ? source : source.GetComponent(componentType); + return componentType == typeof(GameObject) ? source : ResolveAssignableComponent(source, componentType); + } + + private static Component ResolveAssignableComponent(GameObject source, Type componentType) + { + if (source == null || componentType == null || !typeof(Component).IsAssignableFrom(componentType)) + { + return null; + } + + Component component = source.GetComponent(componentType); + if (component != null) + { + return component; + } + + Component[] components = source.GetComponents(); + for (int i = 0; i < components.Length; i++) + { + Component candidate = components[i]; + if (candidate != null && componentType.IsInstanceOfType(candidate)) + { + return candidate; + } + } + + return null; } public static class PrefabChecker diff --git a/Editor/UI/Res/default.txt b/Editor/UI/Res/default.txt index a7d6231..152ec99 100644 --- a/Editor/UI/Res/default.txt +++ b/Editor/UI/Res/default.txt @@ -1 +1,86 @@ -[{"uiElementRegex":"Rect","componentType":"RectTransform"},{"uiElementRegex":"Obj","componentType":"GameObject"},{"uiElementRegex":"Tf","componentType":"Transform"},{"uiElementRegex":"Btn","componentType":"UXButton"},{"uiElementRegex":"Slider","componentType":"Slider"},{"uiElementRegex":"Img","componentType":"Image"},{"uiElementRegex":"RImg","componentType":"RawImage"},{"uiElementRegex":"Scrollbar","componentType":"Scrollbar"},{"uiElementRegex":"ScrollRect","componentType":"ScrollRect"},{"uiElementRegex":"GLayout","componentType":"GridLayoutGroup"},{"uiElementRegex":"HLayout","componentType":"HorizontalLayoutGroup"},{"uiElementRegex":"VLayout","componentType":"VerticalLayoutGroup"},{"uiElementRegex":"Text","componentType":"TMPro.TextMeshProUGUI"},{"uiElementRegex":"TogGroup","componentType":"UXGroup"},{"uiElementRegex":"Mask2D","componentType":"RectMask2D"},{"uiElementRegex":"Video","componentType":"Video.VideoPlayer"},{"uiElementRegex":"Input","componentType":"TMPro.TMP_InputField"},{"uiElementRegex":"CanvasGroup","componentType":"CanvasGroup"},{"uiElementRegex":"ScrollView","componentType":"RecyclerView"},{"uiElementRegex":"Drag","componentType":"UXDraggable"}] \ No newline at end of file +[ + { + "uiElementRegex": "Rect", + "componentType": "UnityEngine.RectTransform" + }, + { + "uiElementRegex": "Obj", + "componentType": "GameObject" + }, + { + "uiElementRegex": "Tf", + "componentType": "UnityEngine.Transform" + }, + { + "uiElementRegex": "Btn", + "componentType": "UnityEngine.UI.UXButton" + }, + { + "uiElementRegex": "Slider", + "componentType": "UnityEngine.UI.Slider" + }, + { + "uiElementRegex": "Img", + "componentType": "UnityEngine.UI.Image" + }, + { + "uiElementRegex": "RImg", + "componentType": "UnityEngine.UI.RawImage" + }, + { + "uiElementRegex": "Scrollbar", + "componentType": "UnityEngine.UI.Scrollbar" + }, + { + "uiElementRegex": "ScrollRect", + "componentType": "UnityEngine.UI.ScrollRect" + }, + { + "uiElementRegex": "GLayout", + "componentType": "UnityEngine.UI.GridLayoutGroup" + }, + { + "uiElementRegex": "HLayout", + "componentType": "UnityEngine.UI.HorizontalLayoutGroup" + }, + { + "uiElementRegex": "VLayout", + "componentType": "UnityEngine.UI.VerticalLayoutGroup" + }, + { + "uiElementRegex": "Text", + "componentType": "TMPro.TextMeshProUGUI" + }, + { + "uiElementRegex": "TogGroup", + "componentType": "UnityEngine.UI.UXGroup" + }, + { + "uiElementRegex": "Mask2D", + "componentType": "UnityEngine.UI.RectMask2D" + }, + { + "uiElementRegex": "Video", + "componentType": "UnityEngine.Video.VideoPlayer" + }, + { + "uiElementRegex": "Input", + "componentType": "TMPro.TMP_InputField" + }, + { + "uiElementRegex": "CanvasGroup", + "componentType": "UnityEngine.CanvasGroup" + }, + { + "uiElementRegex": "ScrollView", + "componentType": "AlicizaX.UI.RecyclerView" + }, + { + "uiElementRegex": "Drag", + "componentType": "UnityEngine.UI.UXDraggable" + }, + { + "uiElementRegex": "Img", + "componentType": "UnityEngine.UI.Image" + } +] \ No newline at end of file