修复继承链导致的无法正确生成ui

This commit is contained in:
陈思海 2026-03-20 17:22:23 +08:00
parent 4c86d6bbda
commit 28874ac17d
2 changed files with 153 additions and 13 deletions

View File

@ -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<Component>();
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

View File

@ -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"}]
[
{
"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"
}
]