AssemblyTool.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. using System.IO;
  2. using System.Threading;
  3. using UnityEditor;
  4. using UnityEditor.Build.Player;
  5. using UnityEngine;
  6. namespace ET
  7. {
  8. public static class AssemblyTool
  9. {
  10. /// <summary>
  11. /// Unity线程的同步上下文
  12. /// </summary>
  13. static SynchronizationContext unitySynchronizationContext { get; set; }
  14. /// <summary>
  15. /// 程序集名字数组
  16. /// </summary>
  17. public static readonly string[] DllNames = { "ET.Hotfix", "ET.HotfixView", "ET.Model", "ET.ModelView" };
  18. [InitializeOnLoadMethod]
  19. static void Initialize()
  20. {
  21. unitySynchronizationContext = SynchronizationContext.Current;
  22. }
  23. /// <summary>
  24. /// 菜单和快捷键编译按钮
  25. /// </summary>
  26. [MenuItem("ET/Loader/Compile _F6", false, ETMenuItemPriority.Compile)]
  27. static void MenuItemOfCompile()
  28. {
  29. // 强制刷新一下,防止关闭auto refresh,文件修改时间不准确
  30. AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
  31. DoCompile();
  32. }
  33. /// <summary>
  34. /// 菜单和快捷键热重载按钮
  35. /// </summary>
  36. [MenuItem("ET/Loader/Reload _F7", false, ETMenuItemPriority.Compile)]
  37. static void MenuItemOfReload()
  38. {
  39. if (Application.isPlaying)
  40. {
  41. CodeLoader.Instance?.Reload();
  42. }
  43. }
  44. /// <summary>
  45. /// 执行编译代码流程
  46. /// </summary>
  47. public static void DoCompile()
  48. {
  49. // 强制刷新一下,防止关闭auto refresh,编译出老代码
  50. AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
  51. GlobalConfig globalConfig = Resources.Load<GlobalConfig>("GlobalConfig");
  52. CodeModeChangeHelper.ChangeToCodeMode(globalConfig.CodeMode.ToString());
  53. bool isCompileOk = CompileDlls();
  54. if (!isCompileOk)
  55. {
  56. return;
  57. }
  58. CopyHotUpdateDlls();
  59. Log.Info($"Compile Finish!");
  60. }
  61. /// <summary>
  62. /// 编译成dll
  63. /// </summary>
  64. static bool CompileDlls()
  65. {
  66. // 运行时编译需要先设置为UnitySynchronizationContext, 编译完再还原为CurrentContext
  67. SynchronizationContext lastSynchronizationContext = Application.isPlaying ? SynchronizationContext.Current : null;
  68. SynchronizationContext.SetSynchronizationContext(unitySynchronizationContext);
  69. bool isCompileOk = false;
  70. try
  71. {
  72. Directory.CreateDirectory(Define.BuildOutputDir);
  73. BuildTarget target = EditorUserBuildSettings.activeBuildTarget;
  74. BuildTargetGroup group = BuildPipeline.GetBuildTargetGroup(target);
  75. ScriptCompilationSettings scriptCompilationSettings = new()
  76. {
  77. group = group,
  78. target = target,
  79. extraScriptingDefines = new[] { "IS_COMPILING" },
  80. options = EditorUserBuildSettings.development ? ScriptCompilationOptions.DevelopmentBuild : ScriptCompilationOptions.None
  81. };
  82. ScriptCompilationResult result = PlayerBuildInterface.CompilePlayerScripts(scriptCompilationSettings, Define.BuildOutputDir);
  83. isCompileOk = result.assemblies.Count > 0;
  84. EditorUtility.ClearProgressBar();
  85. }
  86. finally
  87. {
  88. if (lastSynchronizationContext != null)
  89. {
  90. SynchronizationContext.SetSynchronizationContext(lastSynchronizationContext);
  91. }
  92. }
  93. return isCompileOk;
  94. }
  95. /// <summary>
  96. /// 将dll文件复制到加载目录
  97. /// </summary>
  98. static void CopyHotUpdateDlls()
  99. {
  100. FileHelper.CleanDirectory(Define.CodeDir);
  101. foreach (string dllName in DllNames)
  102. {
  103. string sourceDll = $"{Define.BuildOutputDir}/{dllName}.dll";
  104. string sourcePdb = $"{Define.BuildOutputDir}/{dllName}.pdb";
  105. File.Copy(sourceDll, $"{Define.CodeDir}/{dllName}.dll.bytes", true);
  106. File.Copy(sourcePdb, $"{Define.CodeDir}/{dllName}.pdb.bytes", true);
  107. }
  108. AssetDatabase.Refresh();
  109. }
  110. }
  111. }