优化反射绑定
This commit is contained in:
@@ -135,13 +135,13 @@ namespace XericUI.Core.Base
|
||||
_graphicRaycaster = null;
|
||||
_hierarchyDirty = true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 复位层级脏
|
||||
/// </summary>
|
||||
public void ResetHierarchyDirty()
|
||||
{
|
||||
_hierarchyDirty = false;
|
||||
_hierarchyDirty = false;
|
||||
rectTransform.SetLayoutDirty();
|
||||
}
|
||||
|
||||
@@ -241,21 +241,30 @@ namespace XericUI.Core.Base
|
||||
{
|
||||
var rt = rectTransform;
|
||||
if (rt == null || target == null) return;
|
||||
var parentRT = rt.parent as RectTransform;
|
||||
if (parentRT == null) return;
|
||||
|
||||
Vector3[] corners = new Vector3[4];
|
||||
target.GetWorldCorners(corners);
|
||||
// corners[0]=左下, corners[1]=左上, corners[2]=右上, corners[3]=右下
|
||||
Vector3 worldPos = Vector3.Lerp(
|
||||
Vector3.Lerp(corners[0], corners[1], anchor.y),
|
||||
Vector3.Lerp(corners[3], corners[2], anchor.y),
|
||||
anchor.x);
|
||||
|
||||
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(
|
||||
parentRT, worldPos, null, out Vector2 localPoint))
|
||||
if (rt.parent == target.parent)
|
||||
{
|
||||
rt.anchoredPosition = localPoint;
|
||||
rt.anchorMin = anchor;
|
||||
rt.anchorMax = anchor;
|
||||
rt.pivot = anchor;
|
||||
rt.anchoredPosition = Vector2.zero;
|
||||
return;
|
||||
}
|
||||
|
||||
var targetWorldPos = target.TransformPoint(new Vector3(anchor.x, anchor.y, 0));
|
||||
|
||||
// RectTransformUtility 会自动处理父级不一致的情况
|
||||
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(
|
||||
rt.parent as RectTransform,
|
||||
targetWorldPos,
|
||||
null,
|
||||
out Vector2 anchorLocalPos))
|
||||
{
|
||||
Vector2 pivotOffset = new Vector2(
|
||||
(rt.pivot.x - 0.5f) * rt.rect.width,
|
||||
(rt.pivot.y - 0.5f) * rt.rect.height
|
||||
);
|
||||
rt.anchoredPosition = anchorLocalPos + pivotOffset;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,9 +274,9 @@ namespace XericUI.Core.Base
|
||||
|
||||
public virtual void Show()
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
|
||||
public void Show(bool isShow)
|
||||
{
|
||||
if (isShow)
|
||||
|
||||
+16
-18
@@ -4,12 +4,21 @@ namespace XericUI.ReflectionUIGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// 字段编组特性
|
||||
/// 将多个字段标记为属于同一个 Entry,共享一个 UI 组件实例
|
||||
/// 将多个字段标记为属于同一个编组路径,共享一个 UI 组件实例
|
||||
///
|
||||
/// 编组不携带 Tag,Tag 由 [XuiavrgFieldTag] 单独标记。
|
||||
/// 使用示例:
|
||||
/// [XuiavrgFieldEntryGroup("field1", XuiavrgFieldTag.Label)] public string fieldLabel = "速度";
|
||||
/// [XuiavrgFieldEntryGroup("field1", XuiavrgFieldTag.Context)] public float fieldValue = 0.1f;
|
||||
/// [XuiavrgFieldEntryGroup("field1", XuiavrgFieldTag.Unit)] public string fieldUnit = "m/s";
|
||||
/// [XuiavrgFieldEntryGroup("field1")]
|
||||
/// [XuiavrgFieldTag(XuiavrgFieldTag.Label)]
|
||||
/// public string fieldLabel = "速度";
|
||||
///
|
||||
/// [XuiavrgFieldEntryGroup("field1")]
|
||||
/// [XuiavrgFieldTag(XuiavrgFieldTag.Context)]
|
||||
/// public float fieldValue = 0.1f;
|
||||
///
|
||||
/// [XuiavrgFieldEntryGroup("field1")]
|
||||
/// [XuiavrgFieldTag(XuiavrgFieldTag.Unit)]
|
||||
/// public string fieldUnit = "m/s";
|
||||
///
|
||||
/// 上述三个字段将合并为一个 Entry,分别绑定到 UI 组件上 Label、Context、Unit 三个子元素
|
||||
/// </summary>
|
||||
@@ -18,31 +27,20 @@ namespace XericUI.ReflectionUIGenerator
|
||||
{
|
||||
/// <summary>编组路径,以 "/" 分割层级。同一 groupPath 的字段合并到一个 Entry</summary>
|
||||
public readonly string GroupPath;
|
||||
|
||||
/// <summary>该字段在编组 Entry 中的功能标记</summary>
|
||||
public readonly XuiavrgFieldTag Tag;
|
||||
|
||||
/// <summary>同一 Tag 存在多个时的索引区分</summary>
|
||||
public readonly int TagIndex;
|
||||
|
||||
/// <summary>
|
||||
/// 创建字段编组标记
|
||||
/// </summary>
|
||||
/// <param name="groupPath">编组路径 (如 "field1" 或 "field1/child")</param>
|
||||
/// <param name="tag">功能标记</param>
|
||||
/// <param name="tagIndex">标记索引 (同一 Tag 存在多个时区分)</param>
|
||||
public XuiavrgFieldEntryGroupAttribute(string groupPath, XuiavrgFieldTag tag, int tagIndex = 0)
|
||||
/// <param name="groupPath">编组路径 (如 "field1" 或 "Stats/Speed")</param>
|
||||
public XuiavrgFieldEntryGroupAttribute(string groupPath)
|
||||
{
|
||||
GroupPath = groupPath;
|
||||
Tag = tag;
|
||||
TagIndex = tagIndex;
|
||||
}
|
||||
|
||||
public void BindMetaData(AvrgMemberMetaData metaData)
|
||||
{
|
||||
metaData.GroupPath = GroupPath;
|
||||
metaData.Tag = Tag;
|
||||
metaData.TagIndex = TagIndex;
|
||||
// 不设置 Tag/TagIndex,留给 [XuiavrgFieldTag] 单独处理
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ namespace XericUI.ReflectionUIGenerator
|
||||
/// Manager 在 GenerateUI 阶段会优先使用此名称查找 PropertyGroup
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
|
||||
public class XuiavrgFieldPrefabOverrideAttribute : Attribute, IXuiavrgAttribute
|
||||
public class XuiavrgFieldNameAttribute : Attribute, IXuiavrgAttribute
|
||||
{
|
||||
/// <summary>覆盖的预制体组名称</summary>
|
||||
public readonly string PrefabGroupName;
|
||||
@@ -23,7 +23,7 @@ namespace XericUI.ReflectionUIGenerator
|
||||
/// <param name="prefabGroupName">
|
||||
/// 目标预制体名称,在 AvrgTypePrefabMappingConfig 中查找匹配
|
||||
/// </param>
|
||||
public XuiavrgFieldPrefabOverrideAttribute(string prefabGroupName)
|
||||
public XuiavrgFieldNameAttribute(string prefabGroupName)
|
||||
{
|
||||
PrefabGroupName = prefabGroupName;
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
|
||||
namespace XericUI.ReflectionUIGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// 字段功能标记特性
|
||||
/// 单独设置字段的功能标记,与编组分离
|
||||
///
|
||||
/// 使用示例:
|
||||
/// [XuiavrgFieldEntryGroup("field1")]
|
||||
/// [XuiavrgFieldTag(XuiavrgFieldTag.Label)]
|
||||
/// public string fieldLabel = "速度";
|
||||
///
|
||||
/// [XuiavrgFieldEntryGroup("field1")]
|
||||
/// [XuiavrgFieldTag(XuiavrgFieldTag.Context)]
|
||||
/// public float fieldValue = 0.1f;
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
|
||||
public class XuiavrgFieldTagAttribute : Attribute, IXuiavrgAttribute
|
||||
{
|
||||
/// <summary>功能标记</summary>
|
||||
public readonly XuiavrgFieldTag Tag;
|
||||
|
||||
/// <summary>同一 Tag 存在多个时的索引区分</summary>
|
||||
public readonly int TagIndex;
|
||||
|
||||
/// <summary>
|
||||
/// 创建字段功能标记
|
||||
/// </summary>
|
||||
/// <param name="tag">功能标记</param>
|
||||
/// <param name="tagIndex">标记索引(同一 Tag 存在多个时区分)</param>
|
||||
public XuiavrgFieldTagAttribute(XuiavrgFieldTag tag, int tagIndex = 0)
|
||||
{
|
||||
Tag = tag;
|
||||
TagIndex = tagIndex;
|
||||
}
|
||||
|
||||
public void BindMetaData(AvrgMemberMetaData metaData)
|
||||
{
|
||||
metaData.Tag = Tag;
|
||||
metaData.TagIndex = TagIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -85,23 +85,6 @@ namespace XericUI.ReflectionUIGenerator
|
||||
/// <summary>是否启用无效值状态检查</summary>
|
||||
public bool ValidateInvalid { get; set; }
|
||||
|
||||
// ============ (已弃用字段保留) 旧的验证约束 ============
|
||||
|
||||
/// <summary>字符串最小长度</summary>
|
||||
[Obsolete("将移至 ValueRangeConfig 管理")]
|
||||
public int StringMinLength { get; set; }
|
||||
|
||||
/// <summary>字符串最大长度</summary>
|
||||
public int StringMaxLength { get; set; } = int.MaxValue;
|
||||
|
||||
/// <summary>数值最小值</summary>
|
||||
[Obsolete("将移至 ValueRangeConfig 管理")]
|
||||
public float NumberMinValue { get; set; }
|
||||
|
||||
/// <summary>数值最大值</summary>
|
||||
[Obsolete("将移至 ValueRangeConfig 管理")]
|
||||
public float NumberMaxValue { get; set; }
|
||||
|
||||
// ============ 原始 Attribute 引用 ============
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -7,8 +7,8 @@ using Object = UnityEngine.Object;
|
||||
namespace XericUI.ReflectionUIGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// 节点下生成反射属性管理器 — Metadata-Driven View Model (MDVM 元数据驱动的视图数据模型)
|
||||
/// 负责:构建 Entry → 创建组容器 → 生成 UI → 绑定数据
|
||||
/// 节点下生成反射属性管理器 — MVM (Metadata-Driven View Model)
|
||||
/// 负责:构建 Entry → 创建组容器(树状嵌套)→ 生成 UI → 绑定数据
|
||||
/// </summary>
|
||||
public class XuiavrgInspectorManager : MonoBehaviour
|
||||
{
|
||||
@@ -75,9 +75,9 @@ namespace XericUI.ReflectionUIGenerator
|
||||
public AvrgMemberMetaDataSet CurrentMetaDataSet { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前活跃的组容器字典
|
||||
/// 编组叶节点字典 — 完整 GroupPath → 对应层级的 XuiAvrgMDGroup
|
||||
/// </summary>
|
||||
private Dictionary<string, XuiAvrgMDGroup> _activeGroups = new Dictionary<string, XuiAvrgMDGroup>();
|
||||
private Dictionary<string, XuiAvrgMDGroup> _leafGroupMap = new Dictionary<string, XuiAvrgMDGroup>();
|
||||
|
||||
[Tooltip("类型-预制体映射配置 ScriptableObject")]
|
||||
public AvrgTypePrefabMappingConfig typePrefabMappingConfig;
|
||||
@@ -170,13 +170,14 @@ namespace XericUI.ReflectionUIGenerator
|
||||
});
|
||||
}
|
||||
|
||||
// ============ 三阶段 GenerateUI ============
|
||||
// ============ 四阶段 GenerateUI ============
|
||||
|
||||
/// <summary>
|
||||
/// 生成 UI — 三阶段流程
|
||||
/// 生成 UI — 四阶段流程
|
||||
/// Phase A: 按 GroupPath 分组
|
||||
/// Phase B: 创建 XuiAvrgMDGroup 组容器
|
||||
/// Phase C: 在组容器内生成 UI 组件并绑定
|
||||
/// Phase B: 构建路径树,创建嵌套的 XuiAvrgMDGroup 容器
|
||||
/// Phase C: 在叶节点容器内生成 UI 组件并绑定
|
||||
/// Phase D: 处理非编组 Entry 直接放进根目录
|
||||
/// </summary>
|
||||
public void GenerateUI()
|
||||
{
|
||||
@@ -186,21 +187,19 @@ namespace XericUI.ReflectionUIGenerator
|
||||
return;
|
||||
}
|
||||
|
||||
// Phase A: 收集并分组
|
||||
// Phase A: 按完整 GroupPath 分组
|
||||
var groupedEntries = new Dictionary<string, List<IFieldEntry>>();
|
||||
var ungroupedEntries = new List<IFieldEntry>();
|
||||
|
||||
foreach (var entry in CurrentEntries)
|
||||
{
|
||||
string groupKey = !string.IsNullOrEmpty(entry.EntryName)
|
||||
? GetGroupPathFromEntry(entry)
|
||||
: null;
|
||||
string groupPath = GetGroupPathFromEntry(entry);
|
||||
|
||||
if (!string.IsNullOrEmpty(groupKey))
|
||||
if (!string.IsNullOrEmpty(groupPath))
|
||||
{
|
||||
if (!groupedEntries.ContainsKey(groupKey))
|
||||
groupedEntries[groupKey] = new List<IFieldEntry>();
|
||||
groupedEntries[groupKey].Add(entry);
|
||||
if (!groupedEntries.ContainsKey(groupPath))
|
||||
groupedEntries[groupPath] = new List<IFieldEntry>();
|
||||
groupedEntries[groupPath].Add(entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -208,18 +207,75 @@ namespace XericUI.ReflectionUIGenerator
|
||||
}
|
||||
}
|
||||
|
||||
// Phase B: 创建组容器
|
||||
_activeGroups.Clear();
|
||||
// Phase B: 构建树状嵌套组容器
|
||||
_leafGroupMap.Clear();
|
||||
BuildGroupTree(groupedEntries.Keys);
|
||||
|
||||
// Phase C: 在叶节点容器内生成 UI
|
||||
foreach (var kvp in groupedEntries)
|
||||
{
|
||||
string groupPath = kvp.Key;
|
||||
var entries = kvp.Value;
|
||||
|
||||
// 检查是否已创建(相同 GroupPath 只创建一个容器)
|
||||
if (_activeGroups.ContainsKey(groupPath)) continue;
|
||||
if (!_leafGroupMap.TryGetValue(groupPath, out var leafGroup)) continue;
|
||||
|
||||
var groupGo = new GameObject($"Group [{groupPath}]", typeof(RectTransform));
|
||||
groupGo.transform.SetParent(transform, false);
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
GenerateSingleUI(entry, leafGroup.contentRoot);
|
||||
}
|
||||
}
|
||||
|
||||
// Phase D: 非编组 Entry 直接放进根
|
||||
foreach (var entry in ungroupedEntries)
|
||||
{
|
||||
GenerateSingleUI(entry, transform);
|
||||
}
|
||||
}
|
||||
|
||||
// ============ 树状编组容器构建 ============
|
||||
|
||||
private void BuildGroupTree(IEnumerable<string> allGroupPaths)
|
||||
{
|
||||
var rootNode = new GroupTreeNode(null);
|
||||
|
||||
// Step 1: 将每个完整路径分裂后插入树
|
||||
foreach (var fullPath in allGroupPaths)
|
||||
{
|
||||
if (string.IsNullOrEmpty(fullPath)) continue;
|
||||
|
||||
var segments = fullPath.Split('/');
|
||||
var current = rootNode;
|
||||
|
||||
for (int i = 0; i < segments.Length; i++)
|
||||
{
|
||||
string seg = segments[i];
|
||||
if (!current.Children.ContainsKey(seg))
|
||||
current.Children[seg] = new GroupTreeNode(seg);
|
||||
current = current.Children[seg];
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2: 深度优先遍历,创建层级 GameObject
|
||||
CreateGroupGameObjects(rootNode, null, transform, "");
|
||||
}
|
||||
|
||||
private void CreateGroupGameObjects(
|
||||
GroupTreeNode node,
|
||||
XuiAvrgMDGroup parentGroup,
|
||||
Transform parentTransform,
|
||||
string accumulatedPath)
|
||||
{
|
||||
foreach (var kvp in node.Children)
|
||||
{
|
||||
string segName = kvp.Key;
|
||||
var childNode = kvp.Value;
|
||||
|
||||
string childFullPath = string.IsNullOrEmpty(accumulatedPath)
|
||||
? segName
|
||||
: accumulatedPath + "/" + segName;
|
||||
|
||||
var groupGo = new GameObject($"Group [{childFullPath}]", typeof(RectTransform));
|
||||
groupGo.transform.SetParent(parentTransform, false);
|
||||
|
||||
var rect = groupGo.GetComponent<RectTransform>();
|
||||
rect.anchorMin = new Vector2(0, 1);
|
||||
@@ -228,35 +284,32 @@ namespace XericUI.ReflectionUIGenerator
|
||||
rect.sizeDelta = new Vector2(0, 0);
|
||||
|
||||
var group = groupGo.AddComponent<XuiAvrgMDGroup>();
|
||||
int firstOrder = entries.Count > 0 ? entries[0].FieldOrder : 0;
|
||||
group.Initialize(groupPath, firstOrder);
|
||||
group.Initialize(childFullPath, 0, parentGroup);
|
||||
|
||||
_activeGroups[groupPath] = group;
|
||||
}
|
||||
|
||||
// Phase C: 生成 UI 组件
|
||||
foreach (var kvp in groupedEntries)
|
||||
{
|
||||
string groupPath = kvp.Key;
|
||||
var entries = kvp.Value;
|
||||
|
||||
if (!_activeGroups.TryGetValue(groupPath, out var group)) continue;
|
||||
|
||||
foreach (var entry in entries)
|
||||
// 叶节点映射到完整路径
|
||||
if (childNode.Children.Count == 0)
|
||||
{
|
||||
GenerateSingleUI(entry, group.contentRoot);
|
||||
_leafGroupMap[childFullPath] = group;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var entry in ungroupedEntries)
|
||||
{
|
||||
GenerateSingleUI(entry, transform);
|
||||
CreateGroupGameObjects(childNode, group, group.contentRoot, childFullPath);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成单个 Entry 的 UI
|
||||
/// </summary>
|
||||
private class GroupTreeNode
|
||||
{
|
||||
public string SegmentName { get; }
|
||||
public Dictionary<string, GroupTreeNode> Children { get; }
|
||||
|
||||
public GroupTreeNode(string name)
|
||||
{
|
||||
SegmentName = name;
|
||||
Children = new Dictionary<string, GroupTreeNode>();
|
||||
}
|
||||
}
|
||||
|
||||
// ============ 生成单个 UI ============
|
||||
|
||||
private void GenerateSingleUI(IFieldEntry entry, Transform parent)
|
||||
{
|
||||
if (entry is not XuiFieldTempEntry tempEntry) return;
|
||||
@@ -276,7 +329,6 @@ namespace XericUI.ReflectionUIGenerator
|
||||
uiInstance.name = entry.EntryName;
|
||||
uiInstance.transform.SetParent(parent, false);
|
||||
|
||||
// 检查 XUIAvrgMDValue 是否存在
|
||||
if (uiInstance.GetComponentInChildren<XUIAvrgMDValue>(true) == null)
|
||||
{
|
||||
Debug.LogError($"[Xuiavrg] 预制体 '{prefab.name}' 不符合生成要求:缺少 XUIAvrgMDValue 组件。请确保预制体根节点或其子节点包含 XUIAvrgMDValue 脚本。");
|
||||
@@ -288,12 +340,8 @@ namespace XericUI.ReflectionUIGenerator
|
||||
entry.OnEntryBind();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从 Entry 提取 GroupPath(通过 EntryName 判断)
|
||||
/// </summary>
|
||||
private string GetGroupPathFromEntry(IFieldEntry entry)
|
||||
{
|
||||
// 通过 Bindings 中的元数据找到 GroupPath
|
||||
if (entry.Bindings != null && entry.Bindings.Count > 0)
|
||||
{
|
||||
var metaData = entry.Bindings[0].MetaData;
|
||||
@@ -355,14 +403,14 @@ namespace XericUI.ReflectionUIGenerator
|
||||
|
||||
private void ClearGroups()
|
||||
{
|
||||
foreach (var kvp in _activeGroups)
|
||||
foreach (var kvp in _leafGroupMap)
|
||||
{
|
||||
if (kvp.Value != null && kvp.Value.gameObject != null)
|
||||
{
|
||||
Destroy(kvp.Value.gameObject);
|
||||
}
|
||||
}
|
||||
_activeGroups.Clear();
|
||||
_leafGroupMap.Clear();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
@@ -370,18 +418,5 @@ namespace XericUI.ReflectionUIGenerator
|
||||
ClearAll();
|
||||
}
|
||||
|
||||
// ============ 兼容旧 API ============
|
||||
|
||||
[Obsolete("Use BuildFromMetaDataSet + GenerateUI instead", false)]
|
||||
public void SchemaHydration(object payload)
|
||||
{
|
||||
var metaDataSet = XuiavrgUtilities.ExtractAvrgMemberMetaData(payload);
|
||||
var bindingCollection = metaDataSet.BuildMDVM(payload);
|
||||
BuildFromMetaDataSet(metaDataSet, bindingCollection);
|
||||
GenerateUI();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,30 +21,33 @@ namespace XericUI.ReflectionUIGenerator
|
||||
[Tooltip("编组排序值,越小越靠前")]
|
||||
private int _groupOrder;
|
||||
|
||||
/// <summary>内容挂载点 — 子 UI 组件应放入此 Transform</summary>
|
||||
/// <summary>内容挂载点 — 子 UI 组件或子组应放入此 Transform</summary>
|
||||
public Transform contentRoot;
|
||||
|
||||
/// <summary>父编组(为 null 表示根组,直接挂在 Manager 下)</summary>
|
||||
public XuiAvrgMDGroup ParentGroup { get; private set; }
|
||||
|
||||
/// <summary>编组路径对应的组名</summary>
|
||||
public string GroupName => _groupName;
|
||||
|
||||
/// <summary>编组排序值</summary>
|
||||
public int GroupOrder => _groupOrder;
|
||||
|
||||
/// <summary>上下文层级深度(如 "group1/subgroup" → depth=2)</summary>
|
||||
/// <summary>上下文层级深度(如 "Stats/Speed" → depth=2)</summary>
|
||||
public int ContextDepth { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始化编组容器
|
||||
/// </summary>
|
||||
public void Initialize(string groupPath, int order)
|
||||
public void Initialize(string groupPath, int order, XuiAvrgMDGroup parent = null)
|
||||
{
|
||||
_groupName = groupPath;
|
||||
_groupOrder = order;
|
||||
ParentGroup = parent;
|
||||
ContextDepth = string.IsNullOrEmpty(groupPath) ? 0 : groupPath.Split('/').Length;
|
||||
|
||||
gameObject.name = $"Group [{groupPath}]";
|
||||
|
||||
// 如果没有指定 contentRoot,自动使用自身作为挂载点
|
||||
if (contentRoot == null)
|
||||
contentRoot = transform;
|
||||
}
|
||||
|
||||
@@ -622,6 +622,7 @@ namespace XericUI.XTable.Rendering.Component
|
||||
}
|
||||
|
||||
/// <summary>设置预制体(ContentType 自动设为 Prefab)</summary>
|
||||
/// <remarks>注意是设置预制体而不是实例,设置后订阅单元格预制体生成事件 OnPrefabAcquire 处理获取事件</remarks>
|
||||
public XTableCellData SetCellPrefab(int row, int col, GameObject prefab)
|
||||
{
|
||||
var data = TableData.GetOrCreateCell(row, col);
|
||||
|
||||
Reference in New Issue
Block a user