HAARFTE/Assets/DemoGame/GameScript/Editor/AssemblyTool.cs

237 lines
7.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using UnityEditor;
using UnityEditor.Build.Player;
using UnityEngine;
namespace ZEditor
{
public static class AssemblyTool
{
/// <summary>
/// 菜单和快捷键编译按钮
/// </summary>
[MenuItem("Tool/Compile _F6", false)]
static void MenuItemOfCompile()
{
// 强制刷新一下防止关闭auto refresh文件修改时间不准确
AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
DoCompile();
}
/// <summary>
/// 执行编译代码流程
/// </summary>
public static void DoCompile()
{
// 强制刷新一下防止关闭auto refresh编译出老代码
AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
bool isCompileOk = CompileDlls();
if (!isCompileOk)
{
return;
}
CopyHotUpdateDlls();
BuildHelper.ReGenerateProjectFiles();
Debug.Log($"Compile Finish!");
}
/// <summary>
/// Unity线程的同步上下文
/// </summary>
static SynchronizationContext unitySynchronizationContext { get; set; }
/// <summary>
/// 编辑器下加载热更dll的目录
/// </summary>
public const string CodeDir = "Assets/DemoGame/GameRes/Codes";
/// <summary>
/// VS或Rider工程生成dll的所在目录, 使用HybridCLR打包时需要使用
/// </summary>
public const string BuildOutputDir = "Temp/Bin/Debug";
[InitializeOnLoadMethod]
static void Initialize()
{
unitySynchronizationContext = SynchronizationContext.Current;
}
/// <summary>
/// 编译成dll
/// </summary>
static bool CompileDlls()
{
// 运行时编译需要先设置为UnitySynchronizationContext, 编译完再还原为CurrentContext
SynchronizationContext lastSynchronizationContext = Application.isPlaying ? SynchronizationContext.Current : null;
SynchronizationContext.SetSynchronizationContext(unitySynchronizationContext);
bool isCompileOk = false;
try
{
Directory.CreateDirectory(BuildOutputDir);
BuildTarget target = EditorUserBuildSettings.activeBuildTarget;
BuildTargetGroup group = BuildPipeline.GetBuildTargetGroup(target);
ScriptCompilationSettings scriptCompilationSettings = new()
{
group = group,
target = target,
extraScriptingDefines = new[] { "UNITY_COMPILE" },
options = EditorUserBuildSettings.development ? ScriptCompilationOptions.DevelopmentBuild : ScriptCompilationOptions.None
};
ScriptCompilationResult result = PlayerBuildInterface.CompilePlayerScripts(scriptCompilationSettings, BuildOutputDir);
isCompileOk = result.assemblies.Count > 0;
EditorUtility.ClearProgressBar();
}
finally
{
if (lastSynchronizationContext != null)
{
SynchronizationContext.SetSynchronizationContext(lastSynchronizationContext);
}
}
return isCompileOk;
}
/// <summary>
/// 程序集名字数组
/// </summary>
public static readonly string[] DllNames = { "Hotfix" };
/// <summary>
/// 将dll文件复制到加载目录
/// </summary>
static void CopyHotUpdateDlls()
{
FileHelper.CleanDirectory(CodeDir);
foreach (string dllName in DllNames)
{
string sourceDll = $"{BuildOutputDir}/{dllName}.dll";
string sourcePdb = $"{BuildOutputDir}/{dllName}.pdb";
File.Copy(sourceDll, $"{CodeDir}/{dllName}.dll.bytes", true);
File.Copy(sourcePdb, $"{CodeDir}/{dllName}.pdb.bytes", true);
}
AssetDatabase.Refresh();
}
}
public static class FileHelper
{
public static List<string> GetAllFiles(string dir, string searchPattern = "*")
{
List<string> list = new List<string>();
GetAllFiles(list, dir, searchPattern);
return list;
}
public static void GetAllFiles(List<string> files, string dir, string searchPattern = "*")
{
string[] fls = Directory.GetFiles(dir);
foreach (string fl in fls)
{
files.Add(fl);
}
string[] subDirs = Directory.GetDirectories(dir);
foreach (string subDir in subDirs)
{
GetAllFiles(files, subDir, searchPattern);
}
}
public static void CleanDirectory(string dir)
{
if (!Directory.Exists(dir))
{
return;
}
foreach (string subdir in Directory.GetDirectories(dir))
{
Directory.Delete(subdir, true);
}
foreach (string subFile in Directory.GetFiles(dir))
{
File.Delete(subFile);
}
}
public static void CopyDirectory(string srcDir, string tgtDir)
{
DirectoryInfo source = new DirectoryInfo(srcDir);
DirectoryInfo target = new DirectoryInfo(tgtDir);
if (target.FullName.StartsWith(source.FullName, StringComparison.CurrentCultureIgnoreCase))
{
throw new Exception("父目录不能拷贝到子目录!");
}
if (!source.Exists)
{
return;
}
if (!target.Exists)
{
target.Create();
}
FileInfo[] files = source.GetFiles();
for (int i = 0; i < files.Length; i++)
{
File.Copy(files[i].FullName, Path.Combine(target.FullName, files[i].Name), true);
}
DirectoryInfo[] dirs = source.GetDirectories();
for (int j = 0; j < dirs.Length; j++)
{
CopyDirectory(dirs[j].FullName, Path.Combine(target.FullName, dirs[j].Name));
}
}
public static void ReplaceExtensionName(string srcDir, string extensionName, string newExtensionName)
{
if (Directory.Exists(srcDir))
{
string[] fls = Directory.GetFiles(srcDir);
foreach (string fl in fls)
{
if (fl.EndsWith(extensionName))
{
File.Move(fl, fl.Substring(0, fl.IndexOf(extensionName)) + newExtensionName);
File.Delete(fl);
}
}
string[] subDirs = Directory.GetDirectories(srcDir);
foreach (string subDir in subDirs)
{
ReplaceExtensionName(subDir, extensionName, newExtensionName);
}
}
}
}
public static class BuildHelper
{
[InitializeOnLoadMethod]
public static void ReGenerateProjectFiles()
{
Unity.CodeEditor.CodeEditor.CurrentEditor.SyncAll();
}
}
}