From 0a5ec37d239ccfef1b67fe47ff504dd8d39e4584 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, 17 Apr 2026 11:38:50 +0800 Subject: [PATCH] 1 --- Editor/UI/Helper/UIScriptGeneratorHelper.cs | 124 ++++++++++++++++++-- 1 file changed, 114 insertions(+), 10 deletions(-) diff --git a/Editor/UI/Helper/UIScriptGeneratorHelper.cs b/Editor/UI/Helper/UIScriptGeneratorHelper.cs index ee036c4..5187bec 100644 --- a/Editor/UI/Helper/UIScriptGeneratorHelper.cs +++ b/Editor/UI/Helper/UIScriptGeneratorHelper.cs @@ -27,6 +27,15 @@ namespace AlicizaX.UI.Editor Objs = objs ?? new List(); BindType = bindType; ComponentType = componentType; + ResolvedComponentTypes = new List(); + + if (componentType != null && Objs.Count > 0) + { + for (var i = 0; i < Objs.Count; i++) + { + ResolvedComponentTypes.Add(componentType); + } + } } public UIBindData(string name, GameObject obj, Type componentType = null, EBindType bindType = EBindType.None) @@ -42,6 +51,8 @@ namespace AlicizaX.UI.Editor public Type ComponentType { get; private set; } + public List ResolvedComponentTypes { get; } + public bool IsGameObject => ComponentType == typeof(GameObject); public string TypeName => ComponentType?.FullName ?? string.Empty; @@ -52,6 +63,27 @@ namespace AlicizaX.UI.Editor { ComponentType = componentType; } + + public void AddResolvedObject(GameObject obj, Type componentType) + { + if (obj == null) + { + return; + } + + Objs.Add(obj); + ResolvedComponentTypes.Add(componentType ?? ComponentType); + } + + public Type GetResolvedComponentType(int index) + { + if (index >= 0 && index < ResolvedComponentTypes.Count && ResolvedComponentTypes[index] != null) + { + return ResolvedComponentTypes[index]; + } + + return ComponentType; + } } public static class UIScriptGeneratorHelper @@ -235,6 +267,78 @@ namespace AlicizaX.UI.Editor return comStr.Split(new[] { split }, StringSplitOptions.RemoveEmptyEntries); } + private static bool TryResolveActualComponentType(GameObject source, Type componentType, out Type actualComponentType) + { + actualComponentType = null; + + if (source == null || componentType == null) + { + return false; + } + + if (componentType == typeof(GameObject)) + { + actualComponentType = typeof(GameObject); + return true; + } + + var component = ResolveAssignableComponent(source, componentType); + if (component == null) + { + return false; + } + + actualComponentType = component.GetType(); + return actualComponentType != null; + } + + private static Type ResolveBindComponentType(Type configuredType, IEnumerable actualComponentTypes) + { + if (configuredType == typeof(GameObject)) + { + return typeof(GameObject); + } + + var resolvedTypes = actualComponentTypes? + .Where(type => type != null) + .Distinct() + .ToList(); + + if (resolvedTypes == null || resolvedTypes.Count == 0) + { + return configuredType; + } + + if (resolvedTypes.Count == 1) + { + return resolvedTypes[0]; + } + + return FindCommonComponentBaseType(resolvedTypes) ?? configuredType; + } + + private static Type FindCommonComponentBaseType(IReadOnlyList componentTypes) + { + if (componentTypes == null || componentTypes.Count == 0) + { + return null; + } + + var candidateType = componentTypes[0]; + while (candidateType != null && candidateType != typeof(object)) + { + if (typeof(Component).IsAssignableFrom(candidateType) && + componentTypes.All(type => candidateType.IsAssignableFrom(type))) + { + return candidateType; + } + + candidateType = candidateType.BaseType; + } + + return null; + } + private static void CollectBindData(Transform root) { if (root == null) return; @@ -312,7 +416,7 @@ namespace AlicizaX.UI.Editor continue; } - if (componentType != typeof(GameObject) && ResolveAssignableComponent(node.gameObject, componentType) == null) + if (!TryResolveActualComponentType(node.gameObject, componentType, out var actualComponentType)) { Debug.LogError($"{node.name} does not have component of type {componentType.FullName}"); continue; @@ -325,7 +429,7 @@ namespace AlicizaX.UI.Editor continue; } - _uiBindDatas.Add(new UIBindData(keyName, node.gameObject, componentType)); + _uiBindDatas.Add(new UIBindData(keyName, node.gameObject, actualComponentType)); } } @@ -404,21 +508,21 @@ namespace AlicizaX.UI.Editor var componentType = ResolveUIElementComponentType(com); if (componentType == null) continue; - tempBindDatas[index].SetComponentType(componentType); + foreach (var node in orderedNodes) { - var isGameObject = componentType == typeof(GameObject); - var component = isGameObject ? null : ResolveAssignableComponent(node.gameObject, componentType); - - if (component != null || isGameObject) + if (TryResolveActualComponentType(node.gameObject, componentType, out var actualComponentType)) { - tempBindDatas[index].Objs.Add(node.gameObject); + tempBindDatas[index].AddResolvedObject(node.gameObject, actualComponentType); } else { Debug.LogError($"{node.name} does not have component of type {componentType.FullName}"); } } + + tempBindDatas[index].SetComponentType( + ResolveBindComponentType(componentType, tempBindDatas[index].ResolvedComponentTypes)); } } @@ -787,7 +891,7 @@ namespace AlicizaX.UI.Editor { if (components[i] == null) continue; - var componentObject = ResolveBoundObject(components[i], bindData.ComponentType); + var componentObject = ResolveBoundObject(components[i], bindData.GetResolvedComponentType(i)); if (componentObject != null && elementType.IsInstanceOfType(componentObject)) { @@ -811,7 +915,7 @@ namespace AlicizaX.UI.Editor return false; } - var firstComponent = ResolveBoundObject(bindData.Objs[0], bindData.ComponentType); + var firstComponent = ResolveBoundObject(bindData.Objs[0], bindData.GetResolvedComponentType(0)); if (firstComponent == null) { return false;