FeastSC 发表于 2022-5-11 10:47

[Unity 3d] 编辑器程序集编译API - 笔记


本文是个笔记,记录 2 个编辑器下编译程序集的逻辑。
一 . 编译 Runtime 用的程序集

Runtime 用的程序集:特征是会剔除 #if UNITY_EDITOR 注释的逻辑块)
public static void OnAssemblyBuildRequired()      {            // todo 目前是全部都编译,有木有方法只编译需要的 程序集呢?            var buildDir = Application.temporaryCachePath;            var files = new DirectoryInfo(buildDir).GetFiles();            foreach (var file in files)            {                FileUtil.DeleteFileOrDirectory(file.FullName);            }                        var target = EditorUserBuildSettings.activeBuildTarget;            var group = BuildPipeline.GetBuildTargetGroup(target);            ScriptCompilationSettings scriptCompilationSettings = default;            scriptCompilationSettings.group = group;            scriptCompilationSettings.target = target;            ScriptCompilationResult scriptCompilationResult = PlayerBuildInterface.CompilePlayerScripts(scriptCompilationSettings, buildDir);            var lib_dir = Path.Combine(Application.dataPath, "..", "Library\\ScriptAssemblies");            foreach (var item in Instance.assemblies)            {                if (item.IsValid)    // 如果配置正确则尝试转存储文件                {                  var file = new FileInfo(Path.Combine(lib_dir, item.Dll));                  var lastWriteTime = file.LastWriteTime.Ticks;                  if (item.lastWriteTime < lastWriteTime)                  {                        item.lastWriteTime = lastWriteTime;                        FileUtil.ReplaceFile(Path.Combine(buildDir, item.Dll), item.OutputPath);                        item.UpdateInformation();                  }                }                else                {                  Debug.LogError($"{nameof(AssemblyHotfixManager)}: 请先完善 Hotfix Configuration 配置项!");                }            }            EditorUtility.SetDirty(Instance);      }
Build App 使用的这个APIAddressable 也是这个API
二 . 编译指定 .asmdef 定义的程序集

   public static void SyncAssemblyRawData(bool forceCompilie = false)    {                  // 1.dll 编译存放处            var lib_dir = Path.Combine(Application.dataPath, "..", "Library\\ScriptAssemblies");            foreach (var item in Instance.assemblies)            {                // 如果配置正确则开始尝试编译                if (item.IsValid)                {                  var data = JsonUtility.FromJson<SimplifiedAssemblyData>(item.assembly.text);                  var dll = Path.Combine(lib_dir, $"{data.name}.dll");                  var temp = Path.Combine(Application.temporaryCachePath, $"{data.name}.bytes");                  var file = new FileInfo(dll);                  if (file.Exists)                  {                        var lastWriteTime = file.LastWriteTime.Ticks;                        if (forceCompilie || item.lastWriteTime < lastWriteTime)                        {                            item.lastWriteTime = lastWriteTime;                            var assembly = CompilationPipeline.GetAssemblies(AssembliesType.Player).FirstOrDefault(v => v.name == item.assembly.name);                            if (null != assembly)                            {                              // Compiles scripts outside the Assets folder into a managed assembly that can be used inside the Assets folder.                              AssemblyBuilder builder = new AssemblyBuilder(temp, assembly.sourceFiles);                              builder.compilerOptions.AllowUnsafeCode = item.AllowUnsafeCode;                              BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget);                              builder.compilerOptions.ApiCompatibilityLevel = PlayerSettings.GetApiCompatibilityLevel(buildTargetGroup);                              builder.additionalReferences = assembly.allReferences;                              builder.flags = AssemblyBuilderFlags.None;                              // todo: 以下动作会导致程序集完成编译后IDE 报错,待确认:减少编译频率,变成 aa build 时编译,同时看能不能将 csproj 回到原点                              builder.referencesOptions = ReferencesOptions.UseEngineModules;                              builder.buildTarget = EditorUserBuildSettings.activeBuildTarget;                              builder.buildTargetGroup = buildTargetGroup;                              builder.excludeReferences = new string[] { assembly.outputPath };                              builder.additionalDefines = assembly.defines;                              builder.compilerOptions = assembly.compilerOptions;                              builder.buildFinished += (arg1, arg2) =>                              {                                    bool noErr = true;                                    foreach (var msg in arg2)                                    {                                        if (msg.type == CompilerMessageType.Error)                                        {                                          Debug.LogError(msg.message);                                          noErr = false;                                        }                                        else if (msg.type == CompilerMessageType.Warning)                                        {                                          Debug.LogWarning(msg.message);                                        }                                        else                                        {                                          Debug.Log(msg.message);                                        }                                    }                                    if (noErr)                                    {                                        FileUtil.ReplaceFile(temp, item.OutputPath);                                        item.UpdateInformation();                                    }                              };                              if (!builder.Build())                              {                                    Debug.LogError($"{nameof(AssemblyHotfixManager)}: Assembly {item.Dll} Build Fail!");                              }                              else                              {                                    Debug.Log($"{nameof(AssemblyHotfixManager)} 热更程序集: <color=yellow>{item.Dll} </color> 完成构建!");                              }                            }                        }                  }                }                else                {                  Debug.LogError($"{nameof(AssemblyHotfixManager)}: 请先完善 Hotfix Configuration 配置项!");                }                EditorUtility.SetDirty(Instance);                AssetDatabase.Refresh();            }      }
builder.referencesOptions = ReferencesOptions.UseEngineModules; 编译为 Runtime 程序集这个类主要用于将 Assets 文件夹以外的 Assembly 进行编译并放回到 Assets 中使用这个类使用的编译器不同于 PlayerBuildInterface.CompilePlayerScripts ,编译时会修改所有的 .sln 和 .csproj 文件上述代码并不完善,剩余部分在:这里
页: [1]
查看完整版本: [Unity 3d] 编辑器程序集编译API - 笔记