修改
This commit is contained in:
parent
f3251980f5
commit
8d705cbd94
@ -7,9 +7,6 @@ namespace AlicizaX.UI.Editor
|
|||||||
public class UIGenerateEditorWindow : EditorWindow
|
public class UIGenerateEditorWindow : EditorWindow
|
||||||
{
|
{
|
||||||
private GameObject selectedObject;
|
private GameObject selectedObject;
|
||||||
private Vector2 windowPosition;
|
|
||||||
private float windowWidth;
|
|
||||||
private float windowHeight;
|
|
||||||
private string[] menuItems;
|
private string[] menuItems;
|
||||||
|
|
||||||
[MenuItem("GameObject/UI生成绑定", priority = 10)]
|
[MenuItem("GameObject/UI生成绑定", priority = 10)]
|
||||||
@ -21,37 +18,79 @@ namespace AlicizaX.UI.Editor
|
|||||||
var uiScriptConfigs = UIGenerateConfiguration.Instance.UIScriptGenerateConfigs;
|
var uiScriptConfigs = UIGenerateConfiguration.Instance.UIScriptGenerateConfigs;
|
||||||
if (uiScriptConfigs == null || uiScriptConfigs.Count == 0) return;
|
if (uiScriptConfigs == null || uiScriptConfigs.Count == 0) return;
|
||||||
|
|
||||||
var window = GetWindow<UIGenerateEditorWindow>("", true);
|
var window = GetWindow<UIGenerateEditorWindow>(true, "UI 生成绑定", true);
|
||||||
window.selectedObject = selectedObject;
|
window.selectedObject = selectedObject;
|
||||||
|
|
||||||
window.menuItems = uiScriptConfigs.Select(config => $"{config.ProjectName}").ToArray();
|
window.menuItems = uiScriptConfigs.Select(config => $"{config.ProjectName}").ToArray();
|
||||||
|
|
||||||
var windowWidth = 300;
|
var windowWidth = 300f;
|
||||||
var windowHeight = (window.menuItems.Length * 35f);
|
var windowHeight = Mathf.Max(1, window.menuItems.Length) * 35f + 10f;
|
||||||
|
|
||||||
|
|
||||||
Vector3 objectWorldPosition = selectedObject.transform.position;
|
Vector3 objectWorldPosition = selectedObject.transform.position;
|
||||||
Vector3 screenPosition = HandleUtility.WorldToGUIPoint(objectWorldPosition);
|
Vector2 screenPoint;
|
||||||
var windowPosition = new Vector2(screenPosition.x, screenPosition.y - windowHeight - 5f);
|
|
||||||
|
var sceneView = SceneView.lastActiveSceneView;
|
||||||
|
if (sceneView != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
Vector2 guiPointInSceneView = HandleUtility.WorldToGUIPoint(objectWorldPosition);
|
||||||
|
|
||||||
|
screenPoint = new Vector2(sceneView.position.x + guiPointInSceneView.x,
|
||||||
|
sceneView.position.y + guiPointInSceneView.y);
|
||||||
|
}
|
||||||
|
else if (EditorWindow.mouseOverWindow != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
Vector2 guiPoint = HandleUtility.WorldToGUIPoint(objectWorldPosition);
|
||||||
|
var host = EditorWindow.mouseOverWindow;
|
||||||
|
screenPoint = new Vector2(host.position.x + guiPoint.x, host.position.y + guiPoint.y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
var mainDisplay = Display.displays.Length > 0 ? Display.displays[0] : null;
|
||||||
|
float centerX = (mainDisplay != null) ? (mainDisplay.systemWidth / 2f) : (Screen.width / 2f);
|
||||||
|
float centerY = (mainDisplay != null) ? (mainDisplay.systemHeight / 2f) : (Screen.height / 2f);
|
||||||
|
screenPoint = new Vector2(centerX, centerY);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Vector2 windowPosition = new Vector2(screenPoint.x, screenPoint.y - windowHeight - 5f);
|
||||||
|
|
||||||
|
|
||||||
|
float screenW = Mathf.Max(100, Display.main.systemWidth);
|
||||||
|
float screenH = Mathf.Max(100, Display.main.systemHeight);
|
||||||
|
if (windowPosition.x + windowWidth > screenW) windowPosition.x = screenW - windowWidth - 5f;
|
||||||
|
if (windowPosition.x < 5f) windowPosition.x = 5f;
|
||||||
|
if (windowPosition.y < 5f) windowPosition.y = 5f;
|
||||||
|
if (windowPosition.y + windowHeight > screenH) windowPosition.y = screenH - windowHeight - 5f;
|
||||||
|
|
||||||
window.minSize = new Vector2(windowWidth, windowHeight);
|
window.minSize = new Vector2(windowWidth, windowHeight);
|
||||||
window.maxSize = new Vector2(windowWidth, windowHeight);
|
window.maxSize = new Vector2(windowWidth, windowHeight);
|
||||||
|
|
||||||
window.position = new Rect(windowPosition, new Vector2(windowWidth, windowHeight));
|
window.position = new Rect(windowPosition, new Vector2(windowWidth, windowHeight));
|
||||||
window.Show();
|
window.ShowPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGUI()
|
private void OnGUI()
|
||||||
{
|
{
|
||||||
GUILayout.Space(5);
|
GUILayout.Space(5);
|
||||||
|
if (menuItems == null || menuItems.Length == 0)
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("没有可用配置");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var item in menuItems)
|
foreach (var item in menuItems)
|
||||||
{
|
{
|
||||||
if (GUILayout.Button(item, EditorStyles.toolbarButton))
|
if (GUILayout.Button(item, EditorStyles.toolbarButton, GUILayout.Height(28)))
|
||||||
{
|
{
|
||||||
GenerateScriptForConfig(selectedObject, item);
|
GenerateScriptForConfig(selectedObject, item);
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
GUILayout.Space(10);
|
GUILayout.Space(6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@ using Sirenix.Utilities.Editor;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEditor.Callbacks;
|
using UnityEditor.Callbacks;
|
||||||
|
using UnityEditor.SceneManagement;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
|
||||||
public enum EBindType
|
public enum EBindType
|
||||||
@ -47,28 +48,28 @@ namespace AlicizaX.UI.Editor
|
|||||||
internal static class UIScriptGeneratorHelper
|
internal static class UIScriptGeneratorHelper
|
||||||
{
|
{
|
||||||
private static UIGenerateConfiguration _uiGenerateConfiguration;
|
private static UIGenerateConfiguration _uiGenerateConfiguration;
|
||||||
private static IUIGeneratorHelper _nameRuleHelper;
|
private static IUIGeneratorRuleHelper _uiGeneratorRuleHelper;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置自定义命名规则助手[4](@ref)
|
/// 设置自定义命名规则助手[4](@ref)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static IUIGeneratorHelper UIGeneratorRuleHelper
|
public static IUIGeneratorRuleHelper UIGeneratorRuleHelper
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_nameRuleHelper == null || (_nameRuleHelper != null && !UIConfiguration.UIScriptGeneratorHelper.Equals(_nameRuleHelper.GetType().FullName)))
|
if (_uiGeneratorRuleHelper == null || (_uiGeneratorRuleHelper != null && !UIConfiguration.UIScriptGeneratorRuleHelper.Equals(_uiGeneratorRuleHelper.GetType().FullName)))
|
||||||
{
|
{
|
||||||
Type ruleHelperType = Type.GetType(UIConfiguration.UIScriptGeneratorHelper);
|
Type ruleHelperType = Type.GetType(UIConfiguration.UIScriptGeneratorRuleHelper);
|
||||||
if (ruleHelperType == null)
|
if (ruleHelperType == null)
|
||||||
{
|
{
|
||||||
Debug.LogError($"UIScriptGeneratorHelper: Could not load UI ScriptGeneratorHelper {UIConfiguration.UIScriptGeneratorHelper}");
|
Debug.LogError($"UIScriptGeneratorHelper: Could not load UI ScriptGeneratorHelper {UIConfiguration.UIScriptGeneratorRuleHelper}");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
_nameRuleHelper = Activator.CreateInstance(ruleHelperType) as IUIGeneratorHelper;
|
_uiGeneratorRuleHelper = Activator.CreateInstance(ruleHelperType) as IUIGeneratorRuleHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _nameRuleHelper;
|
return _uiGeneratorRuleHelper;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +115,6 @@ namespace AlicizaX.UI.Editor
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static List<UIBindData> _uiBindDatas = new List<UIBindData>();
|
private static List<UIBindData> _uiBindDatas = new List<UIBindData>();
|
||||||
private static string _generateNameSpace = string.Empty;
|
|
||||||
private static List<string> _arrayComponents = new List<string>();
|
private static List<string> _arrayComponents = new List<string>();
|
||||||
|
|
||||||
private static void GetBindData(Transform root)
|
private static void GetBindData(Transform root)
|
||||||
@ -322,14 +322,13 @@ namespace AlicizaX.UI.Editor
|
|||||||
return variableTextBuilder.ToString();
|
return variableTextBuilder.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GenerateScript(string className)
|
private static string GenerateScript(string className, string generateNameSpace)
|
||||||
{
|
{
|
||||||
StringBuilder scriptBuilder = new StringBuilder();
|
StringBuilder scriptBuilder = new StringBuilder();
|
||||||
scriptBuilder.Append(GetReferenceNamespace());
|
scriptBuilder.Append(GetReferenceNamespace());
|
||||||
|
|
||||||
scriptBuilder.Append("using Sirenix.OdinInspector;\n");
|
|
||||||
scriptBuilder.Append("using AlicizaX.UI.Runtime;\n");
|
scriptBuilder.Append("using AlicizaX.UI.Runtime;\n");
|
||||||
scriptBuilder.Append($"namespace {_generateNameSpace}\n");
|
scriptBuilder.Append($"namespace {generateNameSpace}\n");
|
||||||
scriptBuilder.Append("{\n");
|
scriptBuilder.Append("{\n");
|
||||||
scriptBuilder.Append("\t#Attribute#\n");
|
scriptBuilder.Append("\t#Attribute#\n");
|
||||||
scriptBuilder.Append($"\tpublic class {className} : UIHolderObjectBase\n");
|
scriptBuilder.Append($"\tpublic class {className} : UIHolderObjectBase\n");
|
||||||
@ -349,69 +348,38 @@ namespace AlicizaX.UI.Editor
|
|||||||
|
|
||||||
public static void GenerateAndAttachScript(GameObject targetObject, UIScriptGenerateData scriptGenerateData)
|
public static void GenerateAndAttachScript(GameObject targetObject, UIScriptGenerateData scriptGenerateData)
|
||||||
{
|
{
|
||||||
|
if (!PrefabChecker.IsPrefabAsset(targetObject))
|
||||||
|
{
|
||||||
|
Debug.LogWarning("请将UI界面保存为对应的目录Prefab 在进行代码生成");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!UIGeneratorRuleHelper.CheckCanGenerate(targetObject, scriptGenerateData))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
EditorPrefs.SetInt("InstanceId", targetObject.GetInstanceID());
|
EditorPrefs.SetInt("InstanceId", targetObject.GetInstanceID());
|
||||||
_uiBindDatas.Clear();
|
_uiBindDatas.Clear();
|
||||||
_generateNameSpace = scriptGenerateData.NameSpace;
|
|
||||||
_arrayComponents.Clear();
|
_arrayComponents.Clear();
|
||||||
|
|
||||||
string className = $"{UIConfiguration.UIGenerateCommonData.GeneratePrefix}_{targetObject.name}";
|
string className = UIGeneratorRuleHelper.GetClassGenerateName(targetObject, scriptGenerateData);
|
||||||
string scriptSavePath = Path.Combine(scriptGenerateData.GenerateHolderCodePath, className + ".cs");
|
|
||||||
|
|
||||||
GetBindData(targetObject.transform);
|
GetBindData(targetObject.transform);
|
||||||
|
|
||||||
string scriptContent = GenerateScript(className);
|
string scriptContent = GenerateScript(className, scriptGenerateData.NameSpace);
|
||||||
string tagName = $"\"{targetObject.name}\"";
|
string tagName = $"\"{UIGeneratorRuleHelper.GetUIResourceSavePath(targetObject, scriptGenerateData)}\"";
|
||||||
|
|
||||||
if (scriptGenerateData.LoadType == EUIResLoadType.Resources)
|
|
||||||
{
|
|
||||||
string matchWords = string.Empty;
|
|
||||||
UIConfiguration.UIGenerateCommonData.CombineWords.Any(t =>
|
|
||||||
{
|
|
||||||
if (targetObject.name.IndexOf(t.Key, StringComparison.Ordinal) >= 0)
|
|
||||||
{
|
|
||||||
matchWords = t.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return targetObject.name.IndexOf(t.Key, StringComparison.Ordinal) >= 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
string finalPath = Path.Combine(
|
|
||||||
scriptGenerateData.UIPrefabRootPath.Replace("Assets/", "").Replace("Resources/", ""),
|
|
||||||
matchWords);
|
|
||||||
string directory = Path.Combine(scriptGenerateData.UIPrefabRootPath, matchWords);
|
|
||||||
|
|
||||||
if (!Directory.Exists(directory))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
finalPath = Utility.Path.GetRegularPath(finalPath);
|
|
||||||
tagName = $"\"{finalPath}/{targetObject.name}\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
scriptContent = scriptContent.Replace("#Tag#", tagName);
|
|
||||||
|
|
||||||
string uiAttribute = $"[UIRes({className}.ResTag, EUIResLoadType.{scriptGenerateData.LoadType})]";
|
string uiAttribute = $"[UIRes({className}.ResTag, EUIResLoadType.{scriptGenerateData.LoadType})]";
|
||||||
|
|
||||||
scriptContent = scriptContent.Replace("#Attribute#", uiAttribute);
|
scriptContent = scriptContent.Replace("#Attribute#", uiAttribute);
|
||||||
|
scriptContent = scriptContent.Replace("#Tag#", tagName);
|
||||||
|
|
||||||
if (File.Exists(scriptSavePath))
|
UIGeneratorRuleHelper.WriteUIScriptContent(className, scriptContent, scriptGenerateData);
|
||||||
{
|
|
||||||
string oldText = File.ReadAllText(scriptSavePath);
|
|
||||||
if (oldText.Equals(scriptContent))
|
|
||||||
{
|
|
||||||
EditorPrefs.SetString("Generate", className);
|
|
||||||
CheckHasAttach();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
File.WriteAllText(scriptSavePath, scriptContent, Encoding.UTF8);
|
|
||||||
EditorPrefs.SetString("Generate", className);
|
|
||||||
AssetDatabase.Refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[DidReloadScripts]
|
[DidReloadScripts]
|
||||||
private static void CheckHasAttach()
|
public static void CheckHasAttach()
|
||||||
{
|
{
|
||||||
bool has = EditorPrefs.HasKey("Generate");
|
bool has = EditorPrefs.HasKey("Generate");
|
||||||
if (has)
|
if (has)
|
||||||
@ -513,5 +481,32 @@ namespace AlicizaX.UI.Editor
|
|||||||
Debug.LogError($"Could not find the class: {scriptClassName}");
|
Debug.LogError($"Could not find the class: {scriptClassName}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class PrefabChecker
|
||||||
|
{
|
||||||
|
public static bool IsEditingPrefabAsset(GameObject go)
|
||||||
|
{
|
||||||
|
// 检查当前是否在Prefab编辑模式
|
||||||
|
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||||
|
if (prefabStage == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 检查选中对象是否属于当前PrefabStage
|
||||||
|
return prefabStage.IsPartOfPrefabContents(go);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsPrefabAsset(GameObject go)
|
||||||
|
{
|
||||||
|
// 普通Asset目录中的Prefab
|
||||||
|
var assetType = PrefabUtility.GetPrefabAssetType(go);
|
||||||
|
if (assetType == PrefabAssetType.Regular ||
|
||||||
|
assetType == PrefabAssetType.Variant ||
|
||||||
|
assetType == PrefabAssetType.Model)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Prefab编辑模式下
|
||||||
|
return IsEditingPrefabAsset(go);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -161,7 +161,7 @@ namespace AlicizaX.UI.Editor
|
|||||||
d.UIPrefabRootPath = DrawFolderField("Prefab根目录", d.UIPrefabRootPath, rect.x, rect.y + 3 * (lh + pad), rect.width, lh);
|
d.UIPrefabRootPath = DrawFolderField("Prefab根目录", d.UIPrefabRootPath, rect.x, rect.y + 3 * (lh + pad), rect.width, lh);
|
||||||
d.LoadType = (EUIResLoadType)EditorGUI.EnumPopup(new Rect(rect.x, rect.y + 4 * (lh + pad), rect.width, lh), "加载类型", d.LoadType);
|
d.LoadType = (EUIResLoadType)EditorGUI.EnumPopup(new Rect(rect.x, rect.y + 4 * (lh + pad), rect.width, lh), "加载类型", d.LoadType);
|
||||||
};
|
};
|
||||||
projectList.onAddCallback = (r) => UIScriptGenerateConfigs.Add(new UIScriptGenerateData { ProjectName = "NewProject", NameSpace = "Game.UI", GenerateHolderCodePath = "Assets/Scripts/UI/Generated", UIPrefabRootPath = "Assets/Art/UI/Prefabs", LoadType = EUIResLoadType.Resources });
|
projectList.onAddCallback = (r) => UIScriptGenerateConfigs.Add(new UIScriptGenerateData { ProjectName = "NewProject", NameSpace = "Game.UI", GenerateHolderCodePath = "Assets/Scripts/UI/Generated", UIPrefabRootPath = "Assets/Resources/UI", LoadType = EUIResLoadType.Resources });
|
||||||
projectList.onRemoveCallback = (r) =>
|
projectList.onRemoveCallback = (r) =>
|
||||||
{
|
{
|
||||||
if (r.index >= 0) UIScriptGenerateConfigs.RemoveAt(r.index);
|
if (r.index >= 0) UIScriptGenerateConfigs.RemoveAt(r.index);
|
||||||
@ -192,9 +192,9 @@ namespace AlicizaX.UI.Editor
|
|||||||
{
|
{
|
||||||
m_ScriptGeneratorHelperTypes = new List<string>();
|
m_ScriptGeneratorHelperTypes = new List<string>();
|
||||||
|
|
||||||
m_ScriptGeneratorHelperTypes.AddRange(AlicizaX.Utility.Assembly.GetRuntimeTypeNames(typeof(IUIGeneratorHelper)));
|
m_ScriptGeneratorHelperTypes.AddRange(AlicizaX.Utility.Assembly.GetRuntimeTypeNames(typeof(IUIGeneratorRuleHelper)));
|
||||||
|
|
||||||
m_ScriptGeneratorHelperSelectIndex = m_ScriptGeneratorHelperTypes.IndexOf(UIGenerateConfiguration.Instance.UIScriptGeneratorHelper);
|
m_ScriptGeneratorHelperSelectIndex = m_ScriptGeneratorHelperTypes.IndexOf(UIGenerateConfiguration.Instance.UIScriptGeneratorRuleHelper);
|
||||||
if (m_ScriptGeneratorHelperSelectIndex < 0)
|
if (m_ScriptGeneratorHelperSelectIndex < 0)
|
||||||
{
|
{
|
||||||
m_ScriptGeneratorHelperSelectIndex = 0;
|
m_ScriptGeneratorHelperSelectIndex = 0;
|
||||||
@ -271,9 +271,9 @@ namespace AlicizaX.UI.Editor
|
|||||||
UIGenerateCommonData.GeneratePrefix = EditorGUILayout.TextField(new GUIContent("生成脚本前缀"), UIGenerateCommonData.GeneratePrefix);
|
UIGenerateCommonData.GeneratePrefix = EditorGUILayout.TextField(new GUIContent("生成脚本前缀"), UIGenerateCommonData.GeneratePrefix);
|
||||||
m_ScriptGeneratorHelperSelectIndex = EditorGUILayout.Popup("解密服务", m_ScriptGeneratorHelperSelectIndex, m_ScriptGeneratorHelperTypes.ToArray());
|
m_ScriptGeneratorHelperSelectIndex = EditorGUILayout.Popup("解密服务", m_ScriptGeneratorHelperSelectIndex, m_ScriptGeneratorHelperTypes.ToArray());
|
||||||
string selectService = m_ScriptGeneratorHelperTypes[m_ScriptGeneratorHelperSelectIndex];
|
string selectService = m_ScriptGeneratorHelperTypes[m_ScriptGeneratorHelperSelectIndex];
|
||||||
if (uiGenerateConfiguration.UIScriptGeneratorHelper != selectService)
|
if (uiGenerateConfiguration.UIScriptGeneratorRuleHelper != selectService)
|
||||||
{
|
{
|
||||||
UIGenerateConfiguration.Instance.UIScriptGeneratorHelper = selectService;
|
UIGenerateConfiguration.Instance.UIScriptGeneratorRuleHelper = selectService;
|
||||||
UIGenerateConfiguration.Save();
|
UIGenerateConfiguration.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,6 +496,7 @@ namespace AlicizaX.UI.Editor
|
|||||||
uiGenerateConfiguration.UIElementRegexConfigs = UIElementRegexConfigs;
|
uiGenerateConfiguration.UIElementRegexConfigs = UIElementRegexConfigs;
|
||||||
uiGenerateConfiguration.UIScriptGenerateConfigs = UIScriptGenerateConfigs;
|
uiGenerateConfiguration.UIScriptGenerateConfigs = UIScriptGenerateConfigs;
|
||||||
UIGenerateConfiguration.Save();
|
UIGenerateConfiguration.Save();
|
||||||
|
Debug.Log("UIGenerateConfiguration Saved...");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDisable() => SaveConfig();
|
private void OnDisable() => SaveConfig();
|
||||||
|
|||||||
@ -1,31 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Editor
|
|
||||||
{
|
|
||||||
public interface IUIGeneratorHelper
|
|
||||||
{
|
|
||||||
string GetPrivateComponentByNameRule(string regexName, string componetName, EBindType bindType);
|
|
||||||
|
|
||||||
string GetPublicComponentByNameRule(string variableName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DefaultUIGeneratorHelper : IUIGeneratorHelper
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
181
Editor/UI/IUIGeneratorRuleHelper.cs
Normal file
181
Editor/UI/IUIGeneratorRuleHelper.cs
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,6 +7,7 @@ using AlicizaX.Editor.Setting;
|
|||||||
using AlicizaX.UI.Runtime;
|
using AlicizaX.UI.Runtime;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
|
using UnityEngine.Serialization;
|
||||||
|
|
||||||
namespace AlicizaX.UI.Editor
|
namespace AlicizaX.UI.Editor
|
||||||
{
|
{
|
||||||
@ -19,7 +20,7 @@ namespace AlicizaX.UI.Editor
|
|||||||
|
|
||||||
[Header("UI脚本生成配置(支持多个项目)")] public List<UIScriptGenerateData> UIScriptGenerateConfigs = new List<UIScriptGenerateData>();
|
[Header("UI脚本生成配置(支持多个项目)")] public List<UIScriptGenerateData> UIScriptGenerateConfigs = new List<UIScriptGenerateData>();
|
||||||
|
|
||||||
[Header("UI脚本生成辅助类")] public string UIScriptGeneratorHelper;
|
[Header("UI脚本生成辅助类")] public string UIScriptGeneratorRuleHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
@ -64,9 +65,9 @@ namespace AlicizaX.UI.Editor
|
|||||||
[Header("路径设置")] [Tooltip("生成的UI脚本路径(相对Assets)")]
|
[Header("路径设置")] [Tooltip("生成的UI脚本路径(相对Assets)")]
|
||||||
public string GenerateHolderCodePath = "Assets/Scripts/UI/Generated";
|
public string GenerateHolderCodePath = "Assets/Scripts/UI/Generated";
|
||||||
|
|
||||||
[Tooltip("UI Prefab根目录")] public string UIPrefabRootPath = "Assets/Art/UI/Prefabs";
|
[Tooltip("UI Prefab根目录")] public string UIPrefabRootPath = "Assets/Resources/UI/";
|
||||||
|
|
||||||
[Header("加载类型")] [Tooltip("UI资源加载方式(本地 / YooAsset / Addressable等)")]
|
[Header("加载类型")] [Tooltip("UI资源加载方式(本地 / YooAsset )")]
|
||||||
public EUIResLoadType LoadType = EUIResLoadType.Resources;
|
public EUIResLoadType LoadType = EUIResLoadType.Resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user