[update] 对 Hybrid Global Settings 工作流稍作完善
1. 将 hybrid settings 转移到 ProjectSettings 文件夹 2. 将 hybrid Settings 绘制到 编辑器 ProjectSettings 面板 3. 添加 文档 、Presets、Reset 功能 4. 在 installer 添加 settings 入口 5. 在 菜单栏添加 setting 入口,关于我们、以及文档入口main
parent
47da01204b
commit
caa0281e18
|
@ -1,12 +1,7 @@
|
||||||
using HybridCLR.Editor.Link;
|
using HybridCLR.Editor.Link;
|
||||||
using HybridCLR.Editor.Meta;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
@ -56,6 +51,7 @@ namespace HybridCLR.Editor.Commands
|
||||||
Debug.Log($"[LinkGeneratorCommand] hotfix assembly count:{hotfixAssembles.Count}, ref type count:{refTypes.Count} output:{Application.dataPath}/{ls.outputLinkFile}");
|
Debug.Log($"[LinkGeneratorCommand] hotfix assembly count:{hotfixAssembles.Count}, ref type count:{refTypes.Count} output:{Application.dataPath}/{ls.outputLinkFile}");
|
||||||
var linkXmlWriter = new LinkXmlWriter();
|
var linkXmlWriter = new LinkXmlWriter();
|
||||||
linkXmlWriter.Write($"{Application.dataPath}/{ls.outputLinkFile}", refTypes);
|
linkXmlWriter.Write($"{Application.dataPath}/{ls.outputLinkFile}", refTypes);
|
||||||
|
AssetDatabase.Refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Reflection;
|
|
||||||
using UnityEditorInternal;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
[CreateAssetMenu(fileName = "HybridCLRGlobalSettings", menuName = "HybridCLR/GlobalSettings")]
|
|
||||||
public class HybridCLRGlobalSettings : ScriptableObject
|
|
||||||
{
|
|
||||||
[Header("开启HybridCLR插件")]
|
|
||||||
public bool enable = true;
|
|
||||||
|
|
||||||
[Header("从gitee clone插件代码")]
|
|
||||||
public bool cloneFromGitee = true; // false 则从github上拉取
|
|
||||||
|
|
||||||
[Header("热更新Assembly Definition Modules")]
|
|
||||||
public AssemblyDefinitionAsset[] hotUpdateAssemblyDefinitions;
|
|
||||||
|
|
||||||
[Header("热更新dlls")]
|
|
||||||
public string[] hotUpdateAssemblies;
|
|
||||||
|
|
||||||
[Header("自动扫描生成的link.xml路径")]
|
|
||||||
public string outputLinkFile = "HybridCLR/link.xml";
|
|
||||||
|
|
||||||
[Header("自动扫描生成的AOTGenericReferences.cs路径")]
|
|
||||||
public string outputAOTGenericReferenceFile = "Main/AOTGenericReferences.cs";
|
|
||||||
|
|
||||||
[Header("AOT泛型实例化搜索迭代次数")]
|
|
||||||
public int maxGenericReferenceIteration = 4;
|
|
||||||
|
|
||||||
[Header("预留MonoPInvokeCallbackAttribute函数个数")]
|
|
||||||
public int ReversePInvokeWrapperCount = 10;
|
|
||||||
|
|
||||||
[Header("MethodBridge泛型搜索迭代次数")]
|
|
||||||
public int maxMethodBridgeGenericIteration = 4;
|
|
||||||
}
|
|
|
@ -1,10 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Reflection;
|
||||||
using System.IO;
|
using UnityEditor;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEditor ;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,6 +17,19 @@ namespace HybridCLR.Editor.Installer
|
||||||
|
|
||||||
private void OnGUI()
|
private void OnGUI()
|
||||||
{
|
{
|
||||||
|
var rect = new Rect
|
||||||
|
{
|
||||||
|
x = EditorGUIUtility.currentViewWidth - 24,
|
||||||
|
y = 5,
|
||||||
|
width = 24,
|
||||||
|
height = 24
|
||||||
|
};
|
||||||
|
var content = EditorGUIUtility.IconContent("Settings");
|
||||||
|
content.tooltip = "点击打开HybridCLR Settings";
|
||||||
|
if (GUI.Button(rect, content, GUI.skin.GetStyle("IconButton")))
|
||||||
|
{
|
||||||
|
SettingsService.OpenProjectSettings("Project/HybridCLR Settings");
|
||||||
|
}
|
||||||
string minCompatibleVersion = m_Controller.GetMinCompatibleVersion(m_Controller.Il2CppBranch);
|
string minCompatibleVersion = m_Controller.GetMinCompatibleVersion(m_Controller.Il2CppBranch);
|
||||||
GUI.enabled = true;
|
GUI.enabled = true;
|
||||||
GUILayout.Space(10f);
|
GUILayout.Space(10f);
|
||||||
|
@ -32,6 +41,7 @@ namespace HybridCLR.Editor.Installer
|
||||||
+ $"由于安装HybridCLR时需要从il2cpp_plus兼容版本{m_Controller.Il2CppBranch}(而不是你项目版本)拷贝il2cpp目录,\n"
|
+ $"由于安装HybridCLR时需要从il2cpp_plus兼容版本{m_Controller.Il2CppBranch}(而不是你项目版本)拷贝il2cpp目录,\n"
|
||||||
+ $"你必须同时安装兼容版本 {m_Controller.Il2CppBranch} 才能完成安装", EditorStyles.wordWrappedLabel);
|
+ $"你必须同时安装兼容版本 {m_Controller.Il2CppBranch} 才能完成安装", EditorStyles.wordWrappedLabel);
|
||||||
EditorGUILayout.LabelField("==============================================");
|
EditorGUILayout.LabelField("==============================================");
|
||||||
|
|
||||||
GUILayout.Space(10f);
|
GUILayout.Space(10f);
|
||||||
|
|
||||||
EditorGUILayout.BeginVertical("box");
|
EditorGUILayout.BeginVertical("box");
|
||||||
|
@ -79,29 +89,29 @@ namespace HybridCLR.Editor.Installer
|
||||||
switch (err)
|
switch (err)
|
||||||
{
|
{
|
||||||
case InstallErrorCode.Ok:
|
case InstallErrorCode.Ok:
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case InstallErrorCode.Il2CppInstallPathNotExists:
|
case InstallErrorCode.Il2CppInstallPathNotExists:
|
||||||
{
|
{
|
||||||
EditorGUILayout.HelpBox("li2cpp 路径不存在", MessageType.Error);
|
EditorGUILayout.HelpBox("li2cpp 路径不存在", MessageType.Error);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case InstallErrorCode.InvalidUnityInstallPath:
|
case InstallErrorCode.InvalidUnityInstallPath:
|
||||||
{
|
{
|
||||||
EditorGUILayout.HelpBox($"Unity安装目录必须包含版本号,否则无法识别版本", MessageType.Error);
|
EditorGUILayout.HelpBox($"Unity安装目录必须包含版本号,否则无法识别版本", MessageType.Error);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case InstallErrorCode.Il2CppInstallPathNotMatchIl2CppBranch:
|
case InstallErrorCode.Il2CppInstallPathNotMatchIl2CppBranch:
|
||||||
{
|
{
|
||||||
EditorGUILayout.HelpBox($"il2cpp 版本不兼容,最小版本为 {m_Controller.GetMinCompatibleVersion(m_Controller.Il2CppBranch)}", MessageType.Error);
|
EditorGUILayout.HelpBox($"il2cpp 版本不兼容,最小版本为 {m_Controller.GetMinCompatibleVersion(m_Controller.Il2CppBranch)}", MessageType.Error);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case InstallErrorCode.NotIl2CppPath:
|
case InstallErrorCode.NotIl2CppPath:
|
||||||
{
|
{
|
||||||
EditorGUILayout.HelpBox($"当前选择的路径不是il2cpp目录(必须类似 xxx/il2cpp)", MessageType.Error);
|
EditorGUILayout.HelpBox($"当前选择的路径不是il2cpp目录(必须类似 xxx/il2cpp)", MessageType.Error);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: throw new Exception($"not support {err}");
|
default: throw new Exception($"not support {err}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3708ee1d4035cb14abaa4d64a8ec8148
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,35 @@
|
||||||
|
using UnityEditorInternal;
|
||||||
|
using UnityEngine;
|
||||||
|
namespace HybridCLR.Editor
|
||||||
|
{
|
||||||
|
[FilePath("ProjectSettings/HybridCLRGlobalSettings.asset")]
|
||||||
|
public class HybridCLRGlobalSettings : ScriptableSingleton<HybridCLRGlobalSettings>
|
||||||
|
{
|
||||||
|
[Header("开启HybridCLR插件")]
|
||||||
|
public bool enable = true;
|
||||||
|
|
||||||
|
[Header("从gitee clone插件代码")]
|
||||||
|
public bool cloneFromGitee = true; // false 则从github上拉取
|
||||||
|
|
||||||
|
[Header("热更新Assembly Definition Modules")]
|
||||||
|
public AssemblyDefinitionAsset[] hotUpdateAssemblyDefinitions;
|
||||||
|
|
||||||
|
[Header("热更新dlls")]
|
||||||
|
public string[] hotUpdateAssemblies;
|
||||||
|
|
||||||
|
[Header("自动扫描生成的link.xml路径")]
|
||||||
|
public string outputLinkFile = "HybridCLRData/Generated/link.xml";
|
||||||
|
|
||||||
|
[Header("自动扫描生成的AOTGenericReferences.cs路径")]
|
||||||
|
public string outputAOTGenericReferenceFile = "HybridCLRData/Generated/AOTGenericReferences.cs";
|
||||||
|
|
||||||
|
[Header("AOT泛型实例化搜索迭代次数")]
|
||||||
|
public int maxGenericReferenceIteration = 4;
|
||||||
|
|
||||||
|
[Header("预留MonoPInvokeCallbackAttribute函数个数")]
|
||||||
|
public int ReversePInvokeWrapperCount = 10;
|
||||||
|
|
||||||
|
[Header("MethodBridge泛型搜索迭代次数")]
|
||||||
|
public int maxMethodBridgeGenericIteration = 4;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEditor.Presets;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UIElements;
|
||||||
|
namespace HybridCLR.Editor
|
||||||
|
{
|
||||||
|
public class HybridCLRSettingsProvider : SettingsProvider
|
||||||
|
{
|
||||||
|
private static SerializedObject m_SerializedObject;
|
||||||
|
private SerializedProperty m_Enable;
|
||||||
|
private SerializedProperty m_CloneFromGitee;
|
||||||
|
private SerializedProperty m_HotUpdateAssemblyDefinitions;
|
||||||
|
private SerializedProperty m_HotUpdateAssemblies;
|
||||||
|
private SerializedProperty m_OutputLinkFile;
|
||||||
|
private SerializedProperty m_OutputAOTGenericReferenceFile;
|
||||||
|
private SerializedProperty m_MaxGenericReferenceIteration;
|
||||||
|
private SerializedProperty m_ReversePInvokeWrapperCount;
|
||||||
|
private SerializedProperty m_MaxMethodBridgeGenericIteration;
|
||||||
|
private GUIStyle buttonStyle;
|
||||||
|
public HybridCLRSettingsProvider() : base("Project/HybridCLR Settings", SettingsScope.Project) { }
|
||||||
|
public override void OnActivate(string searchContext, VisualElement rootElement)
|
||||||
|
{
|
||||||
|
HybridCLRGlobalSettings.Instance.Save();
|
||||||
|
var setting = HybridCLRGlobalSettings.Instance;
|
||||||
|
setting.hideFlags &= ~HideFlags.NotEditable;
|
||||||
|
m_SerializedObject ??= new SerializedObject(setting);
|
||||||
|
m_Enable = m_SerializedObject.FindProperty("enable");
|
||||||
|
m_CloneFromGitee = m_SerializedObject.FindProperty("cloneFromGitee");
|
||||||
|
m_HotUpdateAssemblyDefinitions = m_SerializedObject.FindProperty("hotUpdateAssemblyDefinitions");
|
||||||
|
m_HotUpdateAssemblies = m_SerializedObject.FindProperty("hotUpdateAssemblies");
|
||||||
|
m_OutputLinkFile = m_SerializedObject.FindProperty("outputLinkFile");
|
||||||
|
m_OutputAOTGenericReferenceFile = m_SerializedObject.FindProperty("outputAOTGenericReferenceFile");
|
||||||
|
m_MaxGenericReferenceIteration = m_SerializedObject.FindProperty("maxGenericReferenceIteration");
|
||||||
|
m_ReversePInvokeWrapperCount = m_SerializedObject.FindProperty("ReversePInvokeWrapperCount");
|
||||||
|
m_MaxMethodBridgeGenericIteration = m_SerializedObject.FindProperty("maxMethodBridgeGenericIteration");
|
||||||
|
}
|
||||||
|
public override void OnTitleBarGUI()
|
||||||
|
{
|
||||||
|
base.OnTitleBarGUI();
|
||||||
|
var rect = GUILayoutUtility.GetLastRect();
|
||||||
|
buttonStyle ??= GUI.skin.GetStyle("IconButton");
|
||||||
|
|
||||||
|
#region 绘制官方网站跳转按钮
|
||||||
|
var w = rect.x + rect.width;
|
||||||
|
rect.x = w - 58;
|
||||||
|
rect.y += 6;
|
||||||
|
rect.width = rect.height = 18;
|
||||||
|
var content = EditorGUIUtility.IconContent("_Help");
|
||||||
|
content.tooltip = "点击访问 HybridCLR 官方文档";
|
||||||
|
if (GUI.Button(rect, content, buttonStyle))
|
||||||
|
{
|
||||||
|
Application.OpenURL("https://focus-creative-games.github.io/hybridclr/");
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 绘制 Preset
|
||||||
|
rect.x += 19;
|
||||||
|
content = EditorGUIUtility.IconContent("Preset.Context");
|
||||||
|
content.tooltip = "点击存储或加载 Preset .";
|
||||||
|
if (GUI.Button(rect, content, buttonStyle))
|
||||||
|
{
|
||||||
|
var target = HybridCLRGlobalSettings.Instance;
|
||||||
|
var receiver = ScriptableObject.CreateInstance<SettingsPresetReceiver>();
|
||||||
|
receiver.Init(target);
|
||||||
|
PresetSelector.ShowSelector(target, null, true, receiver);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
#region 绘制 Reset
|
||||||
|
rect.x += 19;
|
||||||
|
content = EditorGUIUtility.IconContent("_Popup");
|
||||||
|
content.tooltip = "Reset";
|
||||||
|
if (GUI.Button(rect, content, buttonStyle))
|
||||||
|
{
|
||||||
|
GenericMenu menu = new GenericMenu();
|
||||||
|
menu.AddItem(new GUIContent("Reset"), false, () =>
|
||||||
|
{
|
||||||
|
Undo.RecordObject(HybridCLRGlobalSettings.Instance, "Capture Value for Reset");
|
||||||
|
var dv = ScriptableObject.CreateInstance<HybridCLRGlobalSettings>();
|
||||||
|
var json = EditorJsonUtility.ToJson(dv);
|
||||||
|
EditorJsonUtility.FromJsonOverwrite(json,HybridCLRGlobalSettings.Instance);
|
||||||
|
HybridCLRGlobalSettings.Instance.Save();
|
||||||
|
});
|
||||||
|
menu.ShowAsContext();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
public override void OnGUI(string searchContext)
|
||||||
|
{
|
||||||
|
using (CreateSettingsWindowGUIScope())
|
||||||
|
{
|
||||||
|
if (m_SerializedObject == null || !m_SerializedObject.targetObject)
|
||||||
|
{
|
||||||
|
m_SerializedObject = null;
|
||||||
|
m_SerializedObject = new SerializedObject(HybridCLRGlobalSettings.Instance);
|
||||||
|
}
|
||||||
|
m_SerializedObject.Update();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
EditorGUILayout.PropertyField(m_Enable);
|
||||||
|
EditorGUILayout.PropertyField(m_CloneFromGitee);
|
||||||
|
EditorGUILayout.PropertyField(m_HotUpdateAssemblyDefinitions);
|
||||||
|
EditorGUILayout.PropertyField(m_HotUpdateAssemblies);
|
||||||
|
EditorGUILayout.PropertyField(m_OutputLinkFile);
|
||||||
|
EditorGUILayout.PropertyField(m_OutputAOTGenericReferenceFile);
|
||||||
|
EditorGUILayout.PropertyField(m_MaxGenericReferenceIteration);
|
||||||
|
EditorGUILayout.PropertyField(m_ReversePInvokeWrapperCount);
|
||||||
|
EditorGUILayout.PropertyField(m_MaxMethodBridgeGenericIteration);
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
m_SerializedObject.ApplyModifiedProperties();
|
||||||
|
HybridCLRGlobalSettings.Instance.Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private IDisposable CreateSettingsWindowGUIScope()
|
||||||
|
{
|
||||||
|
var unityEditorAssembly = Assembly.GetAssembly(typeof(EditorWindow));
|
||||||
|
var type = unityEditorAssembly.GetType("UnityEditor.SettingsWindow+GUIScope");
|
||||||
|
return Activator.CreateInstance(type) as IDisposable;
|
||||||
|
}
|
||||||
|
public override void OnDeactivate()
|
||||||
|
{
|
||||||
|
base.OnDeactivate();
|
||||||
|
HybridCLRGlobalSettings.Instance.Save();
|
||||||
|
m_SerializedObject = null;
|
||||||
|
}
|
||||||
|
[SettingsProvider]
|
||||||
|
public static SettingsProvider CreateMyCustomSettingsProvider()
|
||||||
|
{
|
||||||
|
if (HybridCLRGlobalSettings.Instance)
|
||||||
|
{
|
||||||
|
var provider = new HybridCLRSettingsProvider
|
||||||
|
{
|
||||||
|
keywords = GetSearchKeywordsFromSerializedObject(m_SerializedObject ??= new SerializedObject(HybridCLRGlobalSettings.Instance))
|
||||||
|
};
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d2bd1694fedc8b54c88bb9f6c67907d3
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,13 @@
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public static class MenuProvider
|
||||||
|
{
|
||||||
|
[MenuItem("HybridCLR/Settings", priority = 200)]
|
||||||
|
public static void OpenSettings() => SettingsService.OpenProjectSettings("Project/HybridCLR Settings");
|
||||||
|
[MenuItem("HybridCLR/About us", priority = 400)]
|
||||||
|
public static void AboutUs() => Application.OpenURL("https://focus-creative-games.github.io/hybridclr/about/");
|
||||||
|
|
||||||
|
[MenuItem("HybridCLR/Documents", priority = 399)]
|
||||||
|
public static void OpenDoc() => Application.OpenURL("https://focus-creative-games.github.io/hybridclr/");
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a475a5f281298b84da32373694704c68
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,94 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEditorInternal;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace HybridCLR.Editor
|
||||||
|
{
|
||||||
|
public class ScriptableSingleton<T> : ScriptableObject where T : ScriptableObject
|
||||||
|
{
|
||||||
|
private static T s_Instance;
|
||||||
|
public static T Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!s_Instance)
|
||||||
|
{
|
||||||
|
CreateAndLoad();
|
||||||
|
}
|
||||||
|
return s_Instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static void CreateAndLoad()
|
||||||
|
{
|
||||||
|
string filePath = GetFilePath();
|
||||||
|
if (!string.IsNullOrEmpty(filePath))
|
||||||
|
{
|
||||||
|
var arr = InternalEditorUtility.LoadSerializedFileAndForget(filePath);
|
||||||
|
s_Instance = arr.Length > 0 ? arr[0] as T : CreateInstance<T>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError($"{nameof(ScriptableSingleton<T>)}: 请指定单例存档路径! ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Save(bool saveAsText=true)
|
||||||
|
{
|
||||||
|
if (!s_Instance)
|
||||||
|
{
|
||||||
|
Debug.LogError("Cannot save ScriptableSingleton: no instance!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string filePath = GetFilePath();
|
||||||
|
if (!string.IsNullOrEmpty(filePath))
|
||||||
|
{
|
||||||
|
string directoryName = Path.GetDirectoryName(filePath);
|
||||||
|
if (!Directory.Exists(directoryName))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(directoryName);
|
||||||
|
}
|
||||||
|
UnityEngine.Object[] obj = new T[1] { s_Instance };
|
||||||
|
InternalEditorUtility.SaveToSerializedFileAndForget(obj, filePath, saveAsText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected static string GetFilePath()
|
||||||
|
{
|
||||||
|
Type typeFromHandle = typeof(T);
|
||||||
|
object[] customAttributes = typeFromHandle.GetCustomAttributes(inherit: true);
|
||||||
|
object[] array = customAttributes;
|
||||||
|
foreach (object obj in array)
|
||||||
|
{
|
||||||
|
if (obj is FilePathAttribute)
|
||||||
|
{
|
||||||
|
FilePathAttribute filePathAttribute = obj as FilePathAttribute;
|
||||||
|
return filePathAttribute.filepath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
|
public class FilePathAttribute : Attribute
|
||||||
|
{
|
||||||
|
internal string filepath;
|
||||||
|
/// <summary>
|
||||||
|
/// 单例存放路径
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">相对 Project 路径</param>
|
||||||
|
public FilePathAttribute(string path)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(path))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Invalid relative path (it is empty)");
|
||||||
|
}
|
||||||
|
if (path[0] == '/')
|
||||||
|
{
|
||||||
|
path = path.Substring(1);
|
||||||
|
}
|
||||||
|
filepath = path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 851c44a8da67a9742a7ea68815383f27
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,37 @@
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEditor.Presets;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace HybridCLR.Editor
|
||||||
|
{
|
||||||
|
public class SettingsPresetReceiver : PresetSelectorReceiver
|
||||||
|
{
|
||||||
|
private Object m_Target;
|
||||||
|
private Preset m_InitialValue;
|
||||||
|
|
||||||
|
internal void Init(Object target)
|
||||||
|
{
|
||||||
|
m_Target = target;
|
||||||
|
m_InitialValue = new Preset(target);
|
||||||
|
}
|
||||||
|
public override void OnSelectionChanged(Preset selection)
|
||||||
|
{
|
||||||
|
if (selection != null)
|
||||||
|
{
|
||||||
|
Undo.RecordObject(m_Target, "Apply Preset " + selection.name);
|
||||||
|
selection.ApplyTo(m_Target);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Undo.RecordObject(m_Target, "Cancel Preset");
|
||||||
|
m_InitialValue.ApplyTo(m_Target);
|
||||||
|
}
|
||||||
|
SettingsService.RepaintAllSettingsWindow();
|
||||||
|
}
|
||||||
|
public override void OnSelectionClosed(Preset selection)
|
||||||
|
{
|
||||||
|
OnSelectionChanged(selection);
|
||||||
|
Object.DestroyImmediate(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d8373e0cb30c4894db7cd4d0b77a7a48
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -2,17 +2,16 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEditorInternal;
|
using UnityEditorInternal;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
|
||||||
namespace HybridCLR.Editor
|
namespace HybridCLR.Editor
|
||||||
{
|
{
|
||||||
public static class SettingsUtil
|
public static class SettingsUtil
|
||||||
{
|
{
|
||||||
public static bool Enable => GlobalSettings.enable;
|
public static bool Enable => HybridCLRGlobalSettings.Instance.enable;
|
||||||
|
|
||||||
public static string PackageName { get; } = "com.focus-creative-games.hybridclr_unity";
|
public static string PackageName { get; } = "com.focus-creative-games.hybridclr_unity";
|
||||||
|
|
||||||
|
@ -64,7 +63,7 @@ namespace HybridCLR.Editor
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var gs = GlobalSettings;
|
var gs = HybridCLRGlobalSettings.Instance;
|
||||||
var hotfixAssNames = (gs.hotUpdateAssemblyDefinitions ?? Array.Empty<AssemblyDefinitionAsset>()).Select(ad => JsonUtility.FromJson<AssemblyDefinitionData>(ad.text));
|
var hotfixAssNames = (gs.hotUpdateAssemblyDefinitions ?? Array.Empty<AssemblyDefinitionAsset>()).Select(ad => JsonUtility.FromJson<AssemblyDefinitionData>(ad.text));
|
||||||
|
|
||||||
var hotfixAssembles = new List<string>();
|
var hotfixAssembles = new List<string>();
|
||||||
|
@ -76,35 +75,8 @@ namespace HybridCLR.Editor
|
||||||
return hotfixAssembles.ToList();
|
return hotfixAssembles.ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<string> HotUpdateAssemblyFiles => HotUpdateAssemblyNames.Select(dll => dll + ".dll").ToList();
|
public static List<string> HotUpdateAssemblyFiles => HotUpdateAssemblyNames.Select(dll => dll + ".dll").ToList();
|
||||||
|
|
||||||
public static T GetSingletonAssets<T>() where T : ScriptableObject, new()
|
public static HybridCLRGlobalSettings GlobalSettings => HybridCLRGlobalSettings.Instance;
|
||||||
{
|
|
||||||
string assetType = typeof(T).Name;
|
|
||||||
string[] globalAssetPaths = AssetDatabase.FindAssets($"t:{assetType}");
|
|
||||||
if (globalAssetPaths == null || globalAssetPaths.Length == 0)
|
|
||||||
{
|
|
||||||
string defaultNewAssetPath = $"Assets/{typeof(T).Name}.asset";
|
|
||||||
Debug.LogWarning($"没找到 {assetType} asset,自动创建创建一个:{defaultNewAssetPath}.");
|
|
||||||
|
|
||||||
var newAsset = ScriptableObject.CreateInstance<T>();
|
|
||||||
AssetDatabase.CreateAsset(newAsset, defaultNewAssetPath);
|
|
||||||
return newAsset;
|
|
||||||
}
|
|
||||||
if (globalAssetPaths.Length > 1)
|
|
||||||
{
|
|
||||||
foreach (var assetPath in globalAssetPaths)
|
|
||||||
{
|
|
||||||
Debug.LogError($"不能有多个 {assetType}. 路径: {AssetDatabase.GUIDToAssetPath(assetPath)}");
|
|
||||||
}
|
|
||||||
throw new Exception($"不能有多个 {assetType}");
|
|
||||||
}
|
|
||||||
string assPath = AssetDatabase.GUIDToAssetPath(globalAssetPaths[0]);
|
|
||||||
//Debug.Log($"find asset:{assPath}");
|
|
||||||
return AssetDatabase.LoadAssetAtPath<T>(assPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HybridCLRGlobalSettings GlobalSettings => GetSingletonAssets<HybridCLRGlobalSettings>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue