Unity中[InitializeOnLoad]因项目编译失败无法执行的问题咨询
Got it, let's tackle this problem head-on. The core issue here is that your project fails to compile on launch because missing libraries block the [InitializeOnLoad] code from running—so you can't use that path to handle automatic download and setup. Here are four solid workarounds that don't force you to run external scripts manually every time you open the editor:
1. Minimal Bootstrap Script in an Isolated Assembly
The key here is to create a tiny, self-contained editor script that doesn't depend on any of your missing libraries. Since Unity compiles independent assemblies first, this script will build successfully even if other parts of the project fail, letting it run on launch.
Steps:
- Create a new folder in your project (e.g.,
Assets/Bootstrap) - Right-click in the folder → Create → Assembly Definition
- Name it
Bootstrap.asmdef, then in its Inspector, only keep references toUnityEditorandUnityEngine(remove all other dependencies) - Add a script to this folder with your download/setup logic:
using UnityEditor; using UnityEngine.Networking; using System.IO; using System.Threading.Tasks; [InitializeOnLoad] public static class BootstrapInitializer { static BootstrapInitializer() { _ = CheckAndDownloadLibraries(); } private static async Task CheckAndDownloadLibraries() { string targetLibraryPath = Path.Combine(Application.dataPath, "Plugins/RequiredLibrary"); if (!Directory.Exists(targetLibraryPath)) { // Example: Download from a remote source using (UnityWebRequest request = UnityWebRequest.Get("https://your-server.com/required-library.zip")) { await request.SendWebRequest(); if (request.result == UnityWebRequest.Result.Success) { string tempZipPath = Path.Combine(Application.temporaryCachePath, "library.zip"); File.WriteAllBytes(tempZipPath, request.downloadHandler.data); // Add your zip extraction logic here (use a lightweight utility if needed) // ExtractZip(tempZipPath, targetLibraryPath); // Trigger a recompile once libraries are in place AssetDatabase.Refresh(); } else { Debug.LogError($"Failed to download library: {request.error}"); } } } } }
This script runs as soon as the editor launches, before any dependent assemblies are compiled, and handles downloading missing libraries. Once the libraries are in place, AssetDatabase.Refresh() triggers a recompile of the rest of your project.
2. Use Unity Package Manager (UPM) Automated Installation
If your libraries are distributed as UPM packages, you can automate their installation via a bootstrap script that modifies the project's manifest.json and triggers a package resolve.
Steps:
- Use the same isolated bootstrap assembly from the first method
- Add code to check for the package and install it if missing:
using UnityEditor; using UnityEditor.PackageManager; using UnityEditor.PackageManager.Requests; [InitializeOnLoad] public static class PackageBootstrap { static AddRequest addRequest; static PackageBootstrap() { CheckAndInstallPackage(); } private static void CheckAndInstallPackage() { string packageId = "com.yourcompany.required-library"; // Check if the package is already installed foreach (var package in Client.List()) { if (package.name == packageId) return; } // Install the package from a git URL or registry addRequest = Client.Add("https://github.com/yourcompany/required-library.git#v1.0.0"); EditorApplication.update += ProgressCheck; } private static void ProgressCheck() { if (addRequest.IsCompleted) { if (addRequest.Status == StatusCode.Success) Debug.Log("Package installed successfully!"); else if (addRequest.Status >= StatusCode.Failure) Debug.LogError(addRequest.Error.message); EditorApplication.update -= ProgressCheck; AssetDatabase.Refresh(); } } }
This leverages UPM's built-in system to handle dependencies and compilation automatically once the package is added.
3. Preloaded ScriptableObject for Early Initialization
Unity lets you specify preloaded assets that load early in the editor startup process. You can use this to run initialization code before dependent assemblies are compiled.
Steps:
- Create a simple ScriptableObject in your isolated bootstrap assembly:
using UnityEngine; using UnityEditor; public class StartupInitializer : ScriptableObject { [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] private static void RunInitialization() { // Only run in the editor if (!Application.isEditor) return; CheckAndDownloadLibraries(); } private static void CheckAndDownloadLibraries() { // Same download/setup logic as the bootstrap script } }
- Create an instance of this ScriptableObject (right-click → Create → Startup Initializer)
- Go to Edit → Project Settings → Player → Preloaded Assets
- Add your
StartupInitializerinstance to the list
This object loads and runs its initialization method before any scene or dependent code compiles, letting you handle library setup first.
4. Lightweight Editor Wrapper Script (Semi-Automated)
If you prefer not to modify your project code, create a simple wrapper script (e.g., a C# console app) that checks for missing libraries, downloads them if needed, then launches the Unity Editor. Replace your Unity shortcut to point to this wrapper instead of the editor directly.
Example Wrapper Code (Console App):
using System; using System.IO; using System.Net; using System.Diagnostics; class UnityEditorWrapper { static void Main(string[] args) { string projectPath = Environment.CurrentDirectory; string libraryPath = Path.Combine(projectPath, "Assets/Plugins/RequiredLibrary"); string unityEditorPath = @"C:\Program Files\Unity\Hub\Editor\2022.3.1f1\Editor\Unity.exe"; if (!Directory.Exists(libraryPath)) { Console.WriteLine("Downloading required library..."); using (WebClient client = new WebClient()) { string tempZip = Path.Combine(Path.GetTempPath(), "library.zip"); client.DownloadFile("https://your-server.com/required-library.zip", tempZip); // Add zip extraction logic here (e.g., using SharpZipLib) } } // Launch Unity with your project Process.Start(unityEditorPath, $"\"{projectPath}\""); } }
Compile this into an executable, then set your project shortcut to run this exe. Users double-click the shortcut as usual, and the wrapper handles setup silently.
内容的提问来源于stack exchange,提问作者Mircea Ispas

