This commit is contained in:
陈思海 2026-04-17 11:38:50 +08:00
parent a597e1fd83
commit 0a5ec37d23

View File

@ -27,6 +27,15 @@ namespace AlicizaX.UI.Editor
Objs = objs ?? new List<GameObject>(); Objs = objs ?? new List<GameObject>();
BindType = bindType; BindType = bindType;
ComponentType = componentType; ComponentType = componentType;
ResolvedComponentTypes = new List<Type>();
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) 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 Type ComponentType { get; private set; }
public List<Type> ResolvedComponentTypes { get; }
public bool IsGameObject => ComponentType == typeof(GameObject); public bool IsGameObject => ComponentType == typeof(GameObject);
public string TypeName => ComponentType?.FullName ?? string.Empty; public string TypeName => ComponentType?.FullName ?? string.Empty;
@ -52,6 +63,27 @@ namespace AlicizaX.UI.Editor
{ {
ComponentType = componentType; 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 public static class UIScriptGeneratorHelper
@ -235,6 +267,78 @@ namespace AlicizaX.UI.Editor
return comStr.Split(new[] { split }, StringSplitOptions.RemoveEmptyEntries); 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<Type> 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<Type> 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) private static void CollectBindData(Transform root)
{ {
if (root == null) return; if (root == null) return;
@ -312,7 +416,7 @@ namespace AlicizaX.UI.Editor
continue; 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}"); Debug.LogError($"{node.name} does not have component of type {componentType.FullName}");
continue; continue;
@ -325,7 +429,7 @@ namespace AlicizaX.UI.Editor
continue; 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); var componentType = ResolveUIElementComponentType(com);
if (componentType == null) continue; if (componentType == null) continue;
tempBindDatas[index].SetComponentType(componentType);
foreach (var node in orderedNodes) foreach (var node in orderedNodes)
{ {
var isGameObject = componentType == typeof(GameObject); if (TryResolveActualComponentType(node.gameObject, componentType, out var actualComponentType))
var component = isGameObject ? null : ResolveAssignableComponent(node.gameObject, componentType);
if (component != null || isGameObject)
{ {
tempBindDatas[index].Objs.Add(node.gameObject); tempBindDatas[index].AddResolvedObject(node.gameObject, actualComponentType);
} }
else else
{ {
Debug.LogError($"{node.name} does not have component of type {componentType.FullName}"); 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; 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)) if (componentObject != null && elementType.IsInstanceOfType(componentObject))
{ {
@ -811,7 +915,7 @@ namespace AlicizaX.UI.Editor
return false; return false;
} }
var firstComponent = ResolveBoundObject(bindData.Objs[0], bindData.ComponentType); var firstComponent = ResolveBoundObject(bindData.Objs[0], bindData.GetResolvedComponentType(0));
if (firstComponent == null) if (firstComponent == null)
{ {
return false; return false;