2025-09-23 11:18:38 +08:00
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
|
using System.Collections;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using UnityEditor;
|
|
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using Stary.Evo;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
|
using Stary.Evo.Editor;
|
|
|
|
|
|
|
|
|
|
|
|
public class UICreateWindow : EditorWindow
|
|
|
|
|
|
{
|
|
|
|
|
|
#region MenuItem
|
|
|
|
|
|
|
2025-09-24 16:21:43 +08:00
|
|
|
|
[MenuItem("Evo/UI管理/CreateUI")]
|
2025-09-23 11:18:38 +08:00
|
|
|
|
private static void CopyUI()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Selection.activeObject == null || !(Selection.activeObject is GameObject))
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError("请选择UI预制体!");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UICreateWindow.OpenWindow().uiPrefab = Selection.activeObject as GameObject;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-24 16:21:43 +08:00
|
|
|
|
[MenuItem("Evo/UI管理/OpenWindow")]
|
2025-09-23 11:18:38 +08:00
|
|
|
|
public static UICreateWindow OpenWindow()
|
|
|
|
|
|
{
|
|
|
|
|
|
var window = GetWindow<UICreateWindow>("UI管理");
|
|
|
|
|
|
if (window == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
window = CreateWindow<UICreateWindow>("UI管理");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
window.name = "UI管理";
|
|
|
|
|
|
window.Focus();
|
|
|
|
|
|
return window;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
private string _mInput;
|
|
|
|
|
|
|
|
|
|
|
|
private Vector2 _scroll;
|
|
|
|
|
|
private Vector2 _scroll2;
|
|
|
|
|
|
private Vector2 _scroll3;
|
|
|
|
|
|
private string _uiViewTemplate = "UIViewTemplate";
|
|
|
|
|
|
private string _uiConfig = "UIConfig";
|
|
|
|
|
|
private string _uiName;
|
2025-09-24 17:16:12 +08:00
|
|
|
|
private string _saveUIPath;
|
2025-09-23 11:18:38 +08:00
|
|
|
|
public GameObject uiPrefab;
|
|
|
|
|
|
private Dictionary<string, string> _uiNames = new Dictionary<string, string>();
|
|
|
|
|
|
private Dictionary<string, UIConfigJson> _uiJsonDatas = new Dictionary<string, UIConfigJson>();
|
|
|
|
|
|
|
|
|
|
|
|
private bool _isWindow = true;
|
|
|
|
|
|
private UILayer _layer = UILayer.NormalLayer;
|
|
|
|
|
|
|
|
|
|
|
|
private IEnumerable<Type> uiViews;
|
|
|
|
|
|
|
|
|
|
|
|
private string[] _domainNames;
|
|
|
|
|
|
private int _domainIndex;
|
|
|
|
|
|
|
|
|
|
|
|
private UIConfig _uiConfigObj;
|
|
|
|
|
|
|
|
|
|
|
|
private void OnEnable()
|
|
|
|
|
|
{
|
|
|
|
|
|
TryGetPath(ref _uiViewTemplate, _uiViewTemplate, ".txt");
|
|
|
|
|
|
_domainNames = CreatAssetWindow.GetCreatDomainAllName();
|
|
|
|
|
|
ValueChang();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ValueChang()
|
|
|
|
|
|
{
|
|
|
|
|
|
_uiJsonDatas.Clear();
|
|
|
|
|
|
_uiNames.Clear();
|
|
|
|
|
|
uiViews = ReflectionHelper.GetAllUIViewTypes(_domainNames[_domainIndex]);
|
2025-09-24 17:16:12 +08:00
|
|
|
|
_saveUIPath = EditorPrefs.GetString(nameof(_saveUIPath));
|
2025-09-23 11:18:38 +08:00
|
|
|
|
DomainPathField();
|
|
|
|
|
|
foreach (var uiView in uiViews)
|
|
|
|
|
|
{
|
|
|
|
|
|
string str = uiView.Name;
|
|
|
|
|
|
if (str.Equals("Max")) continue;
|
|
|
|
|
|
|
|
|
|
|
|
var jsonData = GetUIJson(str);
|
|
|
|
|
|
//if (jsonData == null || string.IsNullOrEmpty(jsonData.path)) continue;
|
|
|
|
|
|
var scriptPath = GetUIScript(str, true);
|
|
|
|
|
|
_uiNames.AddOrUpdate(str, scriptPath);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-24 17:16:12 +08:00
|
|
|
|
|
2025-09-23 11:18:38 +08:00
|
|
|
|
private void OnGUI()
|
|
|
|
|
|
{
|
2025-09-23 11:21:07 +08:00
|
|
|
|
EditorGUILayout.LabelField("通过[Evo/UI管理]可以打开");
|
2025-09-23 11:18:38 +08:00
|
|
|
|
_scroll = EditorGUILayout.BeginScrollView(_scroll);
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorGUILayout.HelpBox("UI基础文件", MessageType.Info);
|
|
|
|
|
|
{
|
|
|
|
|
|
PathField("UI模板文件.txt", ref _uiViewTemplate, nameof(_uiViewTemplate), ".txt");
|
|
|
|
|
|
DomainPathField();
|
|
|
|
|
|
EditorGUILayout.ObjectField(_uiConfig, _uiConfigObj, typeof(UIConfig), true);
|
|
|
|
|
|
}
|
|
|
|
|
|
EditorGUILayout.Space(10);
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
|
|
|
|
{
|
|
|
|
|
|
_scroll2 = EditorGUILayout.BeginScrollView(_scroll2, "box", GUILayout.Width(position.width * 0.4f - 6));
|
|
|
|
|
|
{
|
2025-09-24 17:16:12 +08:00
|
|
|
|
var tempIndex = EditorGUILayout.Popup("Domain", _domainIndex, _domainNames);
|
2025-09-23 11:18:38 +08:00
|
|
|
|
if (tempIndex != _domainIndex)
|
|
|
|
|
|
{
|
|
|
|
|
|
ValueChang();
|
|
|
|
|
|
_domainIndex = tempIndex;
|
|
|
|
|
|
}
|
2025-09-24 17:16:12 +08:00
|
|
|
|
|
2025-09-23 11:18:38 +08:00
|
|
|
|
EditorGUILayout.HelpBox("已创建的UI", MessageType.Info);
|
|
|
|
|
|
_mInput = EditorGUILayout.TextField(_mInput, EditorStyles.toolbarSearchField, GUILayout.Height(20));
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var uiView in uiViews)
|
|
|
|
|
|
{
|
|
|
|
|
|
string str = uiView.Name;
|
|
|
|
|
|
if (str.Equals("Max")) continue;
|
|
|
|
|
|
if (!string.IsNullOrEmpty(_mInput) && !str.Contains(_mInput)) continue;
|
|
|
|
|
|
|
|
|
|
|
|
var jsonData = GetUIJson(str);
|
|
|
|
|
|
var scriptPath = GetUIScript(str);
|
|
|
|
|
|
if (jsonData == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
jsonData = new UIConfigJson();
|
|
|
|
|
|
}
|
2025-09-24 17:16:12 +08:00
|
|
|
|
|
2025-09-23 11:18:38 +08:00
|
|
|
|
if (string.IsNullOrEmpty(scriptPath)) continue;
|
|
|
|
|
|
|
|
|
|
|
|
var defaultColor = GUI.color;
|
|
|
|
|
|
if (str.Equals(_uiName))
|
|
|
|
|
|
{
|
|
|
|
|
|
GUI.color = Color.yellow;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.BeginHorizontal("box");
|
|
|
|
|
|
if (GUILayout.Button("选中"))
|
|
|
|
|
|
{
|
|
|
|
|
|
uiPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(jsonData.path);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.ObjectField(AssetDatabase.LoadAssetAtPath<GameObject>(jsonData.path),
|
|
|
|
|
|
typeof(GameObject), true);
|
|
|
|
|
|
EditorGUILayout.ObjectField(AssetDatabase.LoadAssetAtPath<TextAsset>(scriptPath),
|
|
|
|
|
|
typeof(TextAsset), true);
|
|
|
|
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
|
|
GUI.color = defaultColor;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
EditorGUILayout.EndScrollView();
|
|
|
|
|
|
_scroll3 = EditorGUILayout.BeginScrollView(_scroll3, "box", GUILayout.Width(position.width * 0.6f - 6));
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorGUILayout.HelpBox("UI操作", MessageType.Info);
|
|
|
|
|
|
uiPrefab = EditorGUILayout.ObjectField("UI预制体", uiPrefab, typeof(GameObject), true) as GameObject;
|
|
|
|
|
|
if (uiPrefab != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_uiName = uiPrefab.name;
|
|
|
|
|
|
var uiScriptPath = GetUIScript(_uiName);
|
|
|
|
|
|
if (string.IsNullOrEmpty(uiScriptPath))
|
|
|
|
|
|
{
|
2025-09-24 17:16:12 +08:00
|
|
|
|
if (string.IsNullOrEmpty(_saveUIPath))
|
|
|
|
|
|
{
|
|
|
|
|
|
_saveUIPath = $"Assets/Domain/{_domainNames[_domainIndex]}/HotUpdate/UI";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (GUILayout.Button($"选择创建路径:{_saveUIPath}"))
|
2025-09-23 11:18:38 +08:00
|
|
|
|
{
|
2025-09-24 17:16:12 +08:00
|
|
|
|
var newPath = EditorUtility.OpenFolderPanel("UI生成路径", _saveUIPath, "");
|
|
|
|
|
|
_saveUIPath = newPath.Replace(Application.dataPath, "Assets");
|
|
|
|
|
|
EditorPrefs.SetString(nameof(_saveUIPath), _saveUIPath);
|
2025-09-23 11:18:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (uiPrefab != null)
|
|
|
|
|
|
{
|
2025-09-24 17:16:12 +08:00
|
|
|
|
EditorGUILayout.TextField("UI生成路径", $"{_saveUIPath}/{_uiName}.cs");
|
2025-09-23 11:18:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_isWindow = EditorGUILayout.Toggle("是否为窗口", _isWindow);
|
|
|
|
|
|
_layer = (UILayer)EditorGUILayout.EnumPopup("UILayer设置", _layer);
|
|
|
|
|
|
|
|
|
|
|
|
var defaultColor = GUI.color;
|
|
|
|
|
|
GUI.color = Color.green;
|
|
|
|
|
|
if (GUILayout.Button("创建UI"))
|
|
|
|
|
|
{
|
|
|
|
|
|
// 生成代码
|
|
|
|
|
|
string str = Regex.Replace(File.ReadAllText(_uiViewTemplate), "UIXXXView", _uiName);
|
|
|
|
|
|
UIControlData uiControlData = uiPrefab.GetComponent<UIControlData>();
|
|
|
|
|
|
if (uiControlData != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
uiControlData.CopyCodeToClipBoardPrivate();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
str = Regex.Replace(str, "//UIControlData",
|
|
|
|
|
|
uiControlData != null ? UnityEngine.GUIUtility.systemCopyBuffer : "");
|
2025-09-24 17:16:12 +08:00
|
|
|
|
string newPath = $"{_saveUIPath}/{_uiName}.cs";
|
2025-09-23 11:18:38 +08:00
|
|
|
|
File.WriteAllText(newPath, str);
|
|
|
|
|
|
|
|
|
|
|
|
var jsonData = new UIConfigJson
|
|
|
|
|
|
{
|
|
|
|
|
|
uiType = _uiName,
|
|
|
|
|
|
pathId = $"Prefabs_{uiPrefab.name}",
|
|
|
|
|
|
path = AssetDatabase.GetAssetPath(uiPrefab),
|
|
|
|
|
|
isWindow = _isWindow,
|
|
|
|
|
|
uiLayer = _layer,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
_uiJsonDatas.Add(_uiName, jsonData);
|
|
|
|
|
|
_uiNames.Add(_uiName, newPath);
|
|
|
|
|
|
SaveJson();
|
|
|
|
|
|
|
|
|
|
|
|
// 生成UIType
|
|
|
|
|
|
// var newStr = Regex.Replace(File.ReadAllText(_uiType), "Max,", $"{_uiName},\n\t\tMax,");
|
|
|
|
|
|
// File.Delete(_uiType);
|
|
|
|
|
|
// File.WriteAllText(_uiType, newStr);
|
|
|
|
|
|
//
|
|
|
|
|
|
// Debug.Log("生成成功:" + newPath);
|
|
|
|
|
|
|
|
|
|
|
|
AssetDatabase.SaveAssets();
|
|
|
|
|
|
AssetDatabase.Refresh();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GUI.color = defaultColor;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
var jsonData = GetUIJson(_uiName);
|
|
|
|
|
|
if (jsonData == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
jsonData = new UIConfigJson();
|
|
|
|
|
|
jsonData.uiType = _uiName;
|
|
|
|
|
|
_uiJsonDatas.AddOrUpdate(_uiName, jsonData);
|
|
|
|
|
|
}
|
2025-09-24 17:16:12 +08:00
|
|
|
|
|
2025-09-23 11:18:38 +08:00
|
|
|
|
if (UnityEditor.PrefabUtility.IsPartOfPrefabAsset(uiPrefab))
|
|
|
|
|
|
{
|
|
|
|
|
|
// 预制体资源就是自身
|
|
|
|
|
|
jsonData.pathId = $"Prefabs_{uiPrefab.name}";
|
|
|
|
|
|
jsonData.path = UnityEditor.AssetDatabase.GetAssetPath(uiPrefab);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.ObjectField("已创建脚本",
|
|
|
|
|
|
AssetDatabase.LoadAssetAtPath(uiScriptPath, typeof(TextAsset)), typeof(TextAsset),
|
|
|
|
|
|
true);
|
|
|
|
|
|
jsonData.isWindow = EditorGUILayout.Toggle("是否为窗口", jsonData.isWindow);
|
|
|
|
|
|
jsonData.uiLayer = (UILayer)EditorGUILayout.EnumPopup("UILayer设置", jsonData.uiLayer);
|
|
|
|
|
|
|
|
|
|
|
|
var defaultColor = GUI.color;
|
|
|
|
|
|
GUI.color = Color.green;
|
|
|
|
|
|
if (GUILayout.Button("保存设置"))
|
|
|
|
|
|
{
|
|
|
|
|
|
SaveJson();
|
|
|
|
|
|
AssetDatabase.SaveAssets();
|
|
|
|
|
|
AssetDatabase.Refresh();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GUI.color = defaultColor;
|
|
|
|
|
|
|
|
|
|
|
|
GUI.color = Color.red;
|
|
|
|
|
|
if (GUILayout.Button("删除UI脚本"))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (EditorUtility.DisplayDialog("是否确认删除",
|
|
|
|
|
|
$"请确认是否删除:\n{uiScriptPath}\n同时会清除Json,UIType中相关数据", "确定", "取消"))
|
|
|
|
|
|
{
|
|
|
|
|
|
// 清除UIConfig中的指定类型
|
|
|
|
|
|
_uiJsonDatas.Remove(_uiName);
|
|
|
|
|
|
_uiNames.Remove(_uiName);
|
|
|
|
|
|
SaveJson();
|
|
|
|
|
|
// 删除文件
|
|
|
|
|
|
File.Delete(uiScriptPath);
|
|
|
|
|
|
|
|
|
|
|
|
AssetDatabase.SaveAssets();
|
|
|
|
|
|
AssetDatabase.Refresh();
|
|
|
|
|
|
_uiNames.Remove(_uiName);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GUI.color = defaultColor;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
_uiName = "";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
EditorGUILayout.EndScrollView();
|
|
|
|
|
|
}
|
|
|
|
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.EndScrollView();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void SaveJson()
|
|
|
|
|
|
{
|
|
|
|
|
|
List<UIConfigJson> list = new List<UIConfigJson>();
|
|
|
|
|
|
foreach (var name in _uiNames.Keys)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_uiJsonDatas.TryGetValue(name, out var data))
|
|
|
|
|
|
{
|
|
|
|
|
|
list.Add(data);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_uiConfigObj.uiConfigJsons.Clear();
|
|
|
|
|
|
_uiConfigObj.uiConfigJsons = list;
|
|
|
|
|
|
EditorUtility.SetDirty(_uiConfigObj);
|
|
|
|
|
|
AssetDatabase.SaveAssets();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void TryGetPath(ref string path, string pathName, string endsWith)
|
|
|
|
|
|
{
|
|
|
|
|
|
path = PlayerPrefs.GetString(pathName);
|
|
|
|
|
|
if (!File.Exists(path))
|
|
|
|
|
|
{
|
|
|
|
|
|
string[] ids = AssetDatabase.FindAssets(pathName);
|
|
|
|
|
|
if (ids != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var id in ids)
|
|
|
|
|
|
{
|
|
|
|
|
|
var str = AssetDatabase.GUIDToAssetPath(id);
|
|
|
|
|
|
if (str.EndsWith(endsWith))
|
|
|
|
|
|
{
|
|
|
|
|
|
path = str;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private string GetUIScript(string name, bool tryFind = false)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_uiNames.TryGetValue(name, out string path))
|
|
|
|
|
|
{
|
|
|
|
|
|
return path;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!tryFind)
|
|
|
|
|
|
{
|
|
|
|
|
|
return string.Empty;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-24 17:16:12 +08:00
|
|
|
|
// if (GetUIJson(name) == null) return string.Empty;
|
2025-09-23 11:18:38 +08:00
|
|
|
|
|
|
|
|
|
|
string[] ids = AssetDatabase.FindAssets(name);
|
|
|
|
|
|
if (ids != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var id in ids)
|
|
|
|
|
|
{
|
|
|
|
|
|
var str = AssetDatabase.GUIDToAssetPath(id);
|
|
|
|
|
|
if (str.EndsWith(".cs"))
|
|
|
|
|
|
{
|
|
|
|
|
|
return str;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return string.Empty;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private UIConfigJson GetUIJson(string name)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_uiJsonDatas.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var item in _uiConfigObj.uiConfigJsons)
|
|
|
|
|
|
{
|
|
|
|
|
|
_uiJsonDatas.AddOrUpdate(item.uiType, item);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError(e);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (_uiJsonDatas.TryGetValue(name, out var jsonData))
|
|
|
|
|
|
{
|
|
|
|
|
|
return jsonData;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void DomainPathField()
|
|
|
|
|
|
{
|
2025-09-24 16:33:01 +08:00
|
|
|
|
var path = $"Assets/Domain/{_domainNames[_domainIndex]}/AddressableRes/Config/UIConfig.asset";
|
2025-09-23 11:18:38 +08:00
|
|
|
|
|
|
|
|
|
|
if (_uiConfigObj == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_uiConfigObj = (UIConfig)AssetDatabase.LoadAssetAtPath(path, typeof(UIConfig));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (_uiConfigObj == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError($"在{path}中未找到UIConfig");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void PathField(string name, ref string path, string pathName, string endsWith)
|
|
|
|
|
|
{
|
|
|
|
|
|
var obj = EditorGUILayout.ObjectField(name, AssetDatabase.LoadAssetAtPath(path, typeof(TextAsset)),
|
|
|
|
|
|
typeof(TextAsset), true);
|
|
|
|
|
|
if (obj != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var newPath = AssetDatabase.GetAssetPath(obj);
|
|
|
|
|
|
if (newPath.EndsWith(endsWith) && !newPath.Equals(path))
|
|
|
|
|
|
{
|
|
|
|
|
|
path = newPath;
|
|
|
|
|
|
PlayerPrefs.SetString(pathName, path);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static class ReflectionHelper
|
|
|
|
|
|
{
|
|
|
|
|
|
public static IEnumerable<T> CreateAllInstancesOf<T>()
|
|
|
|
|
|
{
|
|
|
|
|
|
return typeof(ReflectionHelper).Assembly.GetTypes() //获取当前类库下所有类型
|
|
|
|
|
|
.Where(t => typeof(T).IsAssignableFrom(t)) //获取间接或直接继承t的所有类型
|
|
|
|
|
|
.Where(t => !t.IsAbstract && t.IsClass) //获取非抽象类 排除接口继承
|
|
|
|
|
|
.Select(t => (T)Activator.CreateInstance(t)); //创造实例,并返回结果(项目需求,可删除)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 新增方法:专门用于查找UIView类型的所有实现类
|
|
|
|
|
|
public static IEnumerable<Type> GetAllUIViewTypes(string domainName)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 查找所有程序集中的UIView类型实现
|
|
|
|
|
|
var uiviewType = typeof(UIView);
|
|
|
|
|
|
List<Type> result = new List<Type>();
|
|
|
|
|
|
// 尝试获取指定名称的程序集
|
|
|
|
|
|
var targetAssembly = AppDomain.CurrentDomain.GetAssemblies()
|
|
|
|
|
|
.FirstOrDefault(assembly => assembly.GetName().Name == $"HotUpdate_{domainName}");
|
|
|
|
|
|
|
|
|
|
|
|
if (targetAssembly == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError($"未找到名为HotUpdate_{domainName}的程序集");
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
2025-09-24 17:16:12 +08:00
|
|
|
|
|
2025-09-23 11:18:38 +08:00
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
result.AddRange(targetAssembly.GetTypes()
|
|
|
|
|
|
.Where(t => uiviewType.IsAssignableFrom(t))
|
|
|
|
|
|
.Where(t => !t.IsAbstract && t.IsClass));
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 忽略无法访问的程序集
|
|
|
|
|
|
}
|
|
|
|
|
|
// 遍历所有已加载的程序集
|
|
|
|
|
|
// foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
|
|
|
|
|
// {
|
|
|
|
|
|
// try
|
|
|
|
|
|
// {
|
|
|
|
|
|
// result.AddRange(assembly.GetTypes()
|
|
|
|
|
|
// .Where(t => uiviewType.IsAssignableFrom(t))
|
|
|
|
|
|
// .Where(t => !t.IsAbstract && t.IsClass));
|
|
|
|
|
|
// }
|
|
|
|
|
|
// catch (Exception)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// // 忽略无法访问的程序集
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|