I have an editor script that creates other scripts when it is run. Immediately after creating these new scripts, the editor script needs to access them (e.g., by adding their components to objects, setting references, etc.). Thus, I need a way to make my editor script wait for Unity to recompile before it tries to access these newly-created scripts.
I think I found a workaround solution for this problem:
- Immediately after I create my script using StreamWriter, I call AssetDatabase.ImportAsset using ImportAssetOptions.ForceSynchronousImport.
- I then try to add the component that my procedurally-generated script has created.
- If the result of the AddComponent call is null, then I call AssetDatabase.ImportAsset on the asset I am postprocessing. The second time it imports, the class exists.
Another solution to have a sort of OnPostBuildEvent in Unity is hidden in the AssetPostProcessor class. Save this little snippet in your editor folder and you will get an automatic call whenever compilation finished.
class MyAllPostprocessor : AssetPostprocessor
{
static void OnPostprocessAllAssets(
string[] importedAssets,
string[] deletedAssets,
string[] movedAssets,
string[] movedFromAssetPaths)
{
Debug.Log("Hello OnPostBuildEvent");
}
}
I don't think that's possible. There is no "OnCompiled" event or anything of that nature.
I think your best bet would be to tell your script to wait for a few seconds (enough time to where you would be sure the scripts have compiled) and then try to access them. You can use a coroutine (and yield return WaitForSeconds(x)), or you can start a new thread and use Thread.Sleep().
I think you can achieve this by leveraging the fact that when Unity reloads scripts, it completely serializes all editor windows (including yours), shuts down mono, starts mono, and deserializes all editor windows.
If you can detect that this process has happened, you're probably good to go.
I think you can recognize this by stuffing a value into a field that is not serialized, and then keep monitoring that value in OnGUI() (or something else that happens frequently). As soon as your variable is gone, that means your scripts have reloaded.
make sure not to do the check in a tight loop, but instead let unity "breathe", and check from a OnGUI() method or similar.
I'm trying to use this, but when I force synchronous, I get a big red error message saying:
"Reload Assembly called from managed code directly. This will cause a crash. You should never refresh assets in synchronous mode or enter playmode synchronously from script code."
It works just fine, it's just really annoying to have this error message popping up.
Did you get this error also and just ignore it, or am I doing something wrong?