增加UI绑定对GameObject的支持 单个以及数组组件
This commit is contained in:
parent
958364080f
commit
33922c9521
@ -181,8 +181,8 @@ namespace AlicizaX.UI.Editor
|
||||
}
|
||||
|
||||
uiBindDatas?
|
||||
.Where(bindData => bindData?.BindCom?.FirstOrDefault() != null)
|
||||
.Select(bindData => bindData.BindCom[0].GetType().Namespace)
|
||||
.Where(bindData => bindData?.Objs?.FirstOrDefault() != null)
|
||||
.Select(bindData => bindData.GetFirstOrDefaultType().Namespace)
|
||||
.Where(ns => !string.IsNullOrEmpty(ns))
|
||||
.ToList()
|
||||
.ForEach(ns => namespaceSet.Add(ns));
|
||||
@ -207,7 +207,7 @@ namespace AlicizaX.UI.Editor
|
||||
{
|
||||
var variableName = bindData.Name;
|
||||
var publicName = GetPublicComponentByNameRule(variableName);
|
||||
var firstType = bindData.BindCom?.FirstOrDefault()?.GetType();
|
||||
var firstType = bindData.GetFirstOrDefaultType();
|
||||
var typeName = firstType?.Name ?? "Component";
|
||||
|
||||
var declaration = new StringBuilder();
|
||||
@ -222,7 +222,7 @@ namespace AlicizaX.UI.Editor
|
||||
break;
|
||||
|
||||
case EBindType.ListCom:
|
||||
var count = Math.Max(0, bindData.BindCom?.Count ?? 0);
|
||||
var count = Math.Max(0, bindData.Objs?.Count ?? 0);
|
||||
declaration.AppendLine($"\t\tprivate {typeName}[] {variableName} = new {typeName}[{count}];");
|
||||
declaration.Append($"\t\tpublic {typeName}[] {publicName} => {variableName};");
|
||||
break;
|
||||
|
||||
@ -22,18 +22,33 @@ namespace AlicizaX.UI.Editor
|
||||
public class UIBindData
|
||||
{
|
||||
public string Name { get; }
|
||||
public List<Component> BindCom { get; }
|
||||
public EBindType BindType { get; }
|
||||
|
||||
public UIBindData(string name, List<Component> bindCom, EBindType bindType = EBindType.None)
|
||||
public List<GameObject> Objs { get; set; }
|
||||
public EBindType BindType { get; }
|
||||
public bool IsGameObject => nameof(GameObject).Equals(TypeName);
|
||||
|
||||
public string TypeName = string.Empty;
|
||||
|
||||
public Type GetFirstOrDefaultType()
|
||||
{
|
||||
Name = name ?? throw new ArgumentNullException(nameof(name));
|
||||
BindCom = bindCom ?? new List<Component>();
|
||||
BindType = bindType;
|
||||
if (IsGameObject)
|
||||
{
|
||||
return typeof(GameObject);
|
||||
}
|
||||
|
||||
return Objs.FirstOrDefault()?.GetComponent(TypeName).GetType();
|
||||
}
|
||||
|
||||
public UIBindData(string name, Component bindCom, EBindType bindType = EBindType.None)
|
||||
: this(name, new List<Component> { bindCom }, bindType)
|
||||
public UIBindData(string name, List<GameObject> objs, string typeName = "", EBindType bindType = EBindType.None)
|
||||
{
|
||||
Name = name;
|
||||
Objs = objs ?? new List<GameObject>();
|
||||
BindType = bindType;
|
||||
TypeName = typeName;
|
||||
}
|
||||
|
||||
public UIBindData(string name, GameObject obj, string typeName = "", EBindType bindType = EBindType.None)
|
||||
: this(name, new List<GameObject> { obj }, typeName, bindType)
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -176,11 +191,16 @@ namespace AlicizaX.UI.Editor
|
||||
var typeName = GetUIElementComponentType(com);
|
||||
if (string.IsNullOrEmpty(typeName)) continue;
|
||||
|
||||
var component = node.GetComponent(typeName);
|
||||
if (component == null)
|
||||
|
||||
bool isGameObject = typeName.Equals(nameof(GameObject));
|
||||
if (!isGameObject)
|
||||
{
|
||||
Debug.LogError($"{node.name} does not have component of type {typeName}");
|
||||
continue;
|
||||
var component = node.GetComponent(typeName);
|
||||
if (component == null)
|
||||
{
|
||||
Debug.LogError($"{node.name} does not have component of type {typeName}");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
var keyName = UIGeneratorRuleHelper.GetPrivateComponentByNameRule(com, node.name, EBindType.None);
|
||||
@ -190,7 +210,7 @@ namespace AlicizaX.UI.Editor
|
||||
continue;
|
||||
}
|
||||
|
||||
_uiBindDatas.Add(new UIBindData(keyName, component));
|
||||
_uiBindDatas.Add(new UIBindData(keyName, node.gameObject, typeName));
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,7 +240,7 @@ namespace AlicizaX.UI.Editor
|
||||
return;
|
||||
}
|
||||
|
||||
_uiBindDatas.Add(new UIBindData(keyName, component, EBindType.Widget));
|
||||
_uiBindDatas.Add(new UIBindData(keyName, component.gameObject, component.name, EBindType.Widget));
|
||||
}
|
||||
|
||||
private static void CollectArrayComponent(List<Transform> arrayNode, string nodeName)
|
||||
@ -256,7 +276,7 @@ namespace AlicizaX.UI.Editor
|
||||
return componentArray.Select((com, index) =>
|
||||
{
|
||||
var keyName = UIGeneratorRuleHelper.GetPrivateComponentByNameRule(com, nodeName, EBindType.ListCom);
|
||||
return new UIBindData(keyName, new List<Component>(), EBindType.ListCom);
|
||||
return new UIBindData(keyName, new List<GameObject>(), com, EBindType.ListCom);
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
@ -269,13 +289,15 @@ namespace AlicizaX.UI.Editor
|
||||
|
||||
var typeName = GetUIElementComponentType(com);
|
||||
if (string.IsNullOrEmpty(typeName)) continue;
|
||||
|
||||
tempBindDatas[index].TypeName = typeName;
|
||||
foreach (var node in orderedNodes)
|
||||
{
|
||||
var component = node.GetComponent(typeName);
|
||||
if (component != null)
|
||||
var isGameObject = typeName.Equals(nameof(GameObject));
|
||||
var component = isGameObject ? null : node.GetComponent(typeName);
|
||||
|
||||
if (component != null || isGameObject)
|
||||
{
|
||||
tempBindDatas[index].BindCom.Add(component);
|
||||
tempBindDatas[index].Objs.Add(node.gameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -396,8 +418,8 @@ namespace AlicizaX.UI.Editor
|
||||
return;
|
||||
}
|
||||
|
||||
var component = targetObject.GetOrAddComponent(scriptType);
|
||||
BindFieldsToComponents(component, scriptType);
|
||||
var targetHolder = targetObject.GetOrAddComponent(scriptType);
|
||||
BindFieldsToComponents(targetHolder, scriptType);
|
||||
}
|
||||
|
||||
private static Type FindScriptType(string scriptClassName)
|
||||
@ -410,36 +432,37 @@ namespace AlicizaX.UI.Editor
|
||||
type.Name.Equals(scriptClassName, StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
private static void BindFieldsToComponents(Component component, Type scriptType)
|
||||
private static void BindFieldsToComponents(Component targetHolder, Type scriptType)
|
||||
{
|
||||
var fields = scriptType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
foreach (var field in fields.Where(field => !string.IsNullOrEmpty(field.Name)))
|
||||
{
|
||||
var components = _uiBindDatas.Find(data => data.Name == field.Name)?.BindCom;
|
||||
var bindData = _uiBindDatas.Find(data => data.Name == field.Name);
|
||||
var components = bindData.Objs;
|
||||
if (components == null)
|
||||
{
|
||||
Debug.LogError($"Field {field.Name} did not find matching component binding");
|
||||
continue;
|
||||
}
|
||||
|
||||
SetFieldValue(field, components, component);
|
||||
SetFieldValue(field, components, bindData.TypeName, targetHolder);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetFieldValue(FieldInfo field, IReadOnlyList<Component> components, Component targetComponent)
|
||||
private static void SetFieldValue(FieldInfo field, IReadOnlyList<GameObject> components, string typeName, Component targetComponent)
|
||||
{
|
||||
if (field.FieldType.IsArray)
|
||||
{
|
||||
SetArrayFieldValue(field, components, targetComponent);
|
||||
SetArrayFieldValue(field, components, typeName, targetComponent);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetSingleFieldValue(field, components, targetComponent);
|
||||
SetSingleFieldValue(field, components, typeName, targetComponent);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetArrayFieldValue(FieldInfo field, IReadOnlyList<Component> components, Component targetComponent)
|
||||
private static void SetArrayFieldValue(FieldInfo field, IReadOnlyList<GameObject> components, string typeName, Component targetComponent)
|
||||
{
|
||||
var elementType = field.FieldType.GetElementType();
|
||||
if (elementType == null)
|
||||
@ -453,9 +476,12 @@ namespace AlicizaX.UI.Editor
|
||||
{
|
||||
if (components[i] == null) continue;
|
||||
|
||||
if (elementType.IsInstanceOfType(components[i]))
|
||||
var isGameobject = typeName.Equals(nameof(GameObject));
|
||||
object ComponentObject = isGameobject ? components[i] : components[i].GetComponent(typeName);
|
||||
|
||||
if (elementType.IsInstanceOfType(ComponentObject))
|
||||
{
|
||||
array.SetValue(components[i], i);
|
||||
array.SetValue(ComponentObject, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -466,11 +492,12 @@ namespace AlicizaX.UI.Editor
|
||||
field.SetValue(targetComponent, array);
|
||||
}
|
||||
|
||||
private static void SetSingleFieldValue(FieldInfo field, IReadOnlyList<Component> components, Component targetComponent)
|
||||
private static void SetSingleFieldValue(FieldInfo field, IReadOnlyList<GameObject> components, string typeName, Component targetComponent)
|
||||
{
|
||||
if (components.Count == 0) return;
|
||||
|
||||
var firstComponent = components[0];
|
||||
var isGameobject = typeName.Equals(nameof(GameObject));
|
||||
object firstComponent = isGameobject ? components[0] : components[0].GetComponent(typeName);
|
||||
if (firstComponent == null) return;
|
||||
|
||||
if (field.FieldType.IsInstanceOfType(firstComponent))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user