mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
Init TEngine4.0.0
Init TEngine4.0.0
This commit is contained in:
8
UnityProject/Assets/TEngine/Editor/DefineSymbols.meta
Normal file
8
UnityProject/Assets/TEngine/Editor/DefineSymbols.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d9e289b71d5448498e7ee52d1da52d8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,172 @@
|
||||
using UnityEditor;
|
||||
|
||||
namespace TEngine.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 日志脚本宏定义操作类。
|
||||
/// </summary>
|
||||
public static class LogScriptingDefineSymbols
|
||||
{
|
||||
private const string EnableLogScriptingDefineSymbol = "ENABLE_LOG";
|
||||
private const string EnableDebugAndAboveLogScriptingDefineSymbol = "ENABLE_DEBUG_AND_ABOVE_LOG";
|
||||
private const string EnableInfoAndAboveLogScriptingDefineSymbol = "ENABLE_INFO_AND_ABOVE_LOG";
|
||||
private const string EnableWarningAndAboveLogScriptingDefineSymbol = "ENABLE_WARNING_AND_ABOVE_LOG";
|
||||
private const string EnableErrorAndAboveLogScriptingDefineSymbol = "ENABLE_ERROR_AND_ABOVE_LOG";
|
||||
private const string EnableFatalAndAboveLogScriptingDefineSymbol = "ENABLE_FATAL_AND_ABOVE_LOG";
|
||||
private const string EnableDebugLogScriptingDefineSymbol = "ENABLE_DEBUG_LOG";
|
||||
private const string EnableInfoLogScriptingDefineSymbol = "ENABLE_INFO_LOG";
|
||||
private const string EnableWarningLogScriptingDefineSymbol = "ENABLE_WARNING_LOG";
|
||||
private const string EnableErrorLogScriptingDefineSymbol = "ENABLE_ERROR_LOG";
|
||||
private const string EnableFatalLogScriptingDefineSymbol = "ENABLE_FATAL_LOG";
|
||||
|
||||
private static readonly string[] AboveLogScriptingDefineSymbols = new string[]
|
||||
{
|
||||
EnableDebugAndAboveLogScriptingDefineSymbol,
|
||||
EnableInfoAndAboveLogScriptingDefineSymbol,
|
||||
EnableWarningAndAboveLogScriptingDefineSymbol,
|
||||
EnableErrorAndAboveLogScriptingDefineSymbol,
|
||||
EnableFatalAndAboveLogScriptingDefineSymbol
|
||||
};
|
||||
|
||||
private static readonly string[] SpecifyLogScriptingDefineSymbols = new string[]
|
||||
{
|
||||
EnableDebugLogScriptingDefineSymbol,
|
||||
EnableInfoLogScriptingDefineSymbol,
|
||||
EnableWarningLogScriptingDefineSymbol,
|
||||
EnableErrorLogScriptingDefineSymbol,
|
||||
EnableFatalLogScriptingDefineSymbol
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 禁用所有日志脚本宏定义。
|
||||
/// </summary>
|
||||
[MenuItem("TEngine/Log Scripting Define Symbols/Disable All Logs", false, 30)]
|
||||
public static void DisableAllLogs()
|
||||
{
|
||||
ScriptingDefineSymbols.RemoveScriptingDefineSymbol(EnableLogScriptingDefineSymbol);
|
||||
|
||||
foreach (string specifyLogScriptingDefineSymbol in SpecifyLogScriptingDefineSymbols)
|
||||
{
|
||||
ScriptingDefineSymbols.RemoveScriptingDefineSymbol(specifyLogScriptingDefineSymbol);
|
||||
}
|
||||
|
||||
foreach (string aboveLogScriptingDefineSymbol in AboveLogScriptingDefineSymbols)
|
||||
{
|
||||
ScriptingDefineSymbols.RemoveScriptingDefineSymbol(aboveLogScriptingDefineSymbol);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开启所有日志脚本宏定义。
|
||||
/// </summary>
|
||||
[MenuItem("TEngine/Log Scripting Define Symbols/Enable All Logs", false, 31)]
|
||||
public static void EnableAllLogs()
|
||||
{
|
||||
DisableAllLogs();
|
||||
ScriptingDefineSymbols.AddScriptingDefineSymbol(EnableLogScriptingDefineSymbol);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开启调试及以上级别的日志脚本宏定义。
|
||||
/// </summary>
|
||||
[MenuItem("TEngine/Log Scripting Define Symbols/Enable Debug And Above Logs", false, 32)]
|
||||
public static void EnableDebugAndAboveLogs()
|
||||
{
|
||||
SetAboveLogScriptingDefineSymbol(EnableDebugAndAboveLogScriptingDefineSymbol);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开启信息及以上级别的日志脚本宏定义。
|
||||
/// </summary>
|
||||
[MenuItem("TEngine/Log Scripting Define Symbols/Enable Info And Above Logs", false, 33)]
|
||||
public static void EnableInfoAndAboveLogs()
|
||||
{
|
||||
SetAboveLogScriptingDefineSymbol(EnableInfoAndAboveLogScriptingDefineSymbol);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开启警告及以上级别的日志脚本宏定义。
|
||||
/// </summary>
|
||||
[MenuItem("TEngine/Log Scripting Define Symbols/Enable Warning And Above Logs", false, 34)]
|
||||
public static void EnableWarningAndAboveLogs()
|
||||
{
|
||||
SetAboveLogScriptingDefineSymbol(EnableWarningAndAboveLogScriptingDefineSymbol);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开启错误及以上级别的日志脚本宏定义。
|
||||
/// </summary>
|
||||
[MenuItem("TEngine/Log Scripting Define Symbols/Enable Error And Above Logs", false, 35)]
|
||||
public static void EnableErrorAndAboveLogs()
|
||||
{
|
||||
SetAboveLogScriptingDefineSymbol(EnableErrorAndAboveLogScriptingDefineSymbol);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开启严重错误及以上级别的日志脚本宏定义。
|
||||
/// </summary>
|
||||
[MenuItem("TEngine/Log Scripting Define Symbols/Enable Fatal And Above Logs", false, 36)]
|
||||
public static void EnableFatalAndAboveLogs()
|
||||
{
|
||||
SetAboveLogScriptingDefineSymbol(EnableFatalAndAboveLogScriptingDefineSymbol);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置日志脚本宏定义。
|
||||
/// </summary>
|
||||
/// <param name="aboveLogScriptingDefineSymbol">要设置的日志脚本宏定义。</param>
|
||||
public static void SetAboveLogScriptingDefineSymbol(string aboveLogScriptingDefineSymbol)
|
||||
{
|
||||
if (string.IsNullOrEmpty(aboveLogScriptingDefineSymbol))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string i in AboveLogScriptingDefineSymbols)
|
||||
{
|
||||
if (i == aboveLogScriptingDefineSymbol)
|
||||
{
|
||||
DisableAllLogs();
|
||||
ScriptingDefineSymbols.AddScriptingDefineSymbol(aboveLogScriptingDefineSymbol);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置日志脚本宏定义。
|
||||
/// </summary>
|
||||
/// <param name="specifyLogScriptingDefineSymbols">要设置的日志脚本宏定义。</param>
|
||||
public static void SetSpecifyLogScriptingDefineSymbols(string[] specifyLogScriptingDefineSymbols)
|
||||
{
|
||||
if (specifyLogScriptingDefineSymbols == null || specifyLogScriptingDefineSymbols.Length <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool removed = false;
|
||||
foreach (string specifyLogScriptingDefineSymbol in specifyLogScriptingDefineSymbols)
|
||||
{
|
||||
if (string.IsNullOrEmpty(specifyLogScriptingDefineSymbol))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (string i in SpecifyLogScriptingDefineSymbols)
|
||||
{
|
||||
if (i == specifyLogScriptingDefineSymbol)
|
||||
{
|
||||
if (!removed)
|
||||
{
|
||||
removed = true;
|
||||
DisableAllLogs();
|
||||
}
|
||||
|
||||
ScriptingDefineSymbols.AddScriptingDefineSymbol(specifyLogScriptingDefineSymbol);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a7f38582e7109d344bd714fb29e2cd97
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,44 @@
|
||||
using UnityEditor;
|
||||
|
||||
namespace TEngine.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Profiler分析器宏定义操作类。
|
||||
/// </summary>
|
||||
public class ProfilerDefineSymbols
|
||||
{
|
||||
private const string EnableFirstProfiler = "FIRST_PROFILER";
|
||||
private const string EnableDinProFiler = "T_PROFILER";
|
||||
|
||||
private static readonly string[] AllProfilerDefineSymbols = new string[]
|
||||
{
|
||||
EnableFirstProfiler,
|
||||
EnableDinProFiler,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 禁用所有日志脚本宏定义。
|
||||
/// </summary>
|
||||
[MenuItem("TEngine/Profiler Define Symbols/Disable All Profiler", false, 30)]
|
||||
public static void DisableAllLogs()
|
||||
{
|
||||
foreach (string aboveLogScriptingDefineSymbol in AllProfilerDefineSymbols)
|
||||
{
|
||||
ScriptingDefineSymbols.RemoveScriptingDefineSymbol(aboveLogScriptingDefineSymbol);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开启所有日志脚本宏定义。
|
||||
/// </summary>
|
||||
[MenuItem("TEngine/Profiler Define Symbols/Enable All Profiler", false, 31)]
|
||||
public static void EnableAllLogs()
|
||||
{
|
||||
DisableAllLogs();
|
||||
foreach (string aboveLogScriptingDefineSymbol in AllProfilerDefineSymbols)
|
||||
{
|
||||
ScriptingDefineSymbols.AddScriptingDefineSymbol(aboveLogScriptingDefineSymbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1503a11737564a498b65d84dc90758c2
|
||||
timeCreated: 1694790771
|
@@ -0,0 +1,150 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
|
||||
namespace TEngine.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 脚本宏定义操作类。
|
||||
/// </summary>
|
||||
public static class ScriptingDefineSymbols
|
||||
{
|
||||
private static readonly BuildTargetGroup[] BuildTargetGroups = new BuildTargetGroup[]
|
||||
{
|
||||
BuildTargetGroup.Standalone,
|
||||
BuildTargetGroup.iOS,
|
||||
BuildTargetGroup.Android,
|
||||
BuildTargetGroup.WSA,
|
||||
BuildTargetGroup.WebGL
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 检查指定平台是否存在指定的脚本宏定义。
|
||||
/// </summary>
|
||||
/// <param name="buildTargetGroup">要检查脚本宏定义的平台。</param>
|
||||
/// <param name="scriptingDefineSymbol">要检查的脚本宏定义。</param>
|
||||
/// <returns>指定平台是否存在指定的脚本宏定义。</returns>
|
||||
public static bool HasScriptingDefineSymbol(BuildTargetGroup buildTargetGroup, string scriptingDefineSymbol)
|
||||
{
|
||||
if (string.IsNullOrEmpty(scriptingDefineSymbol))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string[] scriptingDefineSymbols = GetScriptingDefineSymbols(buildTargetGroup);
|
||||
foreach (string i in scriptingDefineSymbols)
|
||||
{
|
||||
if (i == scriptingDefineSymbol)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 为指定平台增加指定的脚本宏定义。
|
||||
/// </summary>
|
||||
/// <param name="buildTargetGroup">要增加脚本宏定义的平台。</param>
|
||||
/// <param name="scriptingDefineSymbol">要增加的脚本宏定义。</param>
|
||||
public static void AddScriptingDefineSymbol(BuildTargetGroup buildTargetGroup, string scriptingDefineSymbol)
|
||||
{
|
||||
if (string.IsNullOrEmpty(scriptingDefineSymbol))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasScriptingDefineSymbol(buildTargetGroup, scriptingDefineSymbol))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<string> scriptingDefineSymbols = new List<string>(GetScriptingDefineSymbols(buildTargetGroup))
|
||||
{
|
||||
scriptingDefineSymbol
|
||||
};
|
||||
|
||||
SetScriptingDefineSymbols(buildTargetGroup, scriptingDefineSymbols.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 为指定平台移除指定的脚本宏定义。
|
||||
/// </summary>
|
||||
/// <param name="buildTargetGroup">要移除脚本宏定义的平台。</param>
|
||||
/// <param name="scriptingDefineSymbol">要移除的脚本宏定义。</param>
|
||||
public static void RemoveScriptingDefineSymbol(BuildTargetGroup buildTargetGroup, string scriptingDefineSymbol)
|
||||
{
|
||||
if (string.IsNullOrEmpty(scriptingDefineSymbol))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HasScriptingDefineSymbol(buildTargetGroup, scriptingDefineSymbol))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<string> scriptingDefineSymbols = new List<string>(GetScriptingDefineSymbols(buildTargetGroup));
|
||||
while (scriptingDefineSymbols.Contains(scriptingDefineSymbol))
|
||||
{
|
||||
scriptingDefineSymbols.Remove(scriptingDefineSymbol);
|
||||
}
|
||||
|
||||
SetScriptingDefineSymbols(buildTargetGroup, scriptingDefineSymbols.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 为所有平台增加指定的脚本宏定义。
|
||||
/// </summary>
|
||||
/// <param name="scriptingDefineSymbol">要增加的脚本宏定义。</param>
|
||||
public static void AddScriptingDefineSymbol(string scriptingDefineSymbol)
|
||||
{
|
||||
if (string.IsNullOrEmpty(scriptingDefineSymbol))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (BuildTargetGroup buildTargetGroup in BuildTargetGroups)
|
||||
{
|
||||
AddScriptingDefineSymbol(buildTargetGroup, scriptingDefineSymbol);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 为所有平台移除指定的脚本宏定义。
|
||||
/// </summary>
|
||||
/// <param name="scriptingDefineSymbol">要移除的脚本宏定义。</param>
|
||||
public static void RemoveScriptingDefineSymbol(string scriptingDefineSymbol)
|
||||
{
|
||||
if (string.IsNullOrEmpty(scriptingDefineSymbol))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (BuildTargetGroup buildTargetGroup in BuildTargetGroups)
|
||||
{
|
||||
RemoveScriptingDefineSymbol(buildTargetGroup, scriptingDefineSymbol);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定平台的脚本宏定义。
|
||||
/// </summary>
|
||||
/// <param name="buildTargetGroup">要获取脚本宏定义的平台。</param>
|
||||
/// <returns>平台的脚本宏定义。</returns>
|
||||
public static string[] GetScriptingDefineSymbols(BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
return PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup).Split(';');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置指定平台的脚本宏定义。
|
||||
/// </summary>
|
||||
/// <param name="buildTargetGroup">要设置脚本宏定义的平台。</param>
|
||||
/// <param name="scriptingDefineSymbols">要设置的脚本宏定义。</param>
|
||||
public static void SetScriptingDefineSymbols(BuildTargetGroup buildTargetGroup, string[] scriptingDefineSymbols)
|
||||
{
|
||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, string.Join(";", scriptingDefineSymbols));
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 654ee3e03c534f841bf22040608d720e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
3
UnityProject/Assets/TEngine/Editor/GameSettings.meta
Normal file
3
UnityProject/Assets/TEngine/Editor/GameSettings.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8886f3797aa14b80ab35d4d5e20d32e6
|
||||
timeCreated: 1695127130
|
@@ -0,0 +1,7 @@
|
||||
using UnityEditor;
|
||||
|
||||
public static class SettingsMenu
|
||||
{
|
||||
[MenuItem("TEngine/Settings/TEngineSettings", priority = -1)]
|
||||
public static void OpenSettings() => SettingsService.OpenProjectSettings("TEngine/TEngineSettings");
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1afcc6b01c286a54d84a1c6a27deceb8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,18 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 同步程序集上下文。
|
||||
/// </summary>
|
||||
public static class SyncAssemblyContent
|
||||
{
|
||||
public static void RefreshAssembly()
|
||||
{
|
||||
SettingsUtils.SetHybridCLRHotUpdateAssemblies(HybridCLR.Editor.SettingsUtil.HotUpdateAssemblyFilesIncludePreserved);
|
||||
SettingsUtils.SetHybridCLRAOTMetaAssemblies(HybridCLR.Editor.SettingsUtil.AOTAssemblyNames);
|
||||
SettingsUtils.HybridCLRCustomGlobalSettings.Enable = HybridCLR.Editor.SettingsUtil.Enable;
|
||||
AssetDatabase.Refresh();
|
||||
AssetDatabase.SaveAssets();
|
||||
Debug.Log("同步AOT和HotUpdate程序集 HybridCLR到TEngineSettings成功。");
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 04407344026702f4ebd61f63c8a35c69
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,90 @@
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine.UIElements;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class TEngineSettingsProvider : SettingsProvider
|
||||
{
|
||||
const string k_SettingsPath = "Assets/TEngine/ResRaw/Resources/TEngineGlobalSettings.asset";
|
||||
private const string headerName = "TEngine/TEngineSettings";
|
||||
private SerializedObject m_CustomSettings;
|
||||
|
||||
internal static SerializedObject GetSerializedSettings()
|
||||
{
|
||||
return new SerializedObject(SettingsUtils.GlobalSettings);
|
||||
}
|
||||
|
||||
public static bool IsSettingsAvailable()
|
||||
{
|
||||
return File.Exists(k_SettingsPath);
|
||||
}
|
||||
|
||||
public override void OnActivate(string searchContext, VisualElement rootElement)
|
||||
{
|
||||
base.OnActivate(searchContext, rootElement);
|
||||
m_CustomSettings = GetSerializedSettings();
|
||||
}
|
||||
|
||||
public override void OnDeactivate()
|
||||
{
|
||||
base.OnDeactivate();
|
||||
SaveAssetData(k_SettingsPath);
|
||||
}
|
||||
|
||||
void SaveAssetData(string path)
|
||||
{
|
||||
TEngineSettings old = AssetDatabase.LoadAssetAtPath<TEngineSettings>(k_SettingsPath);
|
||||
TEngineSettings data = ScriptableObject.CreateInstance<TEngineSettings>();
|
||||
data.Set(old.FrameworkGlobalSettings, old.BybridCLRCustomGlobalSettings);
|
||||
AssetDatabase.DeleteAsset(path);
|
||||
AssetDatabase.CreateAsset(data, path);
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
|
||||
public override void OnGUI(string searchContext)
|
||||
{
|
||||
base.OnGUI(searchContext);
|
||||
using var changeCheckScope = new EditorGUI.ChangeCheckScope();
|
||||
EditorGUILayout.PropertyField(m_CustomSettings.FindProperty("m_FrameworkGlobalSettings"));
|
||||
|
||||
if (GUILayout.Button("Refresh HotUpdateAssemblies"))
|
||||
{
|
||||
SyncAssemblyContent.RefreshAssembly();
|
||||
m_CustomSettings.ApplyModifiedPropertiesWithoutUndo();
|
||||
m_CustomSettings = null;
|
||||
m_CustomSettings = GetSerializedSettings();
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(m_CustomSettings.FindProperty("m_BybridCLRCustomGlobalSettings"));
|
||||
EditorGUILayout.Space(20);
|
||||
if (!changeCheckScope.changed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_CustomSettings.ApplyModifiedPropertiesWithoutUndo();
|
||||
}
|
||||
|
||||
public TEngineSettingsProvider(string path, SettingsScope scopes, IEnumerable<string> keywords = null) : base(path, scopes, keywords)
|
||||
{
|
||||
}
|
||||
|
||||
[SettingsProvider]
|
||||
private static SettingsProvider CreateSettingProvider()
|
||||
{
|
||||
if (IsSettingsAvailable())
|
||||
{
|
||||
var provider = new TEngineSettingsProvider(headerName, SettingsScope.Project);
|
||||
provider.keywords = GetSearchKeywordsFromGUIContentProperties<TEngineSettings>();
|
||||
return provider;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"Open TEngine Settings error,Please Create TEngine TEngineGlobalSettings.assets File in Path TEngine/ResRaw/Resources/");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09fb422339ad47ec86205963c369718b
|
||||
timeCreated: 1678946531
|
3
UnityProject/Assets/TEngine/Editor/HybridCLR.meta
Normal file
3
UnityProject/Assets/TEngine/Editor/HybridCLR.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 71b72a5760a04a4c8a3d8197729c3d10
|
||||
timeCreated: 1695127841
|
@@ -0,0 +1,79 @@
|
||||
using HybridCLR.Editor;
|
||||
using HybridCLR.Editor.Commands;
|
||||
using TEngine.Editor;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
public static class BuildAssetsCommand
|
||||
{
|
||||
private const string EnableHybridClrScriptingDefineSymbol = "ENABLE_HYBRIDCLR";
|
||||
|
||||
/// <summary>
|
||||
/// 禁用HybridCLR宏定义。
|
||||
/// </summary>
|
||||
[MenuItem("HybridCLR/Define Symbols/Disable HybridCLR", false, 30)]
|
||||
public static void Disable()
|
||||
{
|
||||
ScriptingDefineSymbols.RemoveScriptingDefineSymbol(EnableHybridClrScriptingDefineSymbol);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开启HybridCLR宏定义。
|
||||
/// </summary>
|
||||
[MenuItem("HybridCLR/Define Symbols/Enable HybridCLR", false, 31)]
|
||||
public static void Enable()
|
||||
{
|
||||
ScriptingDefineSymbols.RemoveScriptingDefineSymbol(EnableHybridClrScriptingDefineSymbol);
|
||||
ScriptingDefineSymbols.AddScriptingDefineSymbol(EnableHybridClrScriptingDefineSymbol);
|
||||
}
|
||||
|
||||
[MenuItem("HybridCLR/Build/BuildAssets And CopyTo AssemblyTextAssetPath")]
|
||||
public static void BuildAndCopyDlls()
|
||||
{
|
||||
BuildTarget target = EditorUserBuildSettings.activeBuildTarget;
|
||||
CompileDllCommand.CompileDll(target);
|
||||
CopyAOTHotUpdateDlls(target);
|
||||
}
|
||||
|
||||
public static void CopyAOTHotUpdateDlls(BuildTarget target)
|
||||
{
|
||||
CopyAOTAssembliesToAssetPath();
|
||||
CopyHotUpdateAssembliesToAssetPath();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
public static void CopyAOTAssembliesToAssetPath()
|
||||
{
|
||||
var target = EditorUserBuildSettings.activeBuildTarget;
|
||||
string aotAssembliesSrcDir = SettingsUtil.GetAssembliesPostIl2CppStripDir(target);
|
||||
string aotAssembliesDstDir = Application.dataPath +"/"+ SettingsUtils.HybridCLRCustomGlobalSettings.AssemblyTextAssetPath;
|
||||
|
||||
foreach (var dll in SettingsUtils.HybridCLRCustomGlobalSettings.AOTMetaAssemblies)
|
||||
{
|
||||
string srcDllPath = $"{aotAssembliesSrcDir}/{dll}";
|
||||
if (!System.IO.File.Exists(srcDllPath))
|
||||
{
|
||||
Debug.LogError($"ab中添加AOT补充元数据dll:{srcDllPath} 时发生错误,文件不存在。裁剪后的AOT dll在BuildPlayer时才能生成,因此需要你先构建一次游戏App后再打包。");
|
||||
continue;
|
||||
}
|
||||
string dllBytesPath = $"{aotAssembliesDstDir}/{dll}.bytes";
|
||||
System.IO.File.Copy(srcDllPath, dllBytesPath, true);
|
||||
Debug.Log($"[CopyAOTAssembliesToStreamingAssets] copy AOT dll {srcDllPath} -> {dllBytesPath}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void CopyHotUpdateAssembliesToAssetPath()
|
||||
{
|
||||
var target = EditorUserBuildSettings.activeBuildTarget;
|
||||
|
||||
string hotfixDllSrcDir = SettingsUtil.GetHotUpdateDllsOutputDirByTarget(target);
|
||||
string hotfixAssembliesDstDir = Application.dataPath +"/"+ SettingsUtils.HybridCLRCustomGlobalSettings.AssemblyTextAssetPath;
|
||||
foreach (var dll in SettingsUtil.HotUpdateAssemblyFilesExcludePreserved)
|
||||
{
|
||||
string dllPath = $"{hotfixDllSrcDir}/{dll}";
|
||||
string dllBytesPath = $"{hotfixAssembliesDstDir}/{dll}.bytes";
|
||||
System.IO.File.Copy(dllPath, dllBytesPath, true);
|
||||
Debug.Log($"[CopyHotUpdateAssembliesToStreamingAssets] copy hotfix dll {dllPath} -> {dllBytesPath}");
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b43c8d69a58c066469f4f28e310d8181
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
UnityProject/Assets/TEngine/Editor/Inspector.meta
Normal file
8
UnityProject/Assets/TEngine/Editor/Inspector.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d070fe16674cbe240be91ed06370b6be
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,54 @@
|
||||
using UnityEditor;
|
||||
|
||||
namespace TEngine.Editor.Inspector
|
||||
{
|
||||
[CustomEditor(typeof(AudioModule))]
|
||||
internal sealed class AudioModuleInspector : GameFrameworkInspector
|
||||
{
|
||||
private SerializedProperty m_InstanceRoot = null;
|
||||
private SerializedProperty m_AudioMixer = null;
|
||||
private SerializedProperty m_AudioGroupConfigs = null;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
AudioModule t = (AudioModule)target;
|
||||
|
||||
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
|
||||
{
|
||||
EditorGUILayout.PropertyField(m_InstanceRoot);
|
||||
EditorGUILayout.PropertyField(m_AudioMixer);
|
||||
|
||||
EditorGUILayout.PropertyField(m_AudioGroupConfigs, true);
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
Repaint();
|
||||
}
|
||||
|
||||
protected override void OnCompileComplete()
|
||||
{
|
||||
base.OnCompileComplete();
|
||||
|
||||
RefreshTypeNames();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
m_InstanceRoot = serializedObject.FindProperty("m_InstanceRoot");
|
||||
m_AudioMixer = serializedObject.FindProperty("m_AudioMixer");
|
||||
m_AudioGroupConfigs = serializedObject.FindProperty("m_AudioGroupConfigs");
|
||||
RefreshTypeNames();
|
||||
}
|
||||
|
||||
private void RefreshTypeNames()
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3ab21fc9c6dd70744a63b928446497bd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
UnityProject/Assets/TEngine/Editor/Inspector/Core.meta
Normal file
8
UnityProject/Assets/TEngine/Editor/Inspector/Core.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b430ccb333d3963468369c50283c6174
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,57 @@
|
||||
using UnityEditor;
|
||||
|
||||
namespace TEngine.Editor.Inspector
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏框架 Inspector 抽象类。
|
||||
/// </summary>
|
||||
public abstract class GameFrameworkInspector : UnityEditor.Editor
|
||||
{
|
||||
private bool m_IsCompiling = false;
|
||||
|
||||
/// <summary>
|
||||
/// 绘制事件。
|
||||
/// </summary>
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
if (m_IsCompiling && !EditorApplication.isCompiling)
|
||||
{
|
||||
m_IsCompiling = false;
|
||||
OnCompileComplete();
|
||||
}
|
||||
else if (!m_IsCompiling && EditorApplication.isCompiling)
|
||||
{
|
||||
m_IsCompiling = true;
|
||||
OnCompileStart();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编译开始事件。
|
||||
/// </summary>
|
||||
protected virtual void OnCompileStart()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编译完成事件。
|
||||
/// </summary>
|
||||
protected virtual void OnCompileComplete()
|
||||
{
|
||||
}
|
||||
|
||||
protected bool IsPrefabInHierarchy(UnityEngine.Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
return PrefabUtility.GetPrefabAssetType(obj) != PrefabAssetType.Regular;
|
||||
#else
|
||||
return PrefabUtility.GetPrefabType(obj) != PrefabType.Prefab;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d91af5de1cd262429b9414da4df0a4d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,40 @@
|
||||
using UnityEditor;
|
||||
|
||||
namespace TEngine.Editor.Inspector
|
||||
{
|
||||
[CustomEditor(typeof(FsmModule))]
|
||||
internal sealed class FsmComponentInspector : GameFrameworkInspector
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
if (!EditorApplication.isPlaying)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info);
|
||||
return;
|
||||
}
|
||||
|
||||
FsmModule t = (FsmModule)target;
|
||||
|
||||
if (IsPrefabInHierarchy(t.gameObject))
|
||||
{
|
||||
EditorGUILayout.LabelField("FSM Count", t.Count.ToString());
|
||||
|
||||
FsmBase[] fsms = t.GetAllFsms();
|
||||
foreach (FsmBase fsm in fsms)
|
||||
{
|
||||
DrawFsm(fsm);
|
||||
}
|
||||
}
|
||||
|
||||
Repaint();
|
||||
}
|
||||
|
||||
private void DrawFsm(FsmBase fsm)
|
||||
{
|
||||
EditorGUILayout.LabelField(fsm.FullName,
|
||||
fsm.IsRunning ? Utility.Text.Format("{0}, {1:F1} s", fsm.CurrentStateName, fsm.CurrentStateTime) : (fsm.IsDestroyed ? "Destroyed" : "Not Running"));
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 70767d883b439f84d8daaed6ca3f6d35
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,56 @@
|
||||
using UnityEditor;
|
||||
|
||||
namespace TEngine.Editor.Inspector
|
||||
{
|
||||
[CustomEditor(typeof(LocalizationModule))]
|
||||
internal sealed class LocalizationModuleInspector : GameFrameworkInspector
|
||||
{
|
||||
private HelperInfo<LocalizationHelperBase> m_LocalizationHelperInfo = new HelperInfo<LocalizationHelperBase>("Localization");
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
LocalizationModule t = (LocalizationModule)target;
|
||||
|
||||
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
|
||||
{
|
||||
m_LocalizationHelperInfo.Draw();
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
|
||||
{
|
||||
EditorGUILayout.LabelField("Language", t.Language.ToString());
|
||||
EditorGUILayout.LabelField("System Language", t.SystemLanguage.ToString());
|
||||
EditorGUILayout.LabelField("Dictionary Count", t.DictionaryCount.ToString());
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
Repaint();
|
||||
}
|
||||
|
||||
protected override void OnCompileComplete()
|
||||
{
|
||||
base.OnCompileComplete();
|
||||
|
||||
RefreshTypeNames();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
m_LocalizationHelperInfo.Init(serializedObject);
|
||||
|
||||
RefreshTypeNames();
|
||||
}
|
||||
|
||||
private void RefreshTypeNames()
|
||||
{
|
||||
m_LocalizationHelperInfo.Refresh();
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c8de00f4cb14c4fa7b28015f55cd5ee
|
||||
timeCreated: 1695200030
|
@@ -0,0 +1,143 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Editor.Inspector
|
||||
{
|
||||
[CustomEditor(typeof(MemoryPoolModule))]
|
||||
internal sealed class MemoryPoolModuleInspector : GameFrameworkInspector
|
||||
{
|
||||
private readonly Dictionary<string, List<MemoryPoolInfo>> m_MemoryPoolInfos = new Dictionary<string, List<MemoryPoolInfo>>(StringComparer.Ordinal);
|
||||
private readonly HashSet<string> m_OpenedItems = new HashSet<string>();
|
||||
|
||||
private SerializedProperty m_EnableStrictCheck = null;
|
||||
|
||||
private bool m_ShowFullClassName = false;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
MemoryPoolModule t = (MemoryPoolModule)target;
|
||||
|
||||
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
|
||||
{
|
||||
bool enableStrictCheck = EditorGUILayout.Toggle("Enable Strict Check", t.EnableStrictCheck);
|
||||
if (enableStrictCheck != t.EnableStrictCheck)
|
||||
{
|
||||
t.EnableStrictCheck = enableStrictCheck;
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField("Memory Pool Count", MemoryPool.Count.ToString());
|
||||
m_ShowFullClassName = EditorGUILayout.Toggle("Show Full Class Name", m_ShowFullClassName);
|
||||
m_MemoryPoolInfos.Clear();
|
||||
MemoryPoolInfo[] memoryPoolInfos = MemoryPool.GetAllMemoryPoolInfos();
|
||||
foreach (MemoryPoolInfo memoryPoolInfo in memoryPoolInfos)
|
||||
{
|
||||
string assemblyName = memoryPoolInfo.Type.Assembly.GetName().Name;
|
||||
List<MemoryPoolInfo> results = null;
|
||||
if (!m_MemoryPoolInfos.TryGetValue(assemblyName, out results))
|
||||
{
|
||||
results = new List<MemoryPoolInfo>();
|
||||
m_MemoryPoolInfos.Add(assemblyName, results);
|
||||
}
|
||||
|
||||
results.Add(memoryPoolInfo);
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, List<MemoryPoolInfo>> assemblyMemoryPoolInfo in m_MemoryPoolInfos)
|
||||
{
|
||||
bool lastState = m_OpenedItems.Contains(assemblyMemoryPoolInfo.Key);
|
||||
bool currentState = EditorGUILayout.Foldout(lastState, assemblyMemoryPoolInfo.Key);
|
||||
if (currentState != lastState)
|
||||
{
|
||||
if (currentState)
|
||||
{
|
||||
m_OpenedItems.Add(assemblyMemoryPoolInfo.Key);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_OpenedItems.Remove(assemblyMemoryPoolInfo.Key);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentState)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
{
|
||||
EditorGUILayout.LabelField(m_ShowFullClassName ? "Full Class Name" : "Class Name", "Unused\tUsing\tAcquire\tRelease\tAdd\tRemove");
|
||||
assemblyMemoryPoolInfo.Value.Sort(Comparison);
|
||||
foreach (MemoryPoolInfo memoryPoolInfo in assemblyMemoryPoolInfo.Value)
|
||||
{
|
||||
DrawMemoryPoolInfo(memoryPoolInfo);
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Export CSV Data"))
|
||||
{
|
||||
string exportFileName = EditorUtility.SaveFilePanel("Export CSV Data", string.Empty, Utility.Text.Format("Memory Pool Data - {0}.csv", assemblyMemoryPoolInfo.Key), string.Empty);
|
||||
if (!string.IsNullOrEmpty(exportFileName))
|
||||
{
|
||||
try
|
||||
{
|
||||
int index = 0;
|
||||
string[] data = new string[assemblyMemoryPoolInfo.Value.Count + 1];
|
||||
data[index++] = "Class Name,Full Class Name,Unused,Using,Acquire,Release,Add,Remove";
|
||||
foreach (MemoryPoolInfo memoryPoolInfo in assemblyMemoryPoolInfo.Value)
|
||||
{
|
||||
data[index++] = Utility.Text.Format("{0},{1},{2},{3},{4},{5},{6},{7}", memoryPoolInfo.Type.Name, memoryPoolInfo.Type.FullName, memoryPoolInfo.UnusedMemoryCount.ToString(), memoryPoolInfo.UsingMemoryCount.ToString(), memoryPoolInfo.AcquireMemoryCount.ToString(), memoryPoolInfo.ReleaseMemoryCount.ToString(), memoryPoolInfo.AddMemoryCount.ToString(), memoryPoolInfo.RemoveMemoryCount.ToString());
|
||||
}
|
||||
|
||||
File.WriteAllLines(exportFileName, data, Encoding.UTF8);
|
||||
Debug.Log(Utility.Text.Format("Export memory pool CSV data to '{0}' success.", exportFileName));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.LogError(Utility.Text.Format("Export memory pool CSV data to '{0}' failure, exception is '{1}'.", exportFileName, exception.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.PropertyField(m_EnableStrictCheck);
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
Repaint();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
m_EnableStrictCheck = serializedObject.FindProperty("m_EnableStrictCheck");
|
||||
}
|
||||
|
||||
private void DrawMemoryPoolInfo(MemoryPoolInfo memoryPoolInfo)
|
||||
{
|
||||
EditorGUILayout.LabelField(m_ShowFullClassName ? memoryPoolInfo.Type.FullName : memoryPoolInfo.Type.Name, Utility.Text.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", memoryPoolInfo.UnusedMemoryCount.ToString(), memoryPoolInfo.UsingMemoryCount.ToString(), memoryPoolInfo.AcquireMemoryCount.ToString(), memoryPoolInfo.ReleaseMemoryCount.ToString(), memoryPoolInfo.AddMemoryCount.ToString(), memoryPoolInfo.RemoveMemoryCount.ToString()));
|
||||
}
|
||||
|
||||
private int Comparison(MemoryPoolInfo a, MemoryPoolInfo b)
|
||||
{
|
||||
if (m_ShowFullClassName)
|
||||
{
|
||||
return a.Type.FullName.CompareTo(b.Type.FullName);
|
||||
}
|
||||
else
|
||||
{
|
||||
return a.Type.Name.CompareTo(b.Type.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17406c25c88f31948b13eed588b32244
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,146 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Editor.Inspector
|
||||
{
|
||||
[CustomEditor(typeof(ObjectPoolModule))]
|
||||
internal sealed class ObjectPoolModuleInspector : GameFrameworkInspector
|
||||
{
|
||||
private readonly HashSet<string> m_OpenedItems = new HashSet<string>();
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
if (!EditorApplication.isPlaying)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info);
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectPoolModule t = (ObjectPoolModule)target;
|
||||
|
||||
if (IsPrefabInHierarchy(t.gameObject))
|
||||
{
|
||||
EditorGUILayout.LabelField("Object Pool Count", t.Count.ToString());
|
||||
|
||||
ObjectPoolBase[] objectPools = t.GetAllObjectPools(true);
|
||||
foreach (ObjectPoolBase objectPool in objectPools)
|
||||
{
|
||||
DrawObjectPool(objectPool);
|
||||
}
|
||||
}
|
||||
|
||||
Repaint();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
}
|
||||
|
||||
private void DrawObjectPool(ObjectPoolBase objectPool)
|
||||
{
|
||||
bool lastState = m_OpenedItems.Contains(objectPool.FullName);
|
||||
bool currentState = EditorGUILayout.Foldout(lastState, objectPool.FullName);
|
||||
if (currentState != lastState)
|
||||
{
|
||||
if (currentState)
|
||||
{
|
||||
m_OpenedItems.Add(objectPool.FullName);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_OpenedItems.Remove(objectPool.FullName);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentState)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
{
|
||||
EditorGUILayout.LabelField("Name", objectPool.Name);
|
||||
EditorGUILayout.LabelField("Type", objectPool.ObjectType.FullName);
|
||||
EditorGUILayout.LabelField("Auto Release Interval", objectPool.AutoReleaseInterval.ToString());
|
||||
EditorGUILayout.LabelField("Capacity", objectPool.Capacity.ToString());
|
||||
EditorGUILayout.LabelField("Used Count", objectPool.Count.ToString());
|
||||
EditorGUILayout.LabelField("Can Release Count", objectPool.CanReleaseCount.ToString());
|
||||
EditorGUILayout.LabelField("Expire Time", objectPool.ExpireTime.ToString());
|
||||
EditorGUILayout.LabelField("Priority", objectPool.Priority.ToString());
|
||||
ObjectInfo[] objectInfos = objectPool.GetAllObjectInfos();
|
||||
if (objectInfos.Length > 0)
|
||||
{
|
||||
EditorGUILayout.LabelField("Name",
|
||||
objectPool.AllowMultiSpawn ? "Locked\tCount\tFlag\tPriority\tLast Use Time" : "Locked\tIn Use\tFlag\tPriority\tLast Use Time");
|
||||
foreach (ObjectInfo objectInfo in objectInfos)
|
||||
{
|
||||
EditorGUILayout.LabelField(string.IsNullOrEmpty(objectInfo.Name) ? "<None>" : objectInfo.Name,
|
||||
objectPool.AllowMultiSpawn
|
||||
? Utility.Text.Format("{0}\t{1}\t{2}\t{3}\t{4:yyyy-MM-dd HH:mm:ss}", objectInfo.Locked, objectInfo.SpawnCount,
|
||||
objectInfo.CustomCanReleaseFlag,
|
||||
objectInfo.Priority, objectInfo.LastUseTime.ToLocalTime())
|
||||
: Utility.Text.Format("{0}\t{1}\t{2}\t{3}\t{4:yyyy-MM-dd HH:mm:ss}", objectInfo.Locked, objectInfo.IsInUse,
|
||||
objectInfo.CustomCanReleaseFlag,
|
||||
objectInfo.Priority, objectInfo.LastUseTime.ToLocalTime()));
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Release"))
|
||||
{
|
||||
objectPool.Release();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Release All Unused"))
|
||||
{
|
||||
objectPool.ReleaseAllUnused();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Export CSV Data"))
|
||||
{
|
||||
string exportFileName = EditorUtility.SaveFilePanel("Export CSV Data", string.Empty,
|
||||
Utility.Text.Format("Object Pool Data - {0}.csv", objectPool.Name),
|
||||
string.Empty);
|
||||
if (!string.IsNullOrEmpty(exportFileName))
|
||||
{
|
||||
try
|
||||
{
|
||||
int index = 0;
|
||||
string[] data = new string[objectInfos.Length + 1];
|
||||
data[index++] = Utility.Text.Format("Name,Locked,{0},Custom Can Release Flag,Priority,Last Use Time",
|
||||
objectPool.AllowMultiSpawn ? "Count" : "In Use");
|
||||
foreach (ObjectInfo objectInfo in objectInfos)
|
||||
{
|
||||
data[index++] = objectPool.AllowMultiSpawn
|
||||
? Utility.Text.Format("{0},{1},{2},{3},{4},{5:yyyy-MM-dd HH:mm:ss}", objectInfo.Name, objectInfo.Locked,
|
||||
objectInfo.SpawnCount,
|
||||
objectInfo.CustomCanReleaseFlag, objectInfo.Priority, objectInfo.LastUseTime.ToLocalTime())
|
||||
: Utility.Text.Format("{0},{1},{2},{3},{4},{5:yyyy-MM-dd HH:mm:ss}", objectInfo.Name, objectInfo.Locked,
|
||||
objectInfo.IsInUse,
|
||||
objectInfo.CustomCanReleaseFlag, objectInfo.Priority, objectInfo.LastUseTime.ToLocalTime());
|
||||
}
|
||||
|
||||
File.WriteAllLines(exportFileName, data, Encoding.UTF8);
|
||||
Debug.Log(Utility.Text.Format("Export object pool CSV data to '{0}' success.", exportFileName));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.LogError(Utility.Text.Format("Export object pool CSV data to '{0}' failure, exception is '{1}'.", exportFileName,
|
||||
exception));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.Label("Object Pool is Empty ...");
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 581eaf027c4a96d4d8227e2e16a6645b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,163 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Editor.Inspector
|
||||
{
|
||||
[CustomEditor(typeof(ProcedureModule))]
|
||||
internal sealed class ProcedureModuleInspector : GameFrameworkInspector
|
||||
{
|
||||
private SerializedProperty m_AvailableProcedureTypeNames = null;
|
||||
private SerializedProperty m_EntranceProcedureTypeName = null;
|
||||
|
||||
private string[] m_ProcedureTypeNames = null;
|
||||
private List<string> m_CurrentAvailableProcedureTypeNames = null;
|
||||
private int m_EntranceProcedureIndex = -1;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
ProcedureModule t = (ProcedureModule)target;
|
||||
|
||||
if (string.IsNullOrEmpty(m_EntranceProcedureTypeName.stringValue))
|
||||
{
|
||||
EditorGUILayout.HelpBox("Entrance procedure is invalid.", MessageType.Error);
|
||||
}
|
||||
else if (EditorApplication.isPlaying)
|
||||
{
|
||||
EditorGUILayout.LabelField("Current Procedure", t.CurrentProcedure == null ? "None" : t.CurrentProcedure.GetType().ToString());
|
||||
}
|
||||
|
||||
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
|
||||
{
|
||||
GUILayout.Label("Available Procedures", EditorStyles.boldLabel);
|
||||
if (m_ProcedureTypeNames.Length > 0)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
{
|
||||
foreach (string procedureTypeName in m_ProcedureTypeNames)
|
||||
{
|
||||
bool selected = m_CurrentAvailableProcedureTypeNames.Contains(procedureTypeName);
|
||||
if (selected != EditorGUILayout.ToggleLeft(procedureTypeName, selected))
|
||||
{
|
||||
if (!selected)
|
||||
{
|
||||
m_CurrentAvailableProcedureTypeNames.Add(procedureTypeName);
|
||||
WriteAvailableProcedureTypeNames();
|
||||
}
|
||||
else if (procedureTypeName != m_EntranceProcedureTypeName.stringValue)
|
||||
{
|
||||
m_CurrentAvailableProcedureTypeNames.Remove(procedureTypeName);
|
||||
WriteAvailableProcedureTypeNames();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.HelpBox("There is no available procedure.", MessageType.Warning);
|
||||
}
|
||||
|
||||
if (m_CurrentAvailableProcedureTypeNames.Count > 0)
|
||||
{
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
int selectedIndex = EditorGUILayout.Popup("Entrance Procedure", m_EntranceProcedureIndex, m_CurrentAvailableProcedureTypeNames.ToArray());
|
||||
if (selectedIndex != m_EntranceProcedureIndex)
|
||||
{
|
||||
m_EntranceProcedureIndex = selectedIndex;
|
||||
m_EntranceProcedureTypeName.stringValue = m_CurrentAvailableProcedureTypeNames[selectedIndex];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.HelpBox("Select available procedures first.", MessageType.Info);
|
||||
}
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
Repaint();
|
||||
}
|
||||
|
||||
protected override void OnCompileComplete()
|
||||
{
|
||||
base.OnCompileComplete();
|
||||
|
||||
RefreshTypeNames();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
m_AvailableProcedureTypeNames = serializedObject.FindProperty("availableProcedureTypeNames");
|
||||
m_EntranceProcedureTypeName = serializedObject.FindProperty("entranceProcedureTypeName");
|
||||
|
||||
RefreshTypeNames();
|
||||
}
|
||||
|
||||
private void RefreshTypeNames()
|
||||
{
|
||||
m_ProcedureTypeNames = Type.GetRuntimeTypeNames(typeof(ProcedureBase));
|
||||
ReadAvailableProcedureTypeNames();
|
||||
int oldCount = m_CurrentAvailableProcedureTypeNames.Count;
|
||||
m_CurrentAvailableProcedureTypeNames = m_CurrentAvailableProcedureTypeNames.Where(x => m_ProcedureTypeNames.Contains(x)).ToList();
|
||||
if (m_CurrentAvailableProcedureTypeNames.Count != oldCount)
|
||||
{
|
||||
WriteAvailableProcedureTypeNames();
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(m_EntranceProcedureTypeName.stringValue))
|
||||
{
|
||||
m_EntranceProcedureIndex = m_CurrentAvailableProcedureTypeNames.IndexOf(m_EntranceProcedureTypeName.stringValue);
|
||||
if (m_EntranceProcedureIndex < 0)
|
||||
{
|
||||
m_EntranceProcedureTypeName.stringValue = null;
|
||||
}
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private void ReadAvailableProcedureTypeNames()
|
||||
{
|
||||
m_CurrentAvailableProcedureTypeNames = new List<string>();
|
||||
int count = m_AvailableProcedureTypeNames.arraySize;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
m_CurrentAvailableProcedureTypeNames.Add(m_AvailableProcedureTypeNames.GetArrayElementAtIndex(i).stringValue);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteAvailableProcedureTypeNames()
|
||||
{
|
||||
m_AvailableProcedureTypeNames.ClearArray();
|
||||
if (m_CurrentAvailableProcedureTypeNames == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_CurrentAvailableProcedureTypeNames.Sort();
|
||||
int count = m_CurrentAvailableProcedureTypeNames.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
m_AvailableProcedureTypeNames.InsertArrayElementAtIndex(i);
|
||||
m_AvailableProcedureTypeNames.GetArrayElementAtIndex(i).stringValue = m_CurrentAvailableProcedureTypeNames[i];
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(m_EntranceProcedureTypeName.stringValue))
|
||||
{
|
||||
m_EntranceProcedureIndex = m_CurrentAvailableProcedureTypeNames.IndexOf(m_EntranceProcedureTypeName.stringValue);
|
||||
if (m_EntranceProcedureIndex < 0)
|
||||
{
|
||||
m_EntranceProcedureTypeName.stringValue = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f8673b671dafe048a9fcd213c958166
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,258 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using YooAsset.Editor;
|
||||
|
||||
namespace TEngine.Editor.Inspector
|
||||
{
|
||||
[CustomEditor(typeof(ResourceModule))]
|
||||
internal sealed class ResourceModuleInspector : GameFrameworkInspector
|
||||
{
|
||||
private static readonly string[] _resourceModeNames = new string[]
|
||||
{
|
||||
"EditorSimulateMode (编辑器下的模拟模式)",
|
||||
"OfflinePlayMode (单机模式)",
|
||||
"HostPlayMode (联机运行模式)" ,
|
||||
"WebPlayMode (WebGL运行模式)"
|
||||
};
|
||||
private static readonly string[] _verifyLevelNames = new string[]
|
||||
{
|
||||
"Low (验证文件存在)",
|
||||
"Middle (验证文件大小)",
|
||||
"High (验证文件大小和CRC)"
|
||||
};
|
||||
|
||||
private SerializedProperty m_PackageName = null;
|
||||
private SerializedProperty m_PlayMode = null;
|
||||
private SerializedProperty m_ReadWritePathType = null;
|
||||
private SerializedProperty m_VerifyLevel = null;
|
||||
private SerializedProperty m_Milliseconds = null;
|
||||
private SerializedProperty m_MinUnloadUnusedAssetsInterval = null;
|
||||
private SerializedProperty m_MaxUnloadUnusedAssetsInterval = null;
|
||||
private SerializedProperty m_DownloadingMaxNum = null;
|
||||
private SerializedProperty m_FailedTryAgain = null;
|
||||
|
||||
private int m_ResourceModeIndex = 0;
|
||||
private int m_PackageIndex = 0;
|
||||
private int m_VerifyIndex = 0;
|
||||
|
||||
private PopupField<string> _buildPackageField;
|
||||
private List<string> _buildPackageNames;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
m_PackageName = serializedObject.FindProperty("packageName");
|
||||
m_PlayMode = serializedObject.FindProperty("playMode");
|
||||
m_VerifyLevel = serializedObject.FindProperty("verifyLevel");
|
||||
m_Milliseconds = serializedObject.FindProperty("milliseconds");
|
||||
|
||||
m_ReadWritePathType = serializedObject.FindProperty("readWritePathType");
|
||||
m_MinUnloadUnusedAssetsInterval = serializedObject.FindProperty("minUnloadUnusedAssetsInterval");
|
||||
m_MaxUnloadUnusedAssetsInterval = serializedObject.FindProperty("maxUnloadUnusedAssetsInterval");
|
||||
m_DownloadingMaxNum = serializedObject.FindProperty("downloadingMaxNum");
|
||||
m_FailedTryAgain = serializedObject.FindProperty("failedTryAgain");
|
||||
|
||||
RefreshModes();
|
||||
RefreshTypeNames();
|
||||
}
|
||||
|
||||
private void RefreshModes()
|
||||
{
|
||||
m_ResourceModeIndex = m_PlayMode.enumValueIndex > 0 ? m_PlayMode.enumValueIndex : 0;
|
||||
m_VerifyIndex = m_VerifyLevel.enumValueIndex > 0 ? m_VerifyLevel.enumValueIndex : 0;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
ResourceModule t = (ResourceModule)target;
|
||||
|
||||
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
|
||||
{
|
||||
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
|
||||
{
|
||||
EditorGUILayout.EnumPopup("Resource Mode", t.PlayMode);
|
||||
|
||||
EditorGUILayout.EnumPopup("VerifyLevel", t.verifyLevel);
|
||||
|
||||
_buildPackageNames = GetBuildPackageNames();
|
||||
if (_buildPackageNames.Count > 0)
|
||||
{
|
||||
GUILayout.Label(_buildPackageNames[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 资源模式
|
||||
int selectedIndex = EditorGUILayout.Popup("Resource Mode", m_ResourceModeIndex, _resourceModeNames);
|
||||
if (selectedIndex != m_ResourceModeIndex)
|
||||
{
|
||||
m_ResourceModeIndex = selectedIndex;
|
||||
m_PlayMode.enumValueIndex = selectedIndex;
|
||||
}
|
||||
|
||||
int selectedVerifyIndex = EditorGUILayout.Popup("VerifyLevel", m_VerifyIndex, _verifyLevelNames);
|
||||
if (selectedVerifyIndex != m_VerifyIndex)
|
||||
{
|
||||
m_VerifyIndex = selectedVerifyIndex;
|
||||
m_VerifyLevel.enumValueIndex = selectedVerifyIndex;
|
||||
}
|
||||
|
||||
// 包裹名称列表
|
||||
_buildPackageNames = GetBuildPackageNames();
|
||||
if (_buildPackageNames.Count > 0)
|
||||
{
|
||||
int selectedPackageIndex = EditorGUILayout.Popup("Used Packages", m_PackageIndex, _buildPackageNames.ToArray());
|
||||
if (selectedPackageIndex != m_PackageIndex)
|
||||
{
|
||||
m_PackageIndex = selectedPackageIndex;
|
||||
m_PlayMode.enumValueIndex = selectedIndex + 1;
|
||||
}
|
||||
|
||||
int defaultIndex = GetDefaultPackageIndex(AssetBundleBuilderSettingData.Setting.BuildPackage);
|
||||
_buildPackageField = new PopupField<string>(_buildPackageNames, defaultIndex);
|
||||
_buildPackageField.label = "Build Package";
|
||||
_buildPackageField.style.width = 350;
|
||||
_buildPackageField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
AssetBundleBuilderSettingData.IsDirty = true;
|
||||
AssetBundleBuilderSettingData.Setting.BuildPackage = _buildPackageField.value;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.Label("Please Create Packages with YooAssets ...!");
|
||||
}
|
||||
}
|
||||
|
||||
m_ReadWritePathType.enumValueIndex = (int)(ReadWritePathType)EditorGUILayout.EnumPopup("Read-Write Path Type", t.ReadWritePathType);
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
int milliseconds = EditorGUILayout.DelayedIntField("Milliseconds", m_Milliseconds.intValue);
|
||||
if (milliseconds != m_Milliseconds.intValue)
|
||||
{
|
||||
if (EditorApplication.isPlaying)
|
||||
{
|
||||
t.milliseconds = milliseconds;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Milliseconds.longValue = milliseconds;
|
||||
}
|
||||
}
|
||||
|
||||
float minUnloadUnusedAssetsInterval = EditorGUILayout.Slider("Min Unload Unused Assets Interval", m_MinUnloadUnusedAssetsInterval.floatValue, 0f, 3600f);
|
||||
if (Math.Abs(minUnloadUnusedAssetsInterval - m_MinUnloadUnusedAssetsInterval.floatValue) > 0.001f)
|
||||
{
|
||||
if (EditorApplication.isPlaying)
|
||||
{
|
||||
t.MinUnloadUnusedAssetsInterval = minUnloadUnusedAssetsInterval;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_MinUnloadUnusedAssetsInterval.floatValue = minUnloadUnusedAssetsInterval;
|
||||
}
|
||||
}
|
||||
|
||||
float maxUnloadUnusedAssetsInterval = EditorGUILayout.Slider("Max Unload Unused Assets Interval", m_MaxUnloadUnusedAssetsInterval.floatValue, 0f, 3600f);
|
||||
if (Math.Abs(maxUnloadUnusedAssetsInterval - m_MaxUnloadUnusedAssetsInterval.floatValue) > 0.001f)
|
||||
{
|
||||
if (EditorApplication.isPlaying)
|
||||
{
|
||||
t.MaxUnloadUnusedAssetsInterval = maxUnloadUnusedAssetsInterval;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_MaxUnloadUnusedAssetsInterval.floatValue = maxUnloadUnusedAssetsInterval;
|
||||
}
|
||||
}
|
||||
|
||||
float downloadingMaxNum = EditorGUILayout.Slider("Max Downloading Num", m_DownloadingMaxNum.intValue, 1f, 48f);
|
||||
if (Math.Abs(downloadingMaxNum - m_DownloadingMaxNum.intValue) > 0.001f)
|
||||
{
|
||||
if (EditorApplication.isPlaying)
|
||||
{
|
||||
t.downloadingMaxNum = (int)downloadingMaxNum;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_DownloadingMaxNum.intValue = (int)downloadingMaxNum;
|
||||
}
|
||||
}
|
||||
|
||||
float failedTryAgain = EditorGUILayout.Slider("Max FailedTryAgain Count", m_FailedTryAgain.intValue, 1f, 48f);
|
||||
if (Math.Abs(failedTryAgain - m_FailedTryAgain.intValue) > 0.001f)
|
||||
{
|
||||
if (EditorApplication.isPlaying)
|
||||
{
|
||||
t.failedTryAgain = (int)failedTryAgain;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_FailedTryAgain.intValue = (int)failedTryAgain;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
|
||||
{
|
||||
EditorGUILayout.LabelField("Unload Unused Assets",
|
||||
Utility.Text.Format("{0:F2} / {1:F2}", t.LastUnloadUnusedAssetsOperationElapseSeconds, t.MaxUnloadUnusedAssetsInterval));
|
||||
EditorGUILayout.LabelField("Read-Only Path", t.ReadOnlyPath.ToString());
|
||||
EditorGUILayout.LabelField("Read-Write Path", t.ReadWritePath.ToString());
|
||||
EditorGUILayout.LabelField("Applicable Game Version", t.ApplicableGameVersion ?? "<Unknwon>");
|
||||
EditorGUILayout.LabelField("Internal Resource Version", t.InternalResourceVersion.ToString());
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
Repaint();
|
||||
}
|
||||
|
||||
protected override void OnCompileComplete()
|
||||
{
|
||||
base.OnCompileComplete();
|
||||
|
||||
RefreshTypeNames();
|
||||
}
|
||||
|
||||
private void RefreshTypeNames()
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
// 构建包裹相关
|
||||
private int GetDefaultPackageIndex(string packageName)
|
||||
{
|
||||
for (int index = 0; index < _buildPackageNames.Count; index++)
|
||||
{
|
||||
if (_buildPackageNames[index] == packageName)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
AssetBundleBuilderSettingData.IsDirty = true;
|
||||
AssetBundleBuilderSettingData.Setting.BuildPackage = _buildPackageNames[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
private List<string> GetBuildPackageNames()
|
||||
{
|
||||
List<string> result = new List<string>();
|
||||
foreach (var package in AssetBundleCollectorSettingData.Setting.Packages)
|
||||
{
|
||||
result.Add(package.PackageName);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3331df47456eb44388680ac13979201
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,278 @@
|
||||
using System;
|
||||
using TEngine;
|
||||
using System.Collections.Generic;
|
||||
using TEngine.Editor.Inspector;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Editor
|
||||
{
|
||||
[CustomEditor(typeof(RootModule))]
|
||||
internal sealed class RootModuleInspector : GameFrameworkInspector
|
||||
{
|
||||
private const string NoneOptionName = "<None>";
|
||||
private static readonly float[] GameSpeed = new float[] { 0f, 0.01f, 0.1f, 0.25f, 0.5f, 1f, 1.5f, 2f, 4f, 8f };
|
||||
private static readonly string[] GameSpeedForDisplay = new string[] { "0x", "0.01x", "0.1x", "0.25x", "0.5x", "1x", "1.5x", "2x", "4x", "8x" };
|
||||
|
||||
private SerializedProperty m_EditorLanguage = null;
|
||||
private SerializedProperty m_TextHelperTypeName = null;
|
||||
private SerializedProperty m_VersionHelperTypeName = null;
|
||||
private SerializedProperty m_LogHelperTypeName = null;
|
||||
private SerializedProperty m_CompressionHelperTypeName = null;
|
||||
private SerializedProperty m_JsonHelperTypeName = null;
|
||||
private SerializedProperty m_FrameRate = null;
|
||||
private SerializedProperty m_GameSpeed = null;
|
||||
private SerializedProperty m_RunInBackground = null;
|
||||
private SerializedProperty m_NeverSleep = null;
|
||||
|
||||
private string[] m_TextHelperTypeNames = null;
|
||||
private int m_TextHelperTypeNameIndex = 0;
|
||||
private string[] m_VersionHelperTypeNames = null;
|
||||
private int m_VersionHelperTypeNameIndex = 0;
|
||||
private string[] m_LogHelperTypeNames = null;
|
||||
private int m_LogHelperTypeNameIndex = 0;
|
||||
private string[] m_JsonHelperTypeNames = null;
|
||||
private int m_JsonHelperTypeNameIndex = 0;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
RootModule t = (RootModule)target;
|
||||
|
||||
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
|
||||
{
|
||||
EditorGUILayout.PropertyField(m_EditorLanguage);
|
||||
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
{
|
||||
EditorGUILayout.LabelField("Global Helpers", EditorStyles.boldLabel);
|
||||
|
||||
int textHelperSelectedIndex = EditorGUILayout.Popup("Text Helper", m_TextHelperTypeNameIndex, m_TextHelperTypeNames);
|
||||
if (textHelperSelectedIndex != m_TextHelperTypeNameIndex)
|
||||
{
|
||||
m_TextHelperTypeNameIndex = textHelperSelectedIndex;
|
||||
m_TextHelperTypeName.stringValue = textHelperSelectedIndex <= 0 ? null : m_TextHelperTypeNames[textHelperSelectedIndex];
|
||||
}
|
||||
|
||||
int versionHelperSelectedIndex = EditorGUILayout.Popup("Version Helper", m_VersionHelperTypeNameIndex, m_VersionHelperTypeNames);
|
||||
if (versionHelperSelectedIndex != m_VersionHelperTypeNameIndex)
|
||||
{
|
||||
m_VersionHelperTypeNameIndex = versionHelperSelectedIndex;
|
||||
m_VersionHelperTypeName.stringValue = versionHelperSelectedIndex <= 0 ? null : m_VersionHelperTypeNames[versionHelperSelectedIndex];
|
||||
}
|
||||
|
||||
int logHelperSelectedIndex = EditorGUILayout.Popup("Log Helper", m_LogHelperTypeNameIndex, m_LogHelperTypeNames);
|
||||
if (logHelperSelectedIndex != m_LogHelperTypeNameIndex)
|
||||
{
|
||||
m_LogHelperTypeNameIndex = logHelperSelectedIndex;
|
||||
m_LogHelperTypeName.stringValue = logHelperSelectedIndex <= 0 ? null : m_LogHelperTypeNames[logHelperSelectedIndex];
|
||||
}
|
||||
|
||||
int jsonHelperSelectedIndex = EditorGUILayout.Popup("JSON Helper", m_JsonHelperTypeNameIndex, m_JsonHelperTypeNames);
|
||||
if (jsonHelperSelectedIndex != m_JsonHelperTypeNameIndex)
|
||||
{
|
||||
m_JsonHelperTypeNameIndex = jsonHelperSelectedIndex;
|
||||
m_JsonHelperTypeName.stringValue = jsonHelperSelectedIndex <= 0 ? null : m_JsonHelperTypeNames[jsonHelperSelectedIndex];
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
int frameRate = EditorGUILayout.IntSlider("Frame Rate", m_FrameRate.intValue, 1, 120);
|
||||
if (frameRate != m_FrameRate.intValue)
|
||||
{
|
||||
if (EditorApplication.isPlaying)
|
||||
{
|
||||
t.FrameRate = frameRate;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_FrameRate.intValue = frameRate;
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
{
|
||||
float gameSpeed = EditorGUILayout.Slider("Game Speed", m_GameSpeed.floatValue, 0f, 8f);
|
||||
int selectedGameSpeed = GUILayout.SelectionGrid(GetSelectedGameSpeed(gameSpeed), GameSpeedForDisplay, 5);
|
||||
if (selectedGameSpeed >= 0)
|
||||
{
|
||||
gameSpeed = GetGameSpeed(selectedGameSpeed);
|
||||
}
|
||||
|
||||
if (Math.Abs(gameSpeed - m_GameSpeed.floatValue) > 0.01f)
|
||||
{
|
||||
if (EditorApplication.isPlaying)
|
||||
{
|
||||
t.GameSpeed = gameSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_GameSpeed.floatValue = gameSpeed;
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
bool runInBackground = EditorGUILayout.Toggle("Run in Background", m_RunInBackground.boolValue);
|
||||
if (runInBackground != m_RunInBackground.boolValue)
|
||||
{
|
||||
if (EditorApplication.isPlaying)
|
||||
{
|
||||
t.RunInBackground = runInBackground;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RunInBackground.boolValue = runInBackground;
|
||||
}
|
||||
}
|
||||
|
||||
bool neverSleep = EditorGUILayout.Toggle("Never Sleep", m_NeverSleep.boolValue);
|
||||
if (neverSleep != m_NeverSleep.boolValue)
|
||||
{
|
||||
if (EditorApplication.isPlaying)
|
||||
{
|
||||
t.NeverSleep = neverSleep;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_NeverSleep.boolValue = neverSleep;
|
||||
}
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
protected override void OnCompileComplete()
|
||||
{
|
||||
base.OnCompileComplete();
|
||||
|
||||
RefreshTypeNames();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
m_EditorLanguage = serializedObject.FindProperty("m_EditorLanguage");
|
||||
m_TextHelperTypeName = serializedObject.FindProperty("m_TextHelperTypeName");
|
||||
m_VersionHelperTypeName = serializedObject.FindProperty("m_VersionHelperTypeName");
|
||||
m_LogHelperTypeName = serializedObject.FindProperty("m_LogHelperTypeName");
|
||||
m_CompressionHelperTypeName = serializedObject.FindProperty("m_CompressionHelperTypeName");
|
||||
m_JsonHelperTypeName = serializedObject.FindProperty("m_JsonHelperTypeName");
|
||||
m_FrameRate = serializedObject.FindProperty("m_FrameRate");
|
||||
m_GameSpeed = serializedObject.FindProperty("m_GameSpeed");
|
||||
m_RunInBackground = serializedObject.FindProperty("m_RunInBackground");
|
||||
m_NeverSleep = serializedObject.FindProperty("m_NeverSleep");
|
||||
|
||||
RefreshTypeNames();
|
||||
}
|
||||
|
||||
private void RefreshTypeNames()
|
||||
{
|
||||
List<string> textHelperTypeNames = new List<string>
|
||||
{
|
||||
NoneOptionName
|
||||
};
|
||||
|
||||
textHelperTypeNames.AddRange(Type.GetRuntimeTypeNames(typeof(Utility.Text.ITextHelper)));
|
||||
m_TextHelperTypeNames = textHelperTypeNames.ToArray();
|
||||
m_TextHelperTypeNameIndex = 0;
|
||||
if (!string.IsNullOrEmpty(m_TextHelperTypeName.stringValue))
|
||||
{
|
||||
m_TextHelperTypeNameIndex = textHelperTypeNames.IndexOf(m_TextHelperTypeName.stringValue);
|
||||
if (m_TextHelperTypeNameIndex <= 0)
|
||||
{
|
||||
m_TextHelperTypeNameIndex = 0;
|
||||
m_TextHelperTypeName.stringValue = null;
|
||||
}
|
||||
}
|
||||
|
||||
List<string> versionHelperTypeNames = new List<string>
|
||||
{
|
||||
NoneOptionName
|
||||
};
|
||||
|
||||
versionHelperTypeNames.AddRange(Type.GetRuntimeTypeNames(typeof(Version.IVersionHelper)));
|
||||
m_VersionHelperTypeNames = versionHelperTypeNames.ToArray();
|
||||
m_VersionHelperTypeNameIndex = 0;
|
||||
if (!string.IsNullOrEmpty(m_VersionHelperTypeName.stringValue))
|
||||
{
|
||||
m_VersionHelperTypeNameIndex = versionHelperTypeNames.IndexOf(m_VersionHelperTypeName.stringValue);
|
||||
if (m_VersionHelperTypeNameIndex <= 0)
|
||||
{
|
||||
m_VersionHelperTypeNameIndex = 0;
|
||||
m_VersionHelperTypeName.stringValue = null;
|
||||
}
|
||||
}
|
||||
|
||||
List<string> logHelperTypeNames = new List<string>
|
||||
{
|
||||
NoneOptionName
|
||||
};
|
||||
|
||||
logHelperTypeNames.AddRange(Type.GetRuntimeTypeNames(typeof(GameFrameworkLog.ILogHelper)));
|
||||
m_LogHelperTypeNames = logHelperTypeNames.ToArray();
|
||||
m_LogHelperTypeNameIndex = 0;
|
||||
if (!string.IsNullOrEmpty(m_LogHelperTypeName.stringValue))
|
||||
{
|
||||
m_LogHelperTypeNameIndex = logHelperTypeNames.IndexOf(m_LogHelperTypeName.stringValue);
|
||||
if (m_LogHelperTypeNameIndex <= 0)
|
||||
{
|
||||
m_LogHelperTypeNameIndex = 0;
|
||||
m_LogHelperTypeName.stringValue = null;
|
||||
}
|
||||
}
|
||||
|
||||
List<string> jsonHelperTypeNames = new List<string>
|
||||
{
|
||||
NoneOptionName
|
||||
};
|
||||
|
||||
jsonHelperTypeNames.AddRange(Type.GetRuntimeTypeNames(typeof(Utility.Json.IJsonHelper)));
|
||||
m_JsonHelperTypeNames = jsonHelperTypeNames.ToArray();
|
||||
m_JsonHelperTypeNameIndex = 0;
|
||||
if (!string.IsNullOrEmpty(m_JsonHelperTypeName.stringValue))
|
||||
{
|
||||
m_JsonHelperTypeNameIndex = jsonHelperTypeNames.IndexOf(m_JsonHelperTypeName.stringValue);
|
||||
if (m_JsonHelperTypeNameIndex <= 0)
|
||||
{
|
||||
m_JsonHelperTypeNameIndex = 0;
|
||||
m_JsonHelperTypeName.stringValue = null;
|
||||
}
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private float GetGameSpeed(int selectedGameSpeed)
|
||||
{
|
||||
if (selectedGameSpeed < 0)
|
||||
{
|
||||
return GameSpeed[0];
|
||||
}
|
||||
|
||||
if (selectedGameSpeed >= GameSpeed.Length)
|
||||
{
|
||||
return GameSpeed[GameSpeed.Length - 1];
|
||||
}
|
||||
|
||||
return GameSpeed[selectedGameSpeed];
|
||||
}
|
||||
|
||||
private int GetSelectedGameSpeed(float gameSpeed)
|
||||
{
|
||||
for (int i = 0; i < GameSpeed.Length; i++)
|
||||
{
|
||||
if (gameSpeed == GameSpeed[i])
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 250c436df9563f04881e590c3fc80e81
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,73 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Editor.Inspector
|
||||
{
|
||||
[CustomEditor(typeof(SettingModule))]
|
||||
internal sealed class SettingModuleInspector : GameFrameworkInspector
|
||||
{
|
||||
private HelperInfo<SettingHelperBase> m_SettingHelperInfo = new HelperInfo<SettingHelperBase>("Setting");
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
SettingModule t = (SettingModule)target;
|
||||
|
||||
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
|
||||
{
|
||||
m_SettingHelperInfo.Draw();
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
|
||||
{
|
||||
EditorGUILayout.LabelField("Setting Count", t.Count >= 0 ? t.Count.ToString() : "<Unknown>");
|
||||
if (t.Count > 0)
|
||||
{
|
||||
string[] settingNames = t.GetAllSettingNames();
|
||||
foreach (string settingName in settingNames)
|
||||
{
|
||||
EditorGUILayout.LabelField(settingName, t.GetString(settingName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (EditorApplication.isPlaying)
|
||||
{
|
||||
if (GUILayout.Button("Save Settings"))
|
||||
{
|
||||
t.Save();
|
||||
}
|
||||
if (GUILayout.Button("Remove All Settings"))
|
||||
{
|
||||
t.RemoveAllSettings();
|
||||
}
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
Repaint();
|
||||
}
|
||||
|
||||
protected override void OnCompileComplete()
|
||||
{
|
||||
base.OnCompileComplete();
|
||||
|
||||
RefreshTypeNames();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
m_SettingHelperInfo.Init(serializedObject);
|
||||
|
||||
RefreshTypeNames();
|
||||
}
|
||||
|
||||
private void RefreshTypeNames()
|
||||
{
|
||||
m_SettingHelperInfo.Refresh();
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ef9a06ba6ea31f47bf3f0ef922cf41b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,57 @@
|
||||
using UnityEditor;
|
||||
|
||||
namespace TEngine.Editor.Inspector
|
||||
{
|
||||
[CustomEditor(typeof(UIModule))]
|
||||
internal sealed class UIModuleInspector : GameFrameworkInspector
|
||||
{
|
||||
private SerializedProperty m_InstanceRoot = null;
|
||||
private SerializedProperty m_enableErrorLog = null;
|
||||
private SerializedProperty m_dontDestroyUIRoot = null;
|
||||
private SerializedProperty m_UICamera = null;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
UIModule t = (UIModule)target;
|
||||
|
||||
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
|
||||
{
|
||||
EditorGUILayout.PropertyField(m_InstanceRoot);
|
||||
EditorGUILayout.PropertyField(m_enableErrorLog);
|
||||
EditorGUILayout.PropertyField(m_dontDestroyUIRoot);
|
||||
EditorGUILayout.PropertyField(m_UICamera);
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
Repaint();
|
||||
}
|
||||
|
||||
protected override void OnCompileComplete()
|
||||
{
|
||||
base.OnCompileComplete();
|
||||
|
||||
RefreshTypeNames();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
m_InstanceRoot = serializedObject.FindProperty("m_InstanceRoot");
|
||||
m_enableErrorLog = serializedObject.FindProperty("m_enableErrorLog");
|
||||
m_dontDestroyUIRoot = serializedObject.FindProperty("m_dontDestroyUIRoot");
|
||||
m_UICamera = serializedObject.FindProperty("m_UICamera");
|
||||
|
||||
RefreshTypeNames();
|
||||
}
|
||||
|
||||
private void RefreshTypeNames()
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3d5af6a82ddad247810928f33f2c609
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
UnityProject/Assets/TEngine/Editor/Postprocessor.meta
Normal file
8
UnityProject/Assets/TEngine/Editor/Postprocessor.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f9e50268851a5c449725ae364307d7f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,494 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEditor.U2D;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
/// <summary>
|
||||
/// 图集导入管线。
|
||||
/// </summary>
|
||||
public class SpritePostprocessor : AssetPostprocessor
|
||||
{
|
||||
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
|
||||
{
|
||||
foreach (var s in importedAssets)
|
||||
{
|
||||
EditorSpriteSaveInfo.OnImportSprite(s);
|
||||
}
|
||||
|
||||
foreach (var s in deletedAssets)
|
||||
{
|
||||
EditorSpriteSaveInfo.OnDeleteSprite(s);
|
||||
}
|
||||
|
||||
foreach (var s in movedFromAssetPaths)
|
||||
{
|
||||
EditorSpriteSaveInfo.OnDeleteSprite(s);
|
||||
}
|
||||
|
||||
foreach (var s in movedAssets)
|
||||
{
|
||||
EditorSpriteSaveInfo.OnImportSprite(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class EditorSpriteSaveInfo
|
||||
{
|
||||
private const string NormalAtlasDir = "Assets/AssetArt/Atlas";
|
||||
private const string UISpritePath = "Assets/AssetRaw/UIRaw";
|
||||
private const string UIAtlasPath = "Assets/AssetRaw/UIRaw/Atlas";
|
||||
private const string UIRawPath = "Assets/AssetRaw/UIRaw/UIRaw";
|
||||
private static List<string> m_dirtyAtlasList = new List<string>();
|
||||
private static Dictionary<string, List<string>> m_allASprites = new Dictionary<string, List<string>>();
|
||||
private static Dictionary<string, string> m_uiAtlasMap = new Dictionary<string, string>();
|
||||
private static bool m_inited = false;
|
||||
private static bool m_dirty = false;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
if (m_inited)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EditorApplication.update += CheckDirty;
|
||||
}
|
||||
|
||||
public static void CheckDirty()
|
||||
{
|
||||
if (m_dirty)
|
||||
{
|
||||
m_dirty = false;
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
float lastProgress = -1;
|
||||
for (int i = 0; i < m_dirtyAtlasList.Count; i++)
|
||||
{
|
||||
string atlasName = m_dirtyAtlasList[i];
|
||||
Debug.Log("更新图集 : " + atlasName);
|
||||
var curProgress = (float)i / m_dirtyAtlasList.Count;
|
||||
if (curProgress > lastProgress + 0.01f)
|
||||
{
|
||||
lastProgress = curProgress;
|
||||
var progressText = $"当前进度:{i}/{m_dirtyAtlasList.Count} {atlasName}";
|
||||
bool cancel = EditorUtility.DisplayCancelableProgressBar("刷新图集" + atlasName, progressText, curProgress);
|
||||
if (cancel)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool isUI = atlasName.StartsWith("UIRaw");
|
||||
SaveAtlas(atlasName, isUI);
|
||||
}
|
||||
|
||||
EditorUtility.ClearProgressBar();
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
m_dirtyAtlasList.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnImportSprite(string assetPath)
|
||||
{
|
||||
if (!assetPath.StartsWith(UISpritePath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TextureImporter ti = AssetImporter.GetAtPath(assetPath) as TextureImporter;
|
||||
|
||||
if (ti != null)
|
||||
{
|
||||
var modify = false;
|
||||
|
||||
if (assetPath.StartsWith(UISpritePath))
|
||||
{
|
||||
if (ti.textureType != TextureImporterType.Sprite)
|
||||
{
|
||||
ti.textureType = TextureImporterType.Sprite;
|
||||
modify = true;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(ti.spritePackingTag))
|
||||
{
|
||||
ti.spritePackingTag = string.Empty;
|
||||
modify = true;
|
||||
}
|
||||
|
||||
var setting = new TextureImporterSettings();
|
||||
ti.ReadTextureSettings(setting);
|
||||
if (setting.spriteGenerateFallbackPhysicsShape)
|
||||
{
|
||||
setting.spriteGenerateFallbackPhysicsShape = false;
|
||||
ti.SetTextureSettings(setting);
|
||||
modify = true;
|
||||
}
|
||||
|
||||
if (IsKeepRawImage(assetPath))
|
||||
{
|
||||
//调整android格式
|
||||
var andPlatformSettings = ti.GetPlatformTextureSettings("Android");
|
||||
if (!andPlatformSettings.overridden)
|
||||
{
|
||||
andPlatformSettings.overridden = true;
|
||||
modify = true;
|
||||
}
|
||||
|
||||
if (andPlatformSettings.format != TextureImporterFormat.ASTC_6x6)
|
||||
{
|
||||
andPlatformSettings.format = TextureImporterFormat.ASTC_6x6;
|
||||
ti.SetPlatformTextureSettings(andPlatformSettings);
|
||||
modify = true;
|
||||
}
|
||||
|
||||
//调整ios格式
|
||||
var iosPlatformSettings = ti.GetPlatformTextureSettings("iPhone");
|
||||
if (!iosPlatformSettings.overridden)
|
||||
{
|
||||
iosPlatformSettings.overridden = true;
|
||||
modify = true;
|
||||
}
|
||||
|
||||
if (iosPlatformSettings.format != TextureImporterFormat.ASTC_5x5)
|
||||
{
|
||||
iosPlatformSettings.format = TextureImporterFormat.ASTC_5x5;
|
||||
iosPlatformSettings.compressionQuality = 50;
|
||||
ti.SetPlatformTextureSettings(iosPlatformSettings);
|
||||
modify = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (modify)
|
||||
{
|
||||
ti.SaveAndReimport();
|
||||
}
|
||||
|
||||
if (ti.textureType == TextureImporterType.Sprite)
|
||||
{
|
||||
OnProcessSprite(assetPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否保持散图(不打图集)
|
||||
/// </summary>
|
||||
/// <param name="dirPath"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsKeepRawImage(string dirPath)
|
||||
{
|
||||
return dirPath.Contains("UIRaw/Raw/") || dirPath.Contains("UIRaw_Raw_");
|
||||
}
|
||||
|
||||
public static string GetSpritePath(string assetPath)
|
||||
{
|
||||
string path = assetPath.Substring(0, assetPath.LastIndexOf("."));
|
||||
path = path.Replace("Assets/AssetRaw/", "");
|
||||
return path;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据文件路径,返回图集名称
|
||||
/// </summary>
|
||||
/// <param name="fullName"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetPackageTag(string fullName)
|
||||
{
|
||||
fullName = fullName.Replace("\\", "/");
|
||||
int idx = fullName.LastIndexOf("UIRaw", StringComparison.Ordinal);
|
||||
if (idx == -1)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
if (IsKeepRawImage(fullName))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
var atlasPath = fullName.Substring(idx);
|
||||
string str = atlasPath;
|
||||
str = str.Substring(0, str.LastIndexOf("/", StringComparison.Ordinal)).Replace("/", "_");
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
public static void OnProcessSprite(string assetPath)
|
||||
{
|
||||
if (!assetPath.StartsWith("Assets"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (assetPath.StartsWith("Assets/UIRaw_Delete"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Init();
|
||||
|
||||
var spriteName = Path.GetFileNameWithoutExtension(assetPath);
|
||||
var spritePath = GetSpritePath(assetPath);
|
||||
if (!m_uiAtlasMap.TryGetValue(spriteName, out string oldAssetPath) || spritePath == oldAssetPath)
|
||||
{
|
||||
m_uiAtlasMap[spriteName] = spritePath;
|
||||
m_dirty = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"有重名的图片:{spriteName}\n旧图集:{oldAssetPath}\n新图集:{spritePath} ");
|
||||
m_uiAtlasMap[spriteName] = spritePath;
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
string atlasName = GetPackageTag(assetPath);
|
||||
if (string.IsNullOrEmpty(atlasName))
|
||||
{
|
||||
bool keepRaw = IsKeepRawImage(assetPath);
|
||||
if (!keepRaw)
|
||||
{
|
||||
Debug.LogError($"empty packingTag of asset :{assetPath} !!!");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
List<string> ret;
|
||||
if (!m_allASprites.TryGetValue(atlasName, out ret))
|
||||
{
|
||||
ret = new List<string>();
|
||||
m_allASprites.Add(atlasName, ret);
|
||||
}
|
||||
|
||||
if (!ret.Contains(assetPath))
|
||||
{
|
||||
ret.Add(assetPath);
|
||||
m_dirty = true;
|
||||
if (!m_dirtyAtlasList.Contains(atlasName))
|
||||
{
|
||||
m_dirtyAtlasList.Add(atlasName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnDeleteSprite(string assetPath)
|
||||
{
|
||||
if (assetPath.StartsWith("Assets/UIRaw_Delete"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!assetPath.StartsWith(UISpritePath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Init();
|
||||
string atlasName = GetPackageTag(assetPath);
|
||||
if (!m_allASprites.TryGetValue(atlasName, out var ret))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//改成文件名的匹配
|
||||
if (!ret.Exists(s => Path.GetFileName(s) == Path.GetFileName(assetPath)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (assetPath.StartsWith(UISpritePath))
|
||||
{
|
||||
var spriteName = Path.GetFileNameWithoutExtension(assetPath);
|
||||
if (m_uiAtlasMap.ContainsKey(spriteName))
|
||||
{
|
||||
m_uiAtlasMap.Remove(spriteName);
|
||||
m_dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
ret.Remove(assetPath);
|
||||
m_dirty = true;
|
||||
if (!m_dirtyAtlasList.Contains(atlasName))
|
||||
{
|
||||
m_dirtyAtlasList.Add(atlasName);
|
||||
}
|
||||
}
|
||||
|
||||
#region 更新图集
|
||||
|
||||
public static void SaveAtlas(string atlasName, bool isUI)
|
||||
{
|
||||
List<Object> spriteList = new List<Object>();
|
||||
if (m_allASprites.TryGetValue(atlasName, out var list))
|
||||
{
|
||||
list.Sort(StringComparer.Ordinal);
|
||||
|
||||
foreach (var s in list)
|
||||
{
|
||||
var sprite = AssetDatabase.LoadAssetAtPath<Sprite>(s);
|
||||
if (sprite != null)
|
||||
{
|
||||
spriteList.Add(sprite);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var pathv2 = $"{NormalAtlasDir}/{atlasName}.spriteatlasv2";
|
||||
var path = $"{NormalAtlasDir}/{atlasName}.asset";
|
||||
|
||||
if (spriteList.Count == 0)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
AssetDatabase.DeleteAsset(path);
|
||||
}
|
||||
if (File.Exists(pathv2))
|
||||
{
|
||||
AssetDatabase.DeleteAsset(pathv2);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var atlas = new SpriteAtlasAsset();
|
||||
var setting = new SpriteAtlasPackingSettings
|
||||
{
|
||||
blockOffset = 1,
|
||||
padding = 2,
|
||||
enableRotation = true
|
||||
};
|
||||
|
||||
bool isOpaque = atlasName.Contains("Opaque");
|
||||
|
||||
var textureSetting = new SpriteAtlasTextureSettings
|
||||
{
|
||||
generateMipMaps = false,
|
||||
sRGB = true,
|
||||
filterMode = FilterMode.Bilinear
|
||||
};
|
||||
atlas.SetTextureSettings(textureSetting);
|
||||
|
||||
var iphonePlatformSetting = atlas.GetPlatformSettings("iPhone");
|
||||
if (!iphonePlatformSetting.overridden)
|
||||
{
|
||||
iphonePlatformSetting.overridden = true;
|
||||
iphonePlatformSetting.format = isOpaque ? TextureImporterFormat.ASTC_5x5 : TextureImporterFormat.ASTC_5x5;
|
||||
iphonePlatformSetting.compressionQuality = 100;
|
||||
atlas.SetPlatformSettings(iphonePlatformSetting);
|
||||
}
|
||||
|
||||
var androidPlatformSetting = atlas.GetPlatformSettings("Android");
|
||||
if (isOpaque && !androidPlatformSetting.overridden)
|
||||
{
|
||||
androidPlatformSetting.overridden = true;
|
||||
androidPlatformSetting.format = TextureImporterFormat.ETC_RGB4;
|
||||
androidPlatformSetting.compressionQuality = 100;
|
||||
atlas.SetPlatformSettings(androidPlatformSetting);
|
||||
}
|
||||
|
||||
atlas.SetPackingSettings(setting);
|
||||
atlas.Add(spriteList.ToArray());
|
||||
|
||||
AssetDatabase.CreateAsset(atlas, path);
|
||||
File.Move(path, pathv2);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 重新生成图集
|
||||
|
||||
private static Dictionary<string, List<string>> m_tempAllASprites = new Dictionary<string, List<string>>();
|
||||
|
||||
[MenuItem("TEngine/图集/重新生成UI图集")]
|
||||
static void ForceGenAtlas()
|
||||
{
|
||||
Init();
|
||||
List<string> needSaveAtlas = new List<string>();
|
||||
m_tempAllASprites.Clear();
|
||||
var findAssets = AssetDatabase.FindAssets("t:sprite", new[] { UIAtlasPath });
|
||||
foreach (var findAsset in findAssets)
|
||||
{
|
||||
var path = AssetDatabase.GUIDToAssetPath(findAsset);
|
||||
var atlasName = GetPackageTag(path);
|
||||
if (!m_tempAllASprites.TryGetValue(atlasName, out var spriteList))
|
||||
{
|
||||
spriteList = new List<string>();
|
||||
m_tempAllASprites[atlasName] = spriteList;
|
||||
}
|
||||
|
||||
if (!spriteList.Contains(path))
|
||||
{
|
||||
spriteList.Add(path);
|
||||
}
|
||||
}
|
||||
|
||||
//有变化的才刷
|
||||
var iter = m_tempAllASprites.GetEnumerator();
|
||||
while (iter.MoveNext())
|
||||
{
|
||||
bool needSave = false;
|
||||
var atlasName = iter.Current.Key;
|
||||
var newSpritesList = iter.Current.Value;
|
||||
|
||||
if (m_allASprites.TryGetValue(atlasName, out var existSprites))
|
||||
{
|
||||
if (existSprites.Count != newSpritesList.Count)
|
||||
{
|
||||
needSave = true;
|
||||
existSprites.Clear();
|
||||
existSprites.AddRange(newSpritesList);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < newSpritesList.Count; i++)
|
||||
{
|
||||
if (!existSprites.Contains(newSpritesList[i]))
|
||||
{
|
||||
needSave = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (needSave)
|
||||
{
|
||||
existSprites.Clear();
|
||||
existSprites.AddRange(newSpritesList);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
needSave = true;
|
||||
m_allASprites.Add(atlasName, new List<string>(newSpritesList));
|
||||
}
|
||||
|
||||
if (needSave && !needSaveAtlas.Contains(atlasName))
|
||||
{
|
||||
needSaveAtlas.Add(atlasName);
|
||||
}
|
||||
}
|
||||
|
||||
iter.Dispose();
|
||||
foreach (var atlas in needSaveAtlas)
|
||||
{
|
||||
Debug.LogFormat("Gen atlas:{0}", atlas);
|
||||
SaveAtlas(atlas, true);
|
||||
}
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
SpriteAtlasUtility.PackAllAtlases(EditorUserBuildSettings.activeBuildTarget);
|
||||
Debug.Log("Gen end");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0b37506bd00c3f14d83f966ae20ba8ec
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
3
UnityProject/Assets/TEngine/Editor/Resource.meta
Normal file
3
UnityProject/Assets/TEngine/Editor/Resource.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86e1ceb0af034fc0aca146e58c0be5ae
|
||||
timeCreated: 1694879395
|
@@ -0,0 +1,26 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Editor.Resource
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源引用编辑器拓展。
|
||||
/// </summary>
|
||||
[CustomEditor(typeof(AssetReference), true)]
|
||||
public class AssetReferenceEditor : UnityEditor.Editor
|
||||
{
|
||||
private AssetReference _target;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_target = (AssetReference)target;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd6cd0c1877e4e758d03e4f6fdfa96ad
|
||||
timeCreated: 1683733968
|
41
UnityProject/Assets/TEngine/Editor/Resource/Encryption.cs
Normal file
41
UnityProject/Assets/TEngine/Editor/Resource/Encryption.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using TEngine;
|
||||
using YooAsset;
|
||||
|
||||
namespace TEngine.Editor.Resource
|
||||
{
|
||||
public class FileOffsetEncryption : IEncryptionServices
|
||||
{
|
||||
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
|
||||
{
|
||||
int offset = 32;
|
||||
byte[] fileData = File.ReadAllBytes(fileInfo.FilePath);
|
||||
var encryptedData = new byte[fileData.Length + offset];
|
||||
Buffer.BlockCopy(fileData, 0, encryptedData, offset, fileData.Length);
|
||||
|
||||
EncryptResult result = new EncryptResult();
|
||||
result.LoadMethod = EBundleLoadMethod.LoadFromFileOffset;
|
||||
result.EncryptedData = encryptedData;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public class FileStreamEncryption : IEncryptionServices
|
||||
{
|
||||
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
|
||||
{
|
||||
// LoadFromStream
|
||||
var fileData = File.ReadAllBytes(fileInfo.FilePath);
|
||||
for (int i = 0; i < fileData.Length; i++)
|
||||
{
|
||||
fileData[i] ^= BundleStream.KEY;
|
||||
}
|
||||
|
||||
EncryptResult result = new EncryptResult();
|
||||
result.LoadMethod = EBundleLoadMethod.LoadFromStream;
|
||||
result.EncryptedData = fileData;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 37d5ebb52d476484c974184f2c8eb818
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
21
UnityProject/Assets/TEngine/Editor/TEngine.Editor.asmdef
Normal file
21
UnityProject/Assets/TEngine/Editor/TEngine.Editor.asmdef
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "TEngine.Editor",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:24c092aee38482f4e80715eaa8148782",
|
||||
"GUID:e34a5702dd353724aa315fb8011f08c3",
|
||||
"GUID:4d1926c9df5b052469a1c63448b7609a",
|
||||
"GUID:2373f786d14518f44b0f475db77ba4de"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 48c39f1caa38fbd4e99e4c330e531180
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
UnityProject/Assets/TEngine/Editor/ToolbarExtender.meta
Normal file
8
UnityProject/Assets/TEngine/Editor/ToolbarExtender.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 81dccabae12b7f64086d54bc04a85de0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 075130c21aee41b49b3977adc2bfa288
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20dbf6614352aaf488de29690deeab68
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb0502859d7561142a3408d0ce2a19d8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,91 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityToolbarExtender;
|
||||
|
||||
namespace TEngine
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
public class EditorResourceMode
|
||||
{
|
||||
static class ToolbarStyles
|
||||
{
|
||||
public static readonly GUIStyle ToolBarExtenderBtnStyle;
|
||||
|
||||
public static readonly GUIStyle ToolBarTextStyle;
|
||||
|
||||
public static readonly GUIStyle ToolBarButtonGuiStyle;
|
||||
|
||||
static ToolbarStyles()
|
||||
{
|
||||
ToolBarExtenderBtnStyle = new GUIStyle("Command")
|
||||
{
|
||||
fontSize = 12,
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
imagePosition = ImagePosition.ImageAbove,
|
||||
fontStyle = FontStyle.Normal,
|
||||
fixedWidth = 60
|
||||
};
|
||||
|
||||
ToolBarTextStyle = new GUIStyle(ButtonStyleName)
|
||||
{
|
||||
padding = new RectOffset(2, 8, 2, 2),
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
fontStyle = FontStyle.Bold
|
||||
};
|
||||
|
||||
ToolBarButtonGuiStyle = new GUIStyle(ButtonStyleName)
|
||||
{
|
||||
padding = new RectOffset(2, 8, 2, 2),
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
fontStyle = FontStyle.Bold
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static EditorResourceMode()
|
||||
{
|
||||
ToolbarExtender.RightToolbarGUI.Add(OnToolbarGUI);
|
||||
_resourceModeIndex = EditorPrefs.GetInt("EditorResourceMode", 0);
|
||||
}
|
||||
|
||||
private const string ButtonStyleName = "Tab middle";
|
||||
static GUIStyle _buttonGuiStyle;
|
||||
|
||||
private static readonly string[] _resourceModeNames =
|
||||
{ "EditorMode (编辑器下的模拟模式)",
|
||||
"OfflinePlayMode (单机模式)",
|
||||
"HostPlayMode (联机运行模式)",
|
||||
"WebPlayMode (WebGL运行模式)"
|
||||
};
|
||||
|
||||
private static int _resourceModeIndex = 0;
|
||||
public static int ResourceModeIndex => _resourceModeIndex;
|
||||
|
||||
static void OnToolbarGUI()
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
|
||||
{
|
||||
// GUILayout.Label("资源加载模式:",ToolbarStyles.ToolBarTextStyle);
|
||||
|
||||
GUILayout.Space(10);
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
// 资源模式
|
||||
int selectedIndex = EditorGUILayout.Popup("", _resourceModeIndex, _resourceModeNames, ToolbarStyles.ToolBarButtonGuiStyle);
|
||||
// ReSharper disable once RedundantCheckBeforeAssignment
|
||||
if (selectedIndex != _resourceModeIndex)
|
||||
{
|
||||
Debug.Log($"更改编辑器资源运行模式 : {_resourceModeNames[selectedIndex]}");
|
||||
_resourceModeIndex = selectedIndex;
|
||||
EditorPrefs.SetInt("EditorResourceMode", selectedIndex);
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
GUILayout.Space(400);
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ab26dd2998d84a08b35c0132e1814199
|
||||
timeCreated: 1683857308
|
@@ -0,0 +1,84 @@
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityToolbarExtender;
|
||||
|
||||
namespace TEngine
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
public class SceneSwitchLeftButton
|
||||
{
|
||||
private static readonly string SceneMain = "main";
|
||||
|
||||
static SceneSwitchLeftButton()
|
||||
{
|
||||
ToolbarExtender.LeftToolbarGUI.Add(OnToolbarGUI);
|
||||
}
|
||||
|
||||
static readonly string ButtonStyleName = "Tab middle";
|
||||
static GUIStyle _buttonGuiStyle;
|
||||
|
||||
static void OnToolbarGUI()
|
||||
{
|
||||
_buttonGuiStyle ??= new GUIStyle(ButtonStyleName)
|
||||
{
|
||||
padding = new RectOffset(2, 8, 2, 2),
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
fontStyle = FontStyle.Bold
|
||||
};
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button(
|
||||
new GUIContent("Launcher", EditorGUIUtility.FindTexture("PlayButton"), $"Start Scene Launcher"),
|
||||
_buttonGuiStyle))
|
||||
{
|
||||
SceneHelper.StartScene(SceneMain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class SceneHelper
|
||||
{
|
||||
static string _sceneToOpen;
|
||||
|
||||
public static void StartScene(string sceneName)
|
||||
{
|
||||
if (EditorApplication.isPlaying)
|
||||
{
|
||||
EditorApplication.isPlaying = false;
|
||||
}
|
||||
|
||||
_sceneToOpen = sceneName;
|
||||
EditorApplication.update += OnUpdate;
|
||||
}
|
||||
|
||||
static void OnUpdate()
|
||||
{
|
||||
if (_sceneToOpen == null ||
|
||||
EditorApplication.isPlaying || EditorApplication.isPaused ||
|
||||
EditorApplication.isCompiling || EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EditorApplication.update -= OnUpdate;
|
||||
|
||||
if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
|
||||
{
|
||||
string[] guids = AssetDatabase.FindAssets("t:scene " + _sceneToOpen, null);
|
||||
if (guids.Length == 0)
|
||||
{
|
||||
Debug.LogWarning("Couldn't find scene file");
|
||||
}
|
||||
else
|
||||
{
|
||||
string scenePath = AssetDatabase.GUIDToAssetPath(guids[0]);
|
||||
EditorSceneManager.OpenScene(scenePath);
|
||||
EditorApplication.isPlaying = true;
|
||||
}
|
||||
}
|
||||
|
||||
_sceneToOpen = null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 45017e4df12424c4fb16db4708d239f0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,111 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Reflection;
|
||||
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
using UnityEngine.UIElements;
|
||||
#else
|
||||
using UnityEngine.Experimental.UIElements;
|
||||
#endif
|
||||
|
||||
namespace UnityToolbarExtender
|
||||
{
|
||||
public static class ToolbarCallback
|
||||
{
|
||||
static Type m_toolbarType = typeof(Editor).Assembly.GetType("UnityEditor.Toolbar");
|
||||
static Type m_guiViewType = typeof(Editor).Assembly.GetType("UnityEditor.GUIView");
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
static Type m_iWindowBackendType = typeof(Editor).Assembly.GetType("UnityEditor.IWindowBackend");
|
||||
static PropertyInfo m_windowBackend = m_guiViewType.GetProperty("windowBackend",
|
||||
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
static PropertyInfo m_viewVisualTree = m_iWindowBackendType.GetProperty("visualTree",
|
||||
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
#else
|
||||
static PropertyInfo m_viewVisualTree = m_guiViewType.GetProperty("visualTree",
|
||||
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
#endif
|
||||
static FieldInfo m_imguiContainerOnGui = typeof(IMGUIContainer).GetField("m_OnGUIHandler",
|
||||
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
static ScriptableObject m_currentToolbar;
|
||||
|
||||
/// <summary>
|
||||
/// Callback for toolbar OnGUI method.
|
||||
/// </summary>
|
||||
public static Action OnToolbarGUI;
|
||||
public static Action OnToolbarGUILeft;
|
||||
public static Action OnToolbarGUIRight;
|
||||
|
||||
static ToolbarCallback()
|
||||
{
|
||||
EditorApplication.update -= OnUpdate;
|
||||
EditorApplication.update += OnUpdate;
|
||||
}
|
||||
|
||||
static void OnUpdate()
|
||||
{
|
||||
// Relying on the fact that toolbar is ScriptableObject and gets deleted when layout changes
|
||||
if (m_currentToolbar == null)
|
||||
{
|
||||
// Find toolbar
|
||||
var toolbars = Resources.FindObjectsOfTypeAll(m_toolbarType);
|
||||
m_currentToolbar = toolbars.Length > 0 ? (ScriptableObject) toolbars[0] : null;
|
||||
if (m_currentToolbar != null)
|
||||
{
|
||||
#if UNITY_2021_1_OR_NEWER
|
||||
var root = m_currentToolbar.GetType().GetField("m_Root", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
var rawRoot = root.GetValue(m_currentToolbar);
|
||||
var mRoot = rawRoot as VisualElement;
|
||||
RegisterCallback("ToolbarZoneLeftAlign", OnToolbarGUILeft);
|
||||
RegisterCallback("ToolbarZoneRightAlign", OnToolbarGUIRight);
|
||||
|
||||
void RegisterCallback(string root, Action cb) {
|
||||
var toolbarZone = mRoot.Q(root);
|
||||
|
||||
var parent = new VisualElement()
|
||||
{
|
||||
style = {
|
||||
flexGrow = 1,
|
||||
flexDirection = FlexDirection.Row,
|
||||
}
|
||||
};
|
||||
var container = new IMGUIContainer();
|
||||
container.style.flexGrow = 1;
|
||||
container.onGUIHandler += () => {
|
||||
cb?.Invoke();
|
||||
};
|
||||
parent.Add(container);
|
||||
toolbarZone.Add(parent);
|
||||
}
|
||||
#else
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
var windowBackend = m_windowBackend.GetValue(m_currentToolbar);
|
||||
|
||||
// Get it's visual tree
|
||||
var visualTree = (VisualElement) m_viewVisualTree.GetValue(windowBackend, null);
|
||||
#else
|
||||
// Get it's visual tree
|
||||
var visualTree = (VisualElement) m_viewVisualTree.GetValue(m_currentToolbar, null);
|
||||
#endif
|
||||
|
||||
// Get first child which 'happens' to be toolbar IMGUIContainer
|
||||
var container = (IMGUIContainer) visualTree[0];
|
||||
|
||||
// (Re)attach handler
|
||||
var handler = (Action) m_imguiContainerOnGui.GetValue(container);
|
||||
handler -= OnGUI;
|
||||
handler += OnGUI;
|
||||
m_imguiContainerOnGui.SetValue(container, handler);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void OnGUI()
|
||||
{
|
||||
var handler = OnToolbarGUI;
|
||||
if (handler != null) handler();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4314ecffdfd1d90488e39e9ae35d14a1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,169 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityToolbarExtender
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
public static class ToolbarExtender
|
||||
{
|
||||
static int m_toolCount;
|
||||
static GUIStyle m_commandStyle = null;
|
||||
|
||||
public static readonly List<Action> LeftToolbarGUI = new List<Action>();
|
||||
public static readonly List<Action> RightToolbarGUI = new List<Action>();
|
||||
|
||||
static ToolbarExtender()
|
||||
{
|
||||
Type toolbarType = typeof(Editor).Assembly.GetType("UnityEditor.Toolbar");
|
||||
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
string fieldName = "k_ToolCount";
|
||||
#else
|
||||
string fieldName = "s_ShownToolIcons";
|
||||
#endif
|
||||
|
||||
FieldInfo toolIcons = toolbarType.GetField(fieldName,
|
||||
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
|
||||
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
m_toolCount = toolIcons != null ? ((int) toolIcons.GetValue(null)) : 8;
|
||||
#elif UNITY_2019_1_OR_NEWER
|
||||
m_toolCount = toolIcons != null ? ((int) toolIcons.GetValue(null)) : 7;
|
||||
#elif UNITY_2018_1_OR_NEWER
|
||||
m_toolCount = toolIcons != null ? ((Array) toolIcons.GetValue(null)).Length : 6;
|
||||
#else
|
||||
m_toolCount = toolIcons != null ? ((Array) toolIcons.GetValue(null)).Length : 5;
|
||||
#endif
|
||||
|
||||
ToolbarCallback.OnToolbarGUI = OnGUI;
|
||||
ToolbarCallback.OnToolbarGUILeft = GUILeft;
|
||||
ToolbarCallback.OnToolbarGUIRight = GUIRight;
|
||||
}
|
||||
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
public const float space = 8;
|
||||
#else
|
||||
public const float space = 10;
|
||||
#endif
|
||||
public const float largeSpace = 20;
|
||||
public const float buttonWidth = 32;
|
||||
public const float dropdownWidth = 80;
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
public const float playPauseStopWidth = 140;
|
||||
#else
|
||||
public const float playPauseStopWidth = 100;
|
||||
#endif
|
||||
|
||||
static void OnGUI()
|
||||
{
|
||||
// Create two containers, left and right
|
||||
// Screen is whole toolbar
|
||||
|
||||
if (m_commandStyle == null)
|
||||
{
|
||||
m_commandStyle = new GUIStyle("CommandLeft");
|
||||
}
|
||||
|
||||
var screenWidth = EditorGUIUtility.currentViewWidth;
|
||||
|
||||
// Following calculations match code reflected from Toolbar.OldOnGUI()
|
||||
float playButtonsPosition = Mathf.RoundToInt ((screenWidth - playPauseStopWidth) / 2);
|
||||
|
||||
Rect leftRect = new Rect(0, 0, screenWidth, Screen.height);
|
||||
leftRect.xMin += space; // Spacing left
|
||||
leftRect.xMin += buttonWidth * m_toolCount; // Tool buttons
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
leftRect.xMin += space; // Spacing between tools and pivot
|
||||
#else
|
||||
leftRect.xMin += largeSpace; // Spacing between tools and pivot
|
||||
#endif
|
||||
leftRect.xMin += 64 * 2; // Pivot buttons
|
||||
leftRect.xMax = playButtonsPosition;
|
||||
|
||||
Rect rightRect = new Rect(0, 0, screenWidth, Screen.height);
|
||||
rightRect.xMin = playButtonsPosition;
|
||||
rightRect.xMin += m_commandStyle.fixedWidth * 3; // Play buttons
|
||||
rightRect.xMax = screenWidth;
|
||||
rightRect.xMax -= space; // Spacing right
|
||||
rightRect.xMax -= dropdownWidth; // Layout
|
||||
rightRect.xMax -= space; // Spacing between layout and layers
|
||||
rightRect.xMax -= dropdownWidth; // Layers
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
rightRect.xMax -= space; // Spacing between layers and account
|
||||
#else
|
||||
rightRect.xMax -= largeSpace; // Spacing between layers and account
|
||||
#endif
|
||||
rightRect.xMax -= dropdownWidth; // Account
|
||||
rightRect.xMax -= space; // Spacing between account and cloud
|
||||
rightRect.xMax -= buttonWidth; // Cloud
|
||||
rightRect.xMax -= space; // Spacing between cloud and collab
|
||||
rightRect.xMax -= 78; // Colab
|
||||
|
||||
// Add spacing around existing controls
|
||||
leftRect.xMin += space;
|
||||
leftRect.xMax -= space;
|
||||
rightRect.xMin += space;
|
||||
rightRect.xMax -= space;
|
||||
|
||||
// Add top and bottom margins
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
leftRect.y = 4;
|
||||
leftRect.height = 22;
|
||||
rightRect.y = 4;
|
||||
rightRect.height = 22;
|
||||
#else
|
||||
leftRect.y = 5;
|
||||
leftRect.height = 24;
|
||||
rightRect.y = 5;
|
||||
rightRect.height = 24;
|
||||
#endif
|
||||
|
||||
if (leftRect.width > 0)
|
||||
{
|
||||
GUILayout.BeginArea(leftRect);
|
||||
GUILayout.BeginHorizontal();
|
||||
foreach (var handler in LeftToolbarGUI)
|
||||
{
|
||||
handler();
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
|
||||
if (rightRect.width > 0)
|
||||
{
|
||||
GUILayout.BeginArea(rightRect);
|
||||
GUILayout.BeginHorizontal();
|
||||
foreach (var handler in RightToolbarGUI)
|
||||
{
|
||||
handler();
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
}
|
||||
|
||||
public static void GUILeft() {
|
||||
GUILayout.BeginHorizontal();
|
||||
foreach (var handler in LeftToolbarGUI)
|
||||
{
|
||||
handler();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
public static void GUIRight() {
|
||||
GUILayout.BeginHorizontal();
|
||||
foreach (var handler in RightToolbarGUI)
|
||||
{
|
||||
handler();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b71421f0295dfa4f9c32f3ace45690d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
3
UnityProject/Assets/TEngine/Editor/UI.meta
Normal file
3
UnityProject/Assets/TEngine/Editor/UI.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b2fcf4655c847ef95af68f68fc9fc0a
|
||||
timeCreated: 1695286287
|
335
UnityProject/Assets/TEngine/Editor/UI/ScriptGenerator.cs
Normal file
335
UnityProject/Assets/TEngine/Editor/UI/ScriptGenerator.cs
Normal file
@@ -0,0 +1,335 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Editor.UI
|
||||
{
|
||||
public class ScriptGenerator
|
||||
{
|
||||
private const string Gap = "/";
|
||||
|
||||
[MenuItem("GameObject/ScriptGenerator/UIProperty", priority = 41)]
|
||||
public static void MemberProperty()
|
||||
{
|
||||
Generate(false);
|
||||
}
|
||||
|
||||
[MenuItem("GameObject/ScriptGenerator/UIProperty - UniTask", priority = 43)]
|
||||
public static void MemberPropertyUniTask()
|
||||
{
|
||||
Generate(false, true);
|
||||
}
|
||||
|
||||
[MenuItem("GameObject/ScriptGenerator/UIPropertyAndListener", priority = 42)]
|
||||
public static void MemberPropertyAndListener()
|
||||
{
|
||||
Generate(true);
|
||||
}
|
||||
|
||||
[MenuItem("GameObject/ScriptGenerator/UIPropertyAndListener - UniTask", priority = 44)]
|
||||
public static void MemberPropertyAndListenerUniTask()
|
||||
{
|
||||
Generate(true, true);
|
||||
}
|
||||
|
||||
private static void Generate(bool includeListener, bool isUniTask = false)
|
||||
{
|
||||
var root = Selection.activeTransform;
|
||||
if (root != null)
|
||||
{
|
||||
StringBuilder strVar = new StringBuilder();
|
||||
StringBuilder strBind = new StringBuilder();
|
||||
StringBuilder strOnCreate = new StringBuilder();
|
||||
StringBuilder strCallback = new StringBuilder();
|
||||
Ergodic(root, root, ref strVar, ref strBind, ref strOnCreate, ref strCallback, isUniTask);
|
||||
StringBuilder strFile = new StringBuilder();
|
||||
|
||||
if (includeListener)
|
||||
{
|
||||
#if ENABLE_TEXTMESHPRO
|
||||
strFile.Append("using TMPro;\n");
|
||||
#endif
|
||||
if (isUniTask)
|
||||
{
|
||||
strFile.Append("using Cysharp.Threading.Tasks;\n");
|
||||
}
|
||||
|
||||
strFile.Append("using UnityEngine;\n");
|
||||
strFile.Append("using UnityEngine.UI;\n");
|
||||
strFile.Append("using TEngine;\n\n");
|
||||
strFile.Append($"namespace {SettingsUtils.GetUINameSpace()}\n");
|
||||
strFile.Append("{\n");
|
||||
strFile.Append("\t[Window(UILayer.UI)]\n");
|
||||
strFile.Append("\tclass " + root.name + " : UIWindow\n");
|
||||
strFile.Append("\t{\n");
|
||||
}
|
||||
|
||||
// 脚本工具生成的代码
|
||||
strFile.Append("\t\t#region 脚本工具生成的代码\n");
|
||||
strFile.Append(strVar);
|
||||
strFile.Append("\t\tpublic override void ScriptGenerator()\n");
|
||||
strFile.Append("\t\t{\n");
|
||||
strFile.Append(strBind);
|
||||
strFile.Append(strOnCreate);
|
||||
strFile.Append("\t\t}\n");
|
||||
strFile.Append("\t\t#endregion");
|
||||
|
||||
if (includeListener)
|
||||
{
|
||||
strFile.Append("\n\n");
|
||||
// #region 事件
|
||||
strFile.Append("\t\t#region 事件\n");
|
||||
strFile.Append(strCallback);
|
||||
strFile.Append("\t\t#endregion\n\n");
|
||||
|
||||
strFile.Append("\t}\n");
|
||||
strFile.Append("}\n");
|
||||
}
|
||||
|
||||
TextEditor te = new TextEditor();
|
||||
te.text = strFile.ToString();
|
||||
te.SelectAll();
|
||||
te.Copy();
|
||||
}
|
||||
}
|
||||
|
||||
private static void Ergodic(Transform root, Transform transform, ref StringBuilder strVar, ref StringBuilder strBind, ref StringBuilder strOnCreate,
|
||||
ref StringBuilder strCallback, bool isUniTask)
|
||||
{
|
||||
for (int i = 0; i < transform.childCount; ++i)
|
||||
{
|
||||
Transform child = transform.GetChild(i);
|
||||
WriteScript(root, child, ref strVar, ref strBind, ref strOnCreate, ref strCallback, isUniTask);
|
||||
if (child.name.StartsWith("m_item"))
|
||||
{
|
||||
// 子 Item 不再往下遍历
|
||||
continue;
|
||||
}
|
||||
|
||||
Ergodic(root, child, ref strVar, ref strBind, ref strOnCreate, ref strCallback, isUniTask);
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetRelativePath(Transform child, Transform root)
|
||||
{
|
||||
StringBuilder path = new StringBuilder();
|
||||
path.Append(child.name);
|
||||
while (child.parent != null && child.parent != root)
|
||||
{
|
||||
child = child.parent;
|
||||
path.Insert(0, Gap);
|
||||
path.Insert(0, child.name);
|
||||
}
|
||||
|
||||
return path.ToString();
|
||||
}
|
||||
|
||||
public static string GetBtnFuncName(string varName)
|
||||
{
|
||||
return "OnClick" + varName.Replace("m_btn", string.Empty) + "Btn";
|
||||
}
|
||||
|
||||
public static string GetToggleFuncName(string varName)
|
||||
{
|
||||
return "OnToggle" + varName.Replace("m_toggle", string.Empty) + "Change";
|
||||
}
|
||||
|
||||
public static string GetSliderFuncName(string varName)
|
||||
{
|
||||
return "OnSlider" + varName.Replace("m_slider", string.Empty) + "Change";
|
||||
}
|
||||
|
||||
private static void WriteScript(Transform root, Transform child, ref StringBuilder strVar, ref StringBuilder strBind, ref StringBuilder strOnCreate,
|
||||
ref StringBuilder strCallback, bool isUniTask)
|
||||
{
|
||||
string varName = child.name;
|
||||
string componentName = string.Empty;
|
||||
|
||||
var rule = SettingsUtils.GetScriptGenerateRule().Find(t => varName.StartsWith(t.uiElementRegex));
|
||||
|
||||
if (rule != null)
|
||||
{
|
||||
componentName = rule.componentName;
|
||||
}
|
||||
|
||||
if (componentName == string.Empty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string varPath = GetRelativePath(child, root);
|
||||
if (!string.IsNullOrEmpty(varName))
|
||||
{
|
||||
strVar.Append("\t\tprivate " + componentName + " " + varName + ";\n");
|
||||
switch (componentName)
|
||||
{
|
||||
case "Transform":
|
||||
strBind.Append($"\t\t\t{varName} = FindChild(\"{varPath}\");\n");
|
||||
break;
|
||||
case "GameObject":
|
||||
strBind.Append($"\t\t\t{varName} = FindChild(\"{varPath}\").gameObject;\n");
|
||||
break;
|
||||
case "AnimationCurve":
|
||||
strBind.Append($"\t\t\t{varName} = FindChildComponent<AnimCurveObject>(\"{varPath}\").m_animCurve;\n");
|
||||
break;
|
||||
case "RichItemIcon":
|
||||
case "CommonFightWidget":
|
||||
case "PlayerHeadWidget":
|
||||
strBind.Append($"\t\t\t{varName} = CreateWidgetByType<{componentName}>(\"{varPath}\");\n");
|
||||
break;
|
||||
case "RedNoteBehaviour":
|
||||
case "TextButtonItem":
|
||||
case "SwitchTabItem":
|
||||
case "UIActorWidget":
|
||||
case "UIEffectWidget":
|
||||
case "UISpineWidget":
|
||||
strBind.Append($"\t\t\t{varName} = CreateWidget<{componentName}>(\"{varPath}\");\n");
|
||||
break;
|
||||
case "ActorNameBinderText":
|
||||
strBind.Append($"\t\t\t{varName} = FindTextBinder(\"{varPath}\");\n");
|
||||
break;
|
||||
case "ActorNameBinderEffect":
|
||||
strBind.Append($"\t\t\t{varName} = FindEffectBinder(\"{varPath}\");\n");
|
||||
break;
|
||||
default:
|
||||
strBind.Append($"\t\t\t{varName} = FindChildComponent<{componentName}>(\"{varPath}\");\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (componentName == "Button")
|
||||
{
|
||||
string varFuncName = GetBtnFuncName(varName);
|
||||
if (isUniTask)
|
||||
{
|
||||
strOnCreate.Append($"\t\t\t{varName}.onClick.AddListener(UniTask.UnityAction({varFuncName}));\n");
|
||||
strCallback.Append($"\t\tprivate async UniTaskVoid {varFuncName}()\n");
|
||||
strCallback.Append("\t\t{\n await UniTask.Yield();\n\t\t}\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
strOnCreate.Append($"\t\t\t{varName}.onClick.AddListener({varFuncName});\n");
|
||||
strCallback.Append($"\t\tprivate void {varFuncName}()\n");
|
||||
strCallback.Append("\t\t{\n\t\t}\n");
|
||||
}
|
||||
}
|
||||
else if (componentName == "Toggle")
|
||||
{
|
||||
string varFuncName = GetToggleFuncName(varName);
|
||||
strOnCreate.Append($"\t\t\t{varName}.onValueChanged.AddListener({varFuncName});\n");
|
||||
strCallback.Append($"\t\tprivate void {varFuncName}(bool isOn)\n");
|
||||
strCallback.Append("\t\t{\n\t\t}\n");
|
||||
}
|
||||
else if (componentName == "Slider")
|
||||
{
|
||||
string varFuncName = GetSliderFuncName(varName);
|
||||
strOnCreate.Append($"\t\t\t{varName}.onValueChanged.AddListener({varFuncName});\n");
|
||||
strCallback.Append($"\t\tprivate void {varFuncName}(float value)\n");
|
||||
strCallback.Append("\t\t{\n\t\t}\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class GeneratorHelper : EditorWindow
|
||||
{
|
||||
[MenuItem("GameObject/ScriptGenerator/About", priority = 49)]
|
||||
public static void About()
|
||||
{
|
||||
GeneratorHelper welcomeWindow = (GeneratorHelper)EditorWindow.GetWindow(typeof(GeneratorHelper), false, "About");
|
||||
}
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
minSize = new Vector2(400, 600);
|
||||
}
|
||||
|
||||
protected void OnGUI()
|
||||
{
|
||||
GUILayout.BeginVertical();
|
||||
foreach (var item in SettingsUtils.GetScriptGenerateRule())
|
||||
{
|
||||
GUILayout.Label(item.uiElementRegex + ":\t" + item.componentName);
|
||||
}
|
||||
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
|
||||
public class SwitchGroupGenerator
|
||||
{
|
||||
private const string Condition = "m_switchGroup";
|
||||
|
||||
public static readonly SwitchGroupGenerator Instance = new SwitchGroupGenerator();
|
||||
|
||||
public string Process(Transform root)
|
||||
{
|
||||
var sbd = new StringBuilder();
|
||||
var list = new List<Transform>();
|
||||
Collect(root, list);
|
||||
foreach (var node in list)
|
||||
{
|
||||
sbd.AppendLine(Process(root, node)).AppendLine();
|
||||
}
|
||||
|
||||
return sbd.ToString();
|
||||
}
|
||||
|
||||
public void Collect(Transform node, List<Transform> nodeList)
|
||||
{
|
||||
if (node.name.StartsWith(Condition))
|
||||
{
|
||||
nodeList.Add(node);
|
||||
return;
|
||||
}
|
||||
|
||||
var childCnt = node.childCount;
|
||||
for (var i = 0; i < childCnt; i++)
|
||||
{
|
||||
var child = node.GetChild(i);
|
||||
Collect(child, nodeList);
|
||||
}
|
||||
}
|
||||
|
||||
private string Process(Transform root, Transform groupTf)
|
||||
{
|
||||
var parentPath = GetPath(root, groupTf);
|
||||
var name = groupTf.name;
|
||||
var sbd = new StringBuilder(@"
|
||||
var _namePath = ""#parentPath"";
|
||||
var _nameTf = FindChild(_namePath);
|
||||
var childCnt = _nameTf.childCount;
|
||||
SwitchTabItem[] _name;
|
||||
_name = new SwitchTabItem[childCnt];
|
||||
for (var i = 0; i < childCnt; i++)
|
||||
{
|
||||
var child = _nameTf.GetChild(i);
|
||||
_name[i] = CreateWidget<SwitchTabItem>(_namePath + ""/"" + child.name);
|
||||
}");
|
||||
sbd.Replace("_name", name);
|
||||
sbd.Replace("#parentPath", parentPath);
|
||||
return sbd.ToString();
|
||||
}
|
||||
|
||||
public string GetPath(Transform root, Transform childTf)
|
||||
{
|
||||
if (childTf == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
if (childTf == root)
|
||||
{
|
||||
return childTf.name;
|
||||
}
|
||||
|
||||
var parentPath = GetPath(root, childTf.parent);
|
||||
if (parentPath == string.Empty)
|
||||
{
|
||||
return childTf.name;
|
||||
}
|
||||
|
||||
return parentPath + "/" + childTf.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5cde6b81462affb4bac5ca8cd0862f38
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
179
UnityProject/Assets/TEngine/Editor/UI/UIElementEditor.cs
Normal file
179
UnityProject/Assets/TEngine/Editor/UI/UIElementEditor.cs
Normal file
@@ -0,0 +1,179 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Sirenix.OdinInspector.Editor;
|
||||
using TEngine.Editor.UI;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
namespace TEngine
|
||||
{
|
||||
[CanEditMultipleObjects]
|
||||
[CustomEditor(typeof(UIElement), true)]
|
||||
public class UIElementEditor : OdinEditor
|
||||
{
|
||||
protected UIElement Element;
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
Element = target as UIElement;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
EditorGUI.BeginChangeCheck();
|
||||
if (GUILayout.Button("Generate", GUILayout.Width(130)))
|
||||
{
|
||||
CheckUiItems();
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
EditorUtility.SetDirty(Element);
|
||||
}
|
||||
|
||||
base.OnInspectorGUI();
|
||||
}
|
||||
|
||||
protected void CheckUiItems()
|
||||
{
|
||||
if (Element == null) return;
|
||||
ClearUnusedItems();
|
||||
var root = Element.transform;
|
||||
StringBuilder strVar = new StringBuilder();
|
||||
StringBuilder strBind = new StringBuilder();
|
||||
StringBuilder strOnCreate = new StringBuilder();
|
||||
StringBuilder strOnCreateRedNote = new StringBuilder();
|
||||
StringBuilder strCallback = new StringBuilder();
|
||||
Ergodic(root, root, ref strVar, ref strBind, ref strOnCreate, ref strOnCreateRedNote, ref strCallback);
|
||||
StringBuilder strFile = new StringBuilder();
|
||||
|
||||
// 脚本工具生成的代码
|
||||
strFile.Append("\t\t#region 脚本工具生成的代码\n");
|
||||
strFile.Append(strVar);
|
||||
strFile.Append("\t\tpublic override void ScriptGenerator()\n");
|
||||
strFile.Append("\t\t{\n");
|
||||
strFile.Append("\t\t\tCheckUIElement();\n");
|
||||
strFile.Append(strBind);
|
||||
strFile.Append(strOnCreate);
|
||||
strFile.Append(strOnCreateRedNote);
|
||||
strFile.Append("\t\t}\n");
|
||||
strFile.Append("\t\t#endregion");
|
||||
|
||||
TextEditor te = new TextEditor();
|
||||
te.text = strFile.ToString();
|
||||
te.SelectAll();
|
||||
te.Copy();
|
||||
}
|
||||
|
||||
private void ClearUnusedItems()
|
||||
{
|
||||
if (Element == null || Element.Elements == null) return;
|
||||
List<string> ids = new List<string>();
|
||||
foreach (var kv in Element.Elements)
|
||||
{
|
||||
if (kv.Value == null || !string.IsNullOrEmpty(GetVerType(kv.Key)))
|
||||
{
|
||||
ids.Add(kv.Key);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var id in ids)
|
||||
{
|
||||
Element.Elements.Remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
private void Ergodic(Transform root, Transform transform, ref StringBuilder strVar, ref StringBuilder strBind, ref StringBuilder strOnCreate,
|
||||
ref StringBuilder strOnCreateRedNote, ref StringBuilder strCallback)
|
||||
{
|
||||
for (int i = 0; i < transform.childCount; ++i)
|
||||
{
|
||||
Transform child = transform.GetChild(i);
|
||||
WriteScript(root, child, ref strVar, ref strBind, ref strOnCreate, ref strOnCreateRedNote, ref strCallback);
|
||||
if (child.name.StartsWith("m_item"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Ergodic(root, child, ref strVar, ref strBind, ref strOnCreate, ref strOnCreateRedNote, ref strCallback);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteScript(Transform root, Transform child, ref StringBuilder strVar, ref StringBuilder strBind, ref StringBuilder strOnCreate,
|
||||
ref StringBuilder strOnCreateRedNote, ref StringBuilder strCallback)
|
||||
{
|
||||
var varName = child.name;
|
||||
var varType = GetVerType(varName);
|
||||
if (varType == string.Empty) return;
|
||||
if (Element.Elements.Contains(varName))
|
||||
{
|
||||
Debug.LogError("有重复的key:" + varName);
|
||||
return;
|
||||
}
|
||||
|
||||
Element.Elements[varName] = child;
|
||||
if (!string.IsNullOrEmpty(varName))
|
||||
{
|
||||
strVar.Append("\t\tprivate " + varType + " " + varName + ";\n");
|
||||
switch (varType)
|
||||
{
|
||||
case "Transform":
|
||||
strBind.Append($"\t\t\t{varName} = FChild(\"{varName}\");\n");
|
||||
break;
|
||||
case "GameObject":
|
||||
strBind.Append($"\t\t\t{varName} = FChild(\"{varName}\").gameObject;\n");
|
||||
break;
|
||||
case "RichItemIcon":
|
||||
strBind.Append($"\t\t\t{varName} = CreateWidgetByType<{varType}>(FChild(\"{varName}\"));\n");
|
||||
break;
|
||||
case "RedNoteWidget":
|
||||
break;
|
||||
case "TextButtonItem":
|
||||
case "SwitchTabItem":
|
||||
case "UIActorWidget":
|
||||
case "UIEffectWidget":
|
||||
case "UISpineWidget":
|
||||
case "UIMainPlayerWidget":
|
||||
strBind.Append($"\t\t\t{varName} = CreateWidget<{varType}>(FChild(\"{varName}\").gameObject);\n");
|
||||
break;
|
||||
default:
|
||||
strBind.Append($"\t\t\t{varName} = FChild<{varType}>(\"{varName}\");\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (varType == "Button")
|
||||
{
|
||||
string varFuncName = ScriptGenerator.GetBtnFuncName(varName);
|
||||
strOnCreate.Append($"\t\t\t{varName}.onClick.AddListener({varFuncName});\n");
|
||||
strCallback.Append($"\t\tprivate void {varFuncName}()\n");
|
||||
strCallback.Append("\t\t{\n\t\t}\n");
|
||||
}
|
||||
else if (varType == "Toggle")
|
||||
{
|
||||
string varFuncName = ScriptGenerator.GetToggleFuncName(varName);
|
||||
strOnCreate.Append($"\t\t\t{varName}.onValueChanged.AddListener({varFuncName});\n");
|
||||
strCallback.Append($"\t\tprivate void {varFuncName}(bool isOn)\n");
|
||||
strCallback.Append("\t\t{\n\t\t}\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected string GetVerType(string uiName)
|
||||
{
|
||||
foreach (var pair in SettingsUtils.GetScriptGenerateRule())
|
||||
{
|
||||
if (uiName.StartsWith(pair.uiElementRegex))
|
||||
{
|
||||
return pair.componentName;
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02ba9976b78c4a079e16aa9302c1b43e
|
||||
timeCreated: 1696659319
|
8
UnityProject/Assets/TEngine/Editor/Utility.meta
Normal file
8
UnityProject/Assets/TEngine/Editor/Utility.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ed0876b4517e58479840179b3fde246
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
41
UnityProject/Assets/TEngine/Editor/Utility/GetAssetHelper.cs
Normal file
41
UnityProject/Assets/TEngine/Editor/Utility/GetAssetHelper.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取资源路径相关的实用函数。
|
||||
/// </summary>
|
||||
public static class GetAssetHelper
|
||||
{
|
||||
[MenuItem("Assets/Get Asset Path", priority = 3)]
|
||||
static void GetAssetPath()
|
||||
{
|
||||
UnityEngine.Object selObj = Selection.activeObject;
|
||||
|
||||
if (selObj != null)
|
||||
{
|
||||
string assetPath = AssetDatabase.GetAssetPath(selObj);
|
||||
EditorGUIUtility.systemCopyBuffer = assetPath;
|
||||
Debug.Log($"Asset path is {assetPath}");
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("Assets/Get Addressable Path", priority = 3)]
|
||||
static void GetAddressablePath()
|
||||
{
|
||||
UnityEngine.Object selObj = Selection.activeObject;
|
||||
|
||||
if (selObj != null)
|
||||
{
|
||||
string assetPath = AssetDatabase.GetAssetPath(selObj);
|
||||
var split = assetPath.Split('/');
|
||||
var name = split.Last();
|
||||
assetPath = name.Split('.').First();
|
||||
EditorGUIUtility.systemCopyBuffer = assetPath;
|
||||
Debug.Log($"Addressable path is {assetPath}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9cda2f3725dfe964a94ccdc9218e8ebc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
89
UnityProject/Assets/TEngine/Editor/Utility/HelperInfo.cs
Normal file
89
UnityProject/Assets/TEngine/Editor/Utility/HelperInfo.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Editor
|
||||
{
|
||||
internal sealed class HelperInfo<T> where T : MonoBehaviour
|
||||
{
|
||||
private const string CustomOptionName = "<Custom>";
|
||||
|
||||
private readonly string m_Name;
|
||||
|
||||
private SerializedProperty m_HelperTypeName;
|
||||
private SerializedProperty m_CustomHelper;
|
||||
private string[] m_HelperTypeNames;
|
||||
private int m_HelperTypeNameIndex;
|
||||
|
||||
public HelperInfo(string name)
|
||||
{
|
||||
m_Name = name;
|
||||
|
||||
m_HelperTypeName = null;
|
||||
m_CustomHelper = null;
|
||||
m_HelperTypeNames = null;
|
||||
m_HelperTypeNameIndex = 0;
|
||||
}
|
||||
|
||||
public void Init(SerializedObject serializedObject)
|
||||
{
|
||||
m_HelperTypeName = serializedObject.FindProperty(Utility.Text.Format("m_{0}HelperTypeName", m_Name));
|
||||
m_CustomHelper = serializedObject.FindProperty(Utility.Text.Format("m_Custom{0}Helper", m_Name));
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
string displayName = FieldNameForDisplay(m_Name);
|
||||
int selectedIndex = EditorGUILayout.Popup(Utility.Text.Format("{0} Helper", displayName), m_HelperTypeNameIndex, m_HelperTypeNames);
|
||||
if (selectedIndex != m_HelperTypeNameIndex)
|
||||
{
|
||||
m_HelperTypeNameIndex = selectedIndex;
|
||||
m_HelperTypeName.stringValue = selectedIndex <= 0 ? null : m_HelperTypeNames[selectedIndex];
|
||||
}
|
||||
|
||||
if (m_HelperTypeNameIndex <= 0)
|
||||
{
|
||||
EditorGUILayout.PropertyField(m_CustomHelper);
|
||||
if (m_CustomHelper.objectReferenceValue == null)
|
||||
{
|
||||
EditorGUILayout.HelpBox(Utility.Text.Format("You must set Custom {0} Helper.", displayName), MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
List<string> helperTypeNameList = new List<string>
|
||||
{
|
||||
CustomOptionName
|
||||
};
|
||||
|
||||
helperTypeNameList.AddRange(Type.GetRuntimeTypeNames(typeof(T)));
|
||||
m_HelperTypeNames = helperTypeNameList.ToArray();
|
||||
|
||||
m_HelperTypeNameIndex = 0;
|
||||
if (!string.IsNullOrEmpty(m_HelperTypeName.stringValue))
|
||||
{
|
||||
m_HelperTypeNameIndex = helperTypeNameList.IndexOf(m_HelperTypeName.stringValue);
|
||||
if (m_HelperTypeNameIndex <= 0)
|
||||
{
|
||||
m_HelperTypeNameIndex = 0;
|
||||
m_HelperTypeName.stringValue = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string FieldNameForDisplay(string fieldName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(fieldName))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
string str = Regex.Replace(fieldName, @"^m_", string.Empty);
|
||||
str = Regex.Replace(str, @"((?<=[a-z])[A-Z]|[A-Z](?=[a-z]))", @" $1").TrimStart();
|
||||
return str;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5e1e932beb704b8d855ada90d41d6b56
|
||||
timeCreated: 1695116209
|
@@ -0,0 +1,83 @@
|
||||
using System.Diagnostics;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 打开文件夹相关的实用函数。
|
||||
/// </summary>
|
||||
public static class OpenFolderHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 打开 Data Path 文件夹。
|
||||
/// </summary>
|
||||
[MenuItem("TEngine/Open Folder/Data Path", false, 10)]
|
||||
public static void OpenFolderDataPath()
|
||||
{
|
||||
Execute(Application.dataPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 打开 Persistent Data Path 文件夹。
|
||||
/// </summary>
|
||||
[MenuItem("TEngine/Open Folder/Persistent Data Path", false, 11)]
|
||||
public static void OpenFolderPersistentDataPath()
|
||||
{
|
||||
Execute(Application.persistentDataPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 打开 Streaming Assets Path 文件夹。
|
||||
/// </summary>
|
||||
[MenuItem("TEngine/Open Folder/Streaming Assets Path", false, 12)]
|
||||
public static void OpenFolderStreamingAssetsPath()
|
||||
{
|
||||
Execute(Application.streamingAssetsPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 打开 Temporary Cache Path 文件夹。
|
||||
/// </summary>
|
||||
[MenuItem("TEngine/Open Folder/Temporary Cache Path", false, 13)]
|
||||
public static void OpenFolderTemporaryCachePath()
|
||||
{
|
||||
Execute(Application.temporaryCachePath);
|
||||
}
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
|
||||
/// <summary>
|
||||
/// 打开 Console Log Path 文件夹。
|
||||
/// </summary>
|
||||
[MenuItem("TEngine/Open Folder/Console Log Path", false, 14)]
|
||||
public static void OpenFolderConsoleLogPath()
|
||||
{
|
||||
Execute(System.IO.Path.GetDirectoryName(Application.consoleLogPath));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// 打开指定路径的文件夹。
|
||||
/// </summary>
|
||||
/// <param name="folder">要打开的文件夹的路径。</param>
|
||||
public static void Execute(string folder)
|
||||
{
|
||||
folder = $"\"{folder}\"";
|
||||
switch (Application.platform)
|
||||
{
|
||||
case RuntimePlatform.WindowsEditor:
|
||||
Process.Start("Explorer.exe", folder.Replace('/', '\\'));
|
||||
break;
|
||||
|
||||
case RuntimePlatform.OSXEditor:
|
||||
Process.Start("open", folder);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new System.Exception($"Not support open folder on '{Application.platform}' platform.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce4febf89f4174a46be07146ae57de86
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
103
UnityProject/Assets/TEngine/Editor/Utility/ShellHelper.cs
Normal file
103
UnityProject/Assets/TEngine/Editor/Utility/ShellHelper.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TEngine
|
||||
{
|
||||
public static class ShellHelper
|
||||
{
|
||||
public static void Run(string cmd, string workDirectory, List<string> environmentVars = null)
|
||||
{
|
||||
System.Diagnostics.Process process = new();
|
||||
try
|
||||
{
|
||||
#if UNITY_EDITOR_OSX || UNITY_EDITOR_LINUX
|
||||
string app = "bash";
|
||||
string splitChar = ":";
|
||||
string arguments = "-c";
|
||||
#elif UNITY_EDITOR_WIN
|
||||
string app = "cmd.exe";
|
||||
string splitChar = ";";
|
||||
string arguments = "/c";
|
||||
#endif
|
||||
ProcessStartInfo start = new ProcessStartInfo(app);
|
||||
|
||||
if (environmentVars != null)
|
||||
{
|
||||
foreach (string var in environmentVars)
|
||||
{
|
||||
start.EnvironmentVariables["PATH"] += (splitChar + var);
|
||||
}
|
||||
}
|
||||
|
||||
process.StartInfo = start;
|
||||
start.Arguments = arguments + " \"" + cmd + "\"";
|
||||
start.CreateNoWindow = true;
|
||||
start.ErrorDialog = true;
|
||||
start.UseShellExecute = false;
|
||||
start.WorkingDirectory = workDirectory;
|
||||
|
||||
if (start.UseShellExecute)
|
||||
{
|
||||
start.RedirectStandardOutput = false;
|
||||
start.RedirectStandardError = false;
|
||||
start.RedirectStandardInput = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
start.RedirectStandardOutput = true;
|
||||
start.RedirectStandardError = true;
|
||||
start.RedirectStandardInput = true;
|
||||
start.StandardOutputEncoding = System.Text.Encoding.UTF8;
|
||||
start.StandardErrorEncoding = System.Text.Encoding.UTF8;
|
||||
}
|
||||
|
||||
bool endOutput = false;
|
||||
bool endError = false;
|
||||
|
||||
process.OutputDataReceived += (sender, args) =>
|
||||
{
|
||||
if (args.Data != null)
|
||||
{
|
||||
UnityEngine.Debug.Log(args.Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
endOutput = true;
|
||||
}
|
||||
};
|
||||
|
||||
process.ErrorDataReceived += (sender, args) =>
|
||||
{
|
||||
if (args.Data != null)
|
||||
{
|
||||
UnityEngine.Debug.LogError(args.Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
endError = true;
|
||||
}
|
||||
};
|
||||
|
||||
process.Start();
|
||||
process.BeginOutputReadLine();
|
||||
process.BeginErrorReadLine();
|
||||
|
||||
while (!endOutput || !endError)
|
||||
{
|
||||
}
|
||||
|
||||
process.CancelOutputRead();
|
||||
process.CancelErrorRead();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UnityEngine.Debug.LogException(e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
process.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a1d4e955485549fcbcc754c333953255
|
||||
timeCreated: 1695193247
|
83
UnityProject/Assets/TEngine/Editor/Utility/Type.cs
Normal file
83
UnityProject/Assets/TEngine/Editor/Utility/Type.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace TEngine.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 类型相关的实用函数。
|
||||
/// </summary>
|
||||
internal static class Type
|
||||
{
|
||||
private static readonly string[] RuntimeAssemblyNames =
|
||||
{
|
||||
"TEngine.Runtime",
|
||||
"Assembly-CSharp",
|
||||
"GameMain.Runtime",
|
||||
"GameMain",
|
||||
};
|
||||
|
||||
private static readonly string[] RuntimeOrEditorAssemblyNames =
|
||||
{
|
||||
"TEngine.Runtime",
|
||||
"Assembly-CSharp",
|
||||
"TEngine.Editor",
|
||||
"Assembly-CSharp-Editor",
|
||||
"GameMain",
|
||||
"GameMain.Editor"
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 在运行时程序集中获取指定基类的所有子类的名称。
|
||||
/// </summary>
|
||||
/// <param name="typeBase">基类类型。</param>
|
||||
/// <returns>指定基类的所有子类的名称。</returns>
|
||||
internal static string[] GetRuntimeTypeNames(System.Type typeBase)
|
||||
{
|
||||
return GetTypeNames(typeBase, RuntimeAssemblyNames);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在运行时或编辑器程序集中获取指定基类的所有子类的名称。
|
||||
/// </summary>
|
||||
/// <param name="typeBase">基类类型。</param>
|
||||
/// <returns>指定基类的所有子类的名称。</returns>
|
||||
internal static string[] GetRuntimeOrEditorTypeNames(System.Type typeBase)
|
||||
{
|
||||
return GetTypeNames(typeBase, RuntimeOrEditorAssemblyNames);
|
||||
}
|
||||
|
||||
private static string[] GetTypeNames(System.Type typeBase, string[] assemblyNames)
|
||||
{
|
||||
List<string> typeNames = new List<string>();
|
||||
foreach (string assemblyName in assemblyNames)
|
||||
{
|
||||
Assembly assembly = null;
|
||||
try
|
||||
{
|
||||
assembly = Assembly.Load(assemblyName);
|
||||
}
|
||||
catch
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (assembly == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
System.Type[] types = assembly.GetTypes();
|
||||
foreach (System.Type type in types)
|
||||
{
|
||||
if (type.IsClass && !type.IsAbstract && typeBase.IsAssignableFrom(type))
|
||||
{
|
||||
typeNames.Add(type.FullName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typeNames.Sort();
|
||||
return typeNames.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
11
UnityProject/Assets/TEngine/Editor/Utility/Type.cs.meta
Normal file
11
UnityProject/Assets/TEngine/Editor/Utility/Type.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a791d3891e3eeb40b35602635e8093b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user