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