com.alicizax.unity.framework/Editor/UI/Helper/UIScriptGeneratorHelper.cs

508 lines
20 KiB
C#
Raw Normal View History

2025-09-05 19:46:30 +08:00
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using AlicizaX.UI.Runtime;
using UnityEditor;
using UnityEditor.Callbacks;
2025-11-10 16:01:53 +08:00
using UnityEditor.SceneManagement;
2025-11-13 11:16:31 +08:00
using UnityEngine;
2025-09-05 19:46:30 +08:00
2025-11-07 20:47:57 +08:00
namespace AlicizaX.UI.Editor
{
2025-11-11 10:57:35 +08:00
public enum EBindType
{
None,
Widget,
2025-11-13 11:16:31 +08:00
ListCom
2025-11-11 10:57:35 +08:00
}
2025-09-05 19:46:30 +08:00
[Serializable]
2025-11-13 11:16:31 +08:00
public class UIBindData
2025-09-05 19:46:30 +08:00
{
2025-11-13 11:16:31 +08:00
public string Name { get; }
public List<Component> BindCom { get; }
public EBindType BindType { get; }
2025-09-05 19:46:30 +08:00
public UIBindData(string name, List<Component> bindCom, EBindType bindType = EBindType.None)
{
2025-11-11 10:57:35 +08:00
Name = name ?? throw new ArgumentNullException(nameof(name));
BindCom = bindCom ?? new List<Component>();
2025-09-05 19:46:30 +08:00
BindType = bindType;
}
public UIBindData(string name, Component bindCom, EBindType bindType = EBindType.None)
2025-11-11 10:57:35 +08:00
: this(name, new List<Component> { bindCom }, bindType)
2025-09-05 19:46:30 +08:00
{
}
}
2025-09-10 14:26:54 +08:00
internal static class UIScriptGeneratorHelper
2025-09-05 19:46:30 +08:00
{
private static UIGenerateConfiguration _uiGenerateConfiguration;
2025-11-10 16:01:53 +08:00
private static IUIGeneratorRuleHelper _uiGeneratorRuleHelper;
2025-11-13 11:16:31 +08:00
private static readonly List<UIBindData> _uiBindDatas = new List<UIBindData>();
private static readonly HashSet<string> _arrayComponents = new HashSet<string>(StringComparer.Ordinal);
2025-11-07 20:47:57 +08:00
2025-11-13 11:16:31 +08:00
private static IUIGeneratorRuleHelper UIGeneratorRuleHelper =>
_uiGeneratorRuleHelper ?? InitializeRuleHelper();
2025-11-11 10:57:35 +08:00
2025-11-13 11:16:31 +08:00
private static UIGenerateConfiguration UIConfiguration =>
_uiGenerateConfiguration ??= UIGenerateConfiguration.Instance;
private static IUIGeneratorRuleHelper InitializeRuleHelper()
2025-11-07 20:47:57 +08:00
{
2025-11-13 11:16:31 +08:00
var ruleHelperTypeName = UIConfiguration.UIScriptGeneratorRuleHelper;
if (string.IsNullOrWhiteSpace(ruleHelperTypeName))
2025-11-07 20:47:57 +08:00
{
2025-11-13 11:16:31 +08:00
Debug.LogError("UIScriptGeneratorHelper: UIScriptGeneratorRuleHelper not configured.");
return null;
2025-11-07 20:47:57 +08:00
}
2025-11-13 11:16:31 +08:00
var ruleHelperType = Type.GetType(ruleHelperTypeName);
if (ruleHelperType == null)
2025-09-05 19:46:30 +08:00
{
2025-11-13 11:16:31 +08:00
Debug.LogError($"UIScriptGeneratorHelper: Could not load UI ScriptGeneratorHelper {ruleHelperTypeName}");
return null;
}
2025-09-05 19:46:30 +08:00
2025-11-13 11:16:31 +08:00
_uiGeneratorRuleHelper = Activator.CreateInstance(ruleHelperType) as IUIGeneratorRuleHelper;
if (_uiGeneratorRuleHelper == null)
{
Debug.LogError($"UIScriptGeneratorHelper: Failed to instantiate {ruleHelperTypeName} as IUIGeneratorRuleHelper.");
2025-09-05 19:46:30 +08:00
}
2025-11-13 11:16:31 +08:00
return _uiGeneratorRuleHelper;
2025-09-05 19:46:30 +08:00
}
2025-11-12 17:48:41 +08:00
private static string GetUIElementComponentType(string uiName)
2025-09-05 19:46:30 +08:00
{
2025-11-11 10:57:35 +08:00
if (string.IsNullOrEmpty(uiName)) return string.Empty;
2025-09-05 19:46:30 +08:00
2025-11-13 11:16:31 +08:00
return UIConfiguration.UIElementRegexConfigs
?.Where(pair => !string.IsNullOrEmpty(pair?.uiElementRegex))
.FirstOrDefault(pair => uiName.StartsWith(pair.uiElementRegex, StringComparison.Ordinal))
?.componentType ?? string.Empty;
2025-09-05 19:46:30 +08:00
}
2025-11-07 20:47:57 +08:00
private static string[] SplitComponentName(string name)
2025-09-05 19:46:30 +08:00
{
2025-11-11 10:57:35 +08:00
if (string.IsNullOrEmpty(name)) return null;
var common = UIConfiguration.UIGenerateCommonData;
if (string.IsNullOrEmpty(common?.ComCheckEndName) || !name.Contains(common.ComCheckEndName))
return null;
2025-11-13 11:16:31 +08:00
var endIndex = name.IndexOf(common.ComCheckEndName, StringComparison.Ordinal);
2025-11-11 10:57:35 +08:00
if (endIndex <= 0) return null;
2025-09-05 19:46:30 +08:00
2025-11-13 11:16:31 +08:00
var comStr = name.Substring(0, endIndex);
var split = common.ComCheckSplitName ?? "#";
2025-09-05 19:46:30 +08:00
2025-11-13 11:16:31 +08:00
return comStr.Split(new[] { split }, StringSplitOptions.RemoveEmptyEntries);
2025-09-05 19:46:30 +08:00
}
2025-11-13 11:16:31 +08:00
private static void CollectBindData(Transform root)
2025-09-05 19:46:30 +08:00
{
2025-11-11 10:57:35 +08:00
if (root == null) return;
2025-11-13 11:16:31 +08:00
foreach (Transform child in root.Cast<Transform>().Where(child => child != null))
2025-09-05 19:46:30 +08:00
{
2025-11-13 11:16:31 +08:00
if (ShouldSkipChild(child)) continue;
var hasWidget = child.GetComponent<UIHolderObjectBase>() != null;
var isArrayComponent = IsArrayComponent(child.name);
2025-11-07 20:47:57 +08:00
if (hasWidget)
2025-09-05 19:46:30 +08:00
{
CollectWidget(child);
}
2025-11-07 20:47:57 +08:00
else if (isArrayComponent)
2025-09-05 19:46:30 +08:00
{
2025-11-13 11:16:31 +08:00
ProcessArrayComponent(child, root);
2025-09-05 19:46:30 +08:00
}
2025-11-13 11:16:31 +08:00
else
2025-09-05 19:46:30 +08:00
{
CollectComponent(child);
2025-11-13 11:16:31 +08:00
CollectBindData(child);
2025-09-05 19:46:30 +08:00
}
}
}
2025-11-13 11:16:31 +08:00
private static bool ShouldSkipChild(Transform child)
{
var keywords = UIConfiguration.UIGenerateCommonData.ExcludeKeywords;
return keywords?.Any(k =>
!string.IsNullOrEmpty(k) &&
child.name.IndexOf(k, StringComparison.OrdinalIgnoreCase) >= 0) == true;
}
private static bool IsArrayComponent(string componentName)
{
var splitName = UIConfiguration.UIGenerateCommonData.ArrayComSplitName;
return !string.IsNullOrEmpty(splitName) &&
componentName.StartsWith(splitName, StringComparison.Ordinal);
}
private static void ProcessArrayComponent(Transform child, Transform root)
{
var splitCode = UIConfiguration.UIGenerateCommonData.ArrayComSplitName;
var firstIndex = child.name.IndexOf(splitCode, StringComparison.Ordinal);
var lastIndex = child.name.LastIndexOf(splitCode, StringComparison.Ordinal);
if (firstIndex < 0 || lastIndex <= firstIndex) return;
var text = child.name.Substring(firstIndex + splitCode.Length, lastIndex - (firstIndex + splitCode.Length));
if (string.IsNullOrEmpty(text) || _arrayComponents.Contains(text)) return;
_arrayComponents.Add(text);
var arrayComponents = root.Cast<Transform>()
.Where(sibling => sibling.name.Contains(text, StringComparison.Ordinal))
.ToList();
CollectArrayComponent(arrayComponents, text);
}
2025-09-05 19:46:30 +08:00
private static void CollectComponent(Transform node)
{
2025-11-11 10:57:35 +08:00
if (node == null) return;
2025-11-13 11:16:31 +08:00
var componentArray = SplitComponentName(node.name);
2025-11-11 10:57:35 +08:00
if (componentArray == null || componentArray.Length == 0) return;
2025-09-05 19:46:30 +08:00
2025-11-13 11:16:31 +08:00
foreach (var com in componentArray.Where(com => !string.IsNullOrEmpty(com)))
2025-11-11 10:57:35 +08:00
{
2025-11-13 11:16:31 +08:00
var typeName = GetUIElementComponentType(com);
2025-11-11 10:57:35 +08:00
if (string.IsNullOrEmpty(typeName)) continue;
2025-09-05 19:46:30 +08:00
2025-11-13 11:16:31 +08:00
var component = node.GetComponent(typeName);
if (component == null)
2025-11-11 10:57:35 +08:00
{
2025-11-13 11:16:31 +08:00
Debug.LogError($"{node.name} does not have component of type {typeName}");
continue;
2025-11-11 10:57:35 +08:00
}
2025-11-13 11:16:31 +08:00
var keyName = UIGeneratorRuleHelper.GetPrivateComponentByNameRule(com, node.name, EBindType.None);
if (_uiBindDatas.Exists(data => data.Name == keyName))
2025-11-11 10:57:35 +08:00
{
2025-11-13 11:16:31 +08:00
Debug.LogError($"Duplicate key found: {keyName}");
continue;
2025-09-05 19:46:30 +08:00
}
2025-11-13 11:16:31 +08:00
_uiBindDatas.Add(new UIBindData(keyName, component));
2025-09-05 19:46:30 +08:00
}
}
private static void CollectWidget(Transform node)
{
2025-11-11 10:57:35 +08:00
if (node == null) return;
var common = UIConfiguration.UIGenerateCommonData;
2025-11-13 11:16:31 +08:00
if (node.name.Contains(common.ComCheckEndName, StringComparison.Ordinal) &&
node.name.Contains(common.ComCheckSplitName, StringComparison.Ordinal))
2025-09-05 19:46:30 +08:00
{
2025-11-07 20:47:57 +08:00
Debug.LogWarning($"{node.name} child component cannot contain rule definition symbols!");
2025-09-05 19:46:30 +08:00
return;
}
2025-11-13 11:16:31 +08:00
var component = node.GetComponent<UIHolderObjectBase>();
2025-11-11 10:57:35 +08:00
if (component == null)
{
Debug.LogError($"{node.name} expected to be a widget but does not have UIHolderObjectBase.");
return;
}
2025-11-07 20:47:57 +08:00
2025-11-13 11:16:31 +08:00
var keyName = UIGeneratorRuleHelper.GetPrivateComponentByNameRule(string.Empty, node.name, EBindType.Widget);
if (_uiBindDatas.Exists(data => data.Name == keyName))
2025-09-05 19:46:30 +08:00
{
Debug.LogError($"Duplicate key found: {keyName}");
return;
}
2025-11-07 20:47:57 +08:00
_uiBindDatas.Add(new UIBindData(keyName, component, EBindType.Widget));
2025-09-05 19:46:30 +08:00
}
private static void CollectArrayComponent(List<Transform> arrayNode, string nodeName)
{
2025-11-13 11:16:31 +08:00
if (arrayNode == null || !arrayNode.Any()) return;
2025-11-11 10:57:35 +08:00
2025-11-13 11:16:31 +08:00
var componentArray = SplitComponentName(nodeName);
2025-11-11 10:57:35 +08:00
if (componentArray == null || componentArray.Length == 0)
{
Debug.LogWarning($"CollectArrayComponent: {nodeName} has no component definitions.");
return;
}
2025-11-13 11:16:31 +08:00
var orderedNodes = OrderArrayNodes(arrayNode);
var tempBindDatas = CreateTempBindDatas(componentArray, nodeName);
PopulateArrayComponents(componentArray, orderedNodes, tempBindDatas);
_uiBindDatas.AddRange(tempBindDatas);
}
private static List<Transform> OrderArrayNodes(List<Transform> arrayNode)
{
var splitCode = UIConfiguration.UIGenerateCommonData.ArrayComSplitName;
return arrayNode
.Select(node => new { Node = node, Index = ExtractArrayIndex(node.name, splitCode) })
.OrderBy(x => x.Index ?? int.MaxValue)
.Select(x => x.Node)
.ToList();
}
private static List<UIBindData> CreateTempBindDatas(string[] componentArray, string nodeName)
{
return componentArray.Select((com, index) =>
2025-11-11 10:57:35 +08:00
{
2025-11-13 11:16:31 +08:00
var keyName = UIGeneratorRuleHelper.GetPrivateComponentByNameRule(com, nodeName, EBindType.ListCom);
return new UIBindData(keyName, new List<Component>(), EBindType.ListCom);
}).ToList();
}
2025-09-05 19:46:30 +08:00
2025-11-13 11:16:31 +08:00
private static void PopulateArrayComponents(string[] componentArray, List<Transform> orderedNodes, List<UIBindData> tempBindDatas)
{
for (var index = 0; index < componentArray.Length; index++)
2025-09-05 19:46:30 +08:00
{
2025-11-13 11:16:31 +08:00
var com = componentArray[index];
2025-11-11 10:57:35 +08:00
if (string.IsNullOrEmpty(com)) continue;
2025-09-05 19:46:30 +08:00
2025-11-13 11:16:31 +08:00
var typeName = GetUIElementComponentType(com);
2025-11-11 10:57:35 +08:00
if (string.IsNullOrEmpty(typeName)) continue;
2025-11-07 20:47:57 +08:00
2025-11-11 10:57:35 +08:00
foreach (var node in orderedNodes)
{
2025-11-13 11:16:31 +08:00
var component = node.GetComponent(typeName);
2025-11-11 10:57:35 +08:00
if (component != null)
{
tempBindDatas[index].BindCom.Add(component);
}
else
{
Debug.LogError($"{node.name} does not have component of type {typeName}");
2025-09-05 19:46:30 +08:00
}
}
}
2025-11-11 10:57:35 +08:00
}
private static int? ExtractArrayIndex(string nodeName, string splitCode)
{
if (string.IsNullOrEmpty(nodeName) || string.IsNullOrEmpty(splitCode)) return null;
2025-11-13 11:16:31 +08:00
var lastIndex = nodeName.LastIndexOf(splitCode, StringComparison.Ordinal);
if (lastIndex < 0) return null;
2025-09-05 19:46:30 +08:00
2025-11-13 11:16:31 +08:00
var suffix = nodeName.Substring(lastIndex + splitCode.Length);
return int.TryParse(suffix, out var idx) ? idx : (int?)null;
2025-09-05 19:46:30 +08:00
}
2025-11-13 11:16:31 +08:00
public static void GenerateUIBindScript(GameObject targetObject, UIScriptGenerateData scriptGenerateData)
2025-09-05 19:46:30 +08:00
{
2025-11-11 10:57:35 +08:00
if (targetObject == null) throw new ArgumentNullException(nameof(targetObject));
if (scriptGenerateData == null) throw new ArgumentNullException(nameof(scriptGenerateData));
2025-11-10 16:01:53 +08:00
if (!PrefabChecker.IsPrefabAsset(targetObject))
{
Debug.LogWarning("请将UI界面保存为对应的目录Prefab 在进行代码生成");
return;
}
2025-11-11 10:57:35 +08:00
var ruleHelper = UIGeneratorRuleHelper;
2025-11-13 11:16:31 +08:00
if (ruleHelper == null || !ruleHelper.CheckCanGenerate(targetObject, scriptGenerateData))
2025-11-10 16:01:53 +08:00
{
return;
}
2025-11-13 11:16:31 +08:00
InitializeGenerationContext(targetObject);
2025-09-05 19:46:30 +08:00
2025-11-13 11:16:31 +08:00
var className = ruleHelper.GetClassGenerateName(targetObject, scriptGenerateData);
2025-11-11 10:57:35 +08:00
if (string.IsNullOrEmpty(className))
{
Debug.LogError("Generated className is empty.");
return;
}
2025-09-05 19:46:30 +08:00
2025-11-13 11:16:31 +08:00
CollectBindData(targetObject.transform);
GenerateScript(targetObject, className, scriptGenerateData, ruleHelper);
2025-09-05 19:46:30 +08:00
}
2025-11-13 11:16:31 +08:00
private static void InitializeGenerationContext(GameObject targetObject)
2025-09-05 19:46:30 +08:00
{
2025-11-13 11:16:31 +08:00
EditorPrefs.SetInt("InstanceId", targetObject.GetInstanceID());
2025-11-11 10:57:35 +08:00
_uiBindDatas.Clear();
_arrayComponents.Clear();
2025-11-13 11:16:31 +08:00
}
2025-09-10 14:26:54 +08:00
2025-11-13 11:16:31 +08:00
private static void GenerateScript(GameObject targetObject, string className, UIScriptGenerateData scriptGenerateData, IUIGeneratorRuleHelper ruleHelper)
{
var templateText = File.ReadAllText(UIGlobalPath.TemplatePath);
var processedText = ProcessTemplateText(targetObject, templateText, className, scriptGenerateData, ruleHelper);
2025-09-10 14:26:54 +08:00
2025-11-13 11:16:31 +08:00
ruleHelper.WriteUIScriptContent(className, processedText, scriptGenerateData);
EditorPrefs.SetString("Generate", className);
}
2025-11-12 17:48:41 +08:00
2025-11-13 11:16:31 +08:00
private static string ProcessTemplateText(GameObject targetObject, string templateText, string className, UIScriptGenerateData scriptGenerateData, IUIGeneratorRuleHelper ruleHelper)
{
return templateText
.Replace("#ReferenceNameSpace#", ruleHelper.GetReferenceNamespace(_uiBindDatas))
.Replace("#ClassNameSpace#", scriptGenerateData.NameSpace)
.Replace("#ClassName#", className)
.Replace("#TagName#", ruleHelper.GetUIResourceSavePath(targetObject, scriptGenerateData))
.Replace("#LoadType#", scriptGenerateData.LoadType.ToString())
.Replace("#Variable#", ruleHelper.GetVariableContent(_uiBindDatas));
}
[DidReloadScripts]
public static void BindUIScript()
{
if (!EditorPrefs.HasKey("Generate")) return;
2025-11-11 10:57:35 +08:00
2025-11-13 11:16:31 +08:00
var className = EditorPrefs.GetString("Generate");
var instanceId = EditorPrefs.GetInt("InstanceId", -1);
var targetObject = EditorUtility.InstanceIDToObject(instanceId) as GameObject;
2025-09-10 14:26:54 +08:00
2025-11-11 10:57:35 +08:00
if (targetObject == null)
{
Debug.LogWarning("UI script generation attachment object missing!");
return;
2025-09-05 19:46:30 +08:00
}
2025-11-11 10:57:35 +08:00
2025-11-13 11:16:31 +08:00
_uiBindDatas.Clear();
_arrayComponents.Clear();
2025-11-12 17:48:41 +08:00
2025-11-13 11:16:31 +08:00
CollectBindData(targetObject.transform);
2025-11-12 17:48:41 +08:00
BindScriptPropertyField(targetObject, className);
2025-11-13 11:16:31 +08:00
CleanupContext();
2025-11-11 10:57:35 +08:00
Debug.Log($"Generate {className} Successfully attached to game object");
2025-11-13 11:16:31 +08:00
}
2025-11-12 17:48:41 +08:00
2025-11-13 11:16:31 +08:00
private static void CleanupContext()
{
EditorPrefs.DeleteKey("Generate");
_uiBindDatas.Clear();
_arrayComponents.Clear();
2025-09-05 19:46:30 +08:00
}
2025-11-12 17:48:41 +08:00
private static void BindScriptPropertyField(GameObject targetObject, string scriptClassName)
2025-09-05 19:46:30 +08:00
{
2025-11-11 10:57:35 +08:00
if (targetObject == null) throw new ArgumentNullException(nameof(targetObject));
if (string.IsNullOrEmpty(scriptClassName)) throw new ArgumentNullException(nameof(scriptClassName));
2025-11-13 11:16:31 +08:00
var scriptType = FindScriptType(scriptClassName);
if (scriptType == null)
{
Debug.LogError($"Could not find the class: {scriptClassName}");
return;
}
var component = targetObject.GetOrAddComponent(scriptType);
BindFieldsToComponents(component, scriptType);
}
private static Type FindScriptType(string scriptClassName)
{
return AppDomain.CurrentDomain.GetAssemblies()
.Where(asm => !asm.GetName().Name.EndsWith(".Editor") &&
!asm.GetName().Name.Equals("UnityEditor"))
.SelectMany(asm => asm.GetTypes())
.FirstOrDefault(type => type.IsClass && !type.IsAbstract &&
type.Name.Equals(scriptClassName, StringComparison.Ordinal));
}
private static void BindFieldsToComponents(Component component, Type scriptType)
{
var fields = scriptType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
2025-11-11 10:57:35 +08:00
2025-11-13 11:16:31 +08:00
foreach (var field in fields.Where(field => !string.IsNullOrEmpty(field.Name)))
2025-09-05 19:46:30 +08:00
{
2025-11-13 11:16:31 +08:00
var components = _uiBindDatas.Find(data => data.Name == field.Name)?.BindCom;
if (components == null)
2025-11-11 10:57:35 +08:00
{
2025-11-13 11:16:31 +08:00
Debug.LogError($"Field {field.Name} did not find matching component binding");
2025-11-11 10:57:35 +08:00
continue;
}
2025-11-13 11:16:31 +08:00
SetFieldValue(field, components, component);
}
}
2025-11-11 10:57:35 +08:00
2025-11-13 11:16:31 +08:00
private static void SetFieldValue(FieldInfo field, IReadOnlyList<Component> components, Component targetComponent)
{
if (field.FieldType.IsArray)
{
SetArrayFieldValue(field, components, targetComponent);
}
else
{
SetSingleFieldValue(field, components, targetComponent);
2025-09-05 19:46:30 +08:00
}
2025-11-13 11:16:31 +08:00
}
2025-09-05 19:46:30 +08:00
2025-11-13 11:16:31 +08:00
private static void SetArrayFieldValue(FieldInfo field, IReadOnlyList<Component> components, Component targetComponent)
{
var elementType = field.FieldType.GetElementType();
if (elementType == null)
2025-09-05 19:46:30 +08:00
{
2025-11-13 11:16:31 +08:00
Debug.LogError($"Field {field.Name} has unknown element type.");
2025-11-11 10:57:35 +08:00
return;
}
2025-09-05 19:46:30 +08:00
2025-11-13 11:16:31 +08:00
var array = Array.CreateInstance(elementType, components.Count);
for (var i = 0; i < components.Count; i++)
2025-11-11 10:57:35 +08:00
{
2025-11-13 11:16:31 +08:00
if (components[i] == null) continue;
2025-11-11 10:57:35 +08:00
2025-11-13 11:16:31 +08:00
if (elementType.IsInstanceOfType(components[i]))
2025-11-11 10:57:35 +08:00
{
2025-11-13 11:16:31 +08:00
array.SetValue(components[i], i);
2025-11-11 10:57:35 +08:00
}
else
{
2025-11-13 11:16:31 +08:00
Debug.LogError($"Element {i} type mismatch for field {field.Name}");
2025-09-05 19:46:30 +08:00
}
}
2025-11-13 11:16:31 +08:00
field.SetValue(targetComponent, array);
}
private static void SetSingleFieldValue(FieldInfo field, IReadOnlyList<Component> components, Component targetComponent)
{
if (components.Count == 0) return;
var firstComponent = components[0];
if (firstComponent == null) return;
if (field.FieldType.IsInstanceOfType(firstComponent))
{
field.SetValue(targetComponent, firstComponent);
}
else
{
Debug.LogError($"Field {field.Name} type mismatch");
}
2025-09-05 19:46:30 +08:00
}
2025-11-10 16:01:53 +08:00
public static class PrefabChecker
{
public static bool IsEditingPrefabAsset(GameObject go)
{
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
2025-11-13 11:16:31 +08:00
return prefabStage?.IsPartOfPrefabContents(go) == true;
2025-11-10 16:01:53 +08:00
}
public static bool IsPrefabAsset(GameObject go)
{
2025-11-11 10:57:35 +08:00
if (go == null) return false;
2025-11-10 16:01:53 +08:00
var assetType = PrefabUtility.GetPrefabAssetType(go);
2025-11-13 11:16:31 +08:00
var isRegularPrefab = assetType == PrefabAssetType.Regular ||
assetType == PrefabAssetType.Variant ||
assetType == PrefabAssetType.Model;
2025-11-10 16:01:53 +08:00
2025-11-13 11:16:31 +08:00
return isRegularPrefab || IsEditingPrefabAsset(go);
2025-11-10 16:01:53 +08:00
}
}
2025-09-05 19:46:30 +08:00
}
}