com.alicizax.unity.framework/Editor/UI/IUIGeneratorRuleHelper.cs
2025-11-10 16:01:53 +08:00

182 lines
7.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.IO;
using System.Text;
using AlicizaX.UI.Runtime;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
namespace AlicizaX.UI.Editor
{
public interface IUIGeneratorRuleHelper
{
string GetPrivateComponentByNameRule(string regexName, string componetName, EBindType bindType);
string GetPublicComponentByNameRule(string variableName);
string GetClassGenerateName(GameObject targetObject, UIScriptGenerateData scriptGenerateData);
string GetUIResourceSavePath(GameObject targetObject, UIScriptGenerateData scriptGenerateData);
void WriteUIScriptContent(string className, string scriptContent, UIScriptGenerateData scriptGenerateData);
bool CheckCanGenerate(GameObject targetObject, UIScriptGenerateData scriptGenerateData);
}
public class DefaultIuiGeneratorRuleHelper : IUIGeneratorRuleHelper
{
public string GetPrivateComponentByNameRule(string regexName, string componentName, EBindType bindType)
{
string endPrefix = bindType == EBindType.ListCom ? "List" : string.Empty;
int endNameIndex = componentName.IndexOf(
UIGenerateConfiguration.Instance.UIGenerateCommonData.ComCheckEndName,
StringComparison.Ordinal);
string componentSuffix = endNameIndex >= 0 ? componentName.Substring(endNameIndex + 1) : componentName;
return $"m{regexName}{componentSuffix}{endPrefix}";
}
public string GetPublicComponentByNameRule(string variableName)
{
return variableName.Substring(1);
}
public string GetClassGenerateName(GameObject targetObject, UIScriptGenerateData scriptGenerateData)
{
return $"{UIGenerateConfiguration.Instance.UIGenerateCommonData.GeneratePrefix}_{targetObject.name}";
}
public string GetUIResourceSavePath(GameObject targetObject, UIScriptGenerateData scriptGenerateData)
{
if (targetObject == null)
return $"\"{nameof(targetObject)}\"";
// 默认返回资源名
string defaultPath = targetObject.name;
// 获取对应的Prefab资源路径支持场景Prefab实例 & Prefab编辑模式
string assetPath = GetPrefabAssetPath(targetObject);
if (string.IsNullOrEmpty(assetPath) || !assetPath.StartsWith("Assets/"))
return defaultPath; // 不在 Assets 下
// 统一使用正斜杠
assetPath = assetPath.Replace('\\', '/');
switch (scriptGenerateData.LoadType)
{
case EUIResLoadType.Resources:
{
string resourcesRoot = scriptGenerateData.UIPrefabRootPath; // 例如 "Assets/Resources/UI"
string relPath = GetResourcesRelativePath(assetPath, resourcesRoot);
if (relPath == null)
{
Debug.LogWarning($"[UI生成] 资源 {assetPath} 不在配置的 Resources 根目录下: {resourcesRoot}");
return defaultPath;
}
return relPath;
}
case EUIResLoadType.AssetBundle:
{
string bundleRoot = scriptGenerateData.UIPrefabRootPath; // 例如 "Assets/Bundles/UI"
var defaultPackage = YooAsset.Editor.AssetBundleCollectorSettingData.Setting.GetPackage("DefaultPackage");
if (defaultPackage.EnableAddressable)
return defaultPath;
if (!assetPath.StartsWith(bundleRoot, System.StringComparison.OrdinalIgnoreCase))
{
Debug.LogWarning($"[UI生成] 资源 {assetPath} 不在配置的 AssetBundle 根目录下: {bundleRoot}");
return defaultPath;
}
return Path.ChangeExtension(assetPath, null);
}
default:
return defaultPath;
}
}
/// <summary>
/// 获取 GameObject 对应的 Prefab 资源路径,如果是 Prefab 编辑模式也可以获取
/// </summary>
private string GetPrefabAssetPath(GameObject go)
{
var prefabAsset = PrefabUtility.GetCorrespondingObjectFromSource(go);
if (prefabAsset != null)
return AssetDatabase.GetAssetPath(prefabAsset);
// Prefab 编辑模式
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
if (prefabStage != null && prefabStage.IsPartOfPrefabContents(go))
return prefabStage.assetPath;
return null;
}
/// <summary>
/// 获取 Resources.Load 可用路径(去掉扩展名),如果不在指定的 Resources 根目录返回 null
/// </summary>
private string GetResourcesRelativePath(string assetPath, string resourcesRoot)
{
// 统一正斜杠
assetPath = assetPath.Replace('\\', '/');
resourcesRoot = resourcesRoot.Replace('\\', '/');
if (!assetPath.StartsWith(resourcesRoot, System.StringComparison.OrdinalIgnoreCase))
return null;
// 获取相对路径
string relPath = assetPath.Substring(resourcesRoot.Length).TrimStart('/');
return Path.ChangeExtension(relPath, null); // 去掉扩展名
}
public void WriteUIScriptContent(string className, string scriptContent, UIScriptGenerateData scriptGenerateData)
{
string scriptFolderPath = scriptGenerateData.GenerateHolderCodePath;
string scriptFilePath = Path.Combine(scriptFolderPath, className + ".cs");
if (!Directory.Exists(scriptFolderPath))
{
Directory.CreateDirectory(scriptFolderPath);
}
if (File.Exists(scriptFilePath))
{
string oldText = File.ReadAllText(scriptFilePath);
if (oldText.Equals(scriptContent))
{
EditorPrefs.SetString("Generate", className);
UIScriptGeneratorHelper.CheckHasAttach();
return;
}
}
File.WriteAllText(scriptFilePath, scriptContent, Encoding.UTF8);
EditorPrefs.SetString("Generate", className);
AssetDatabase.Refresh();
}
public bool CheckCanGenerate(GameObject targetObject, UIScriptGenerateData scriptGenerateData)
{
string assetPath = GetPrefabAssetPath(targetObject);
if (string.IsNullOrEmpty(assetPath) || !assetPath.StartsWith("Assets/"))
return false; // 不在 Assets 下
// 统一使用正斜杠
assetPath = assetPath.Replace('\\', '/');
bool result = assetPath.StartsWith(scriptGenerateData.UIPrefabRootPath, System.StringComparison.OrdinalIgnoreCase);
if (!result)
{
Debug.LogWarning($"UI存储位置与配置生成规则不符合 请检查对应配置的UIPrefabRootPath\n[AssetPath]{assetPath}\n[ConfigPath]{scriptGenerateData.UIPrefabRootPath}");
}
return result;
}
}
}