Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

InitializeOnLoad vs DidReloadScripts

Discussion in 'Scripting' started by liortal, Mar 19, 2015.

  1. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,559
    Hi,

    I'd like some code to execute whenever scripts are rebuilt.

    I'm wondering what are the differences between both of these attributes (with respect to - when are they invoked ?)

    According to the documentation:
    • DidReloadScripts - Add this attribute to a method to get a notification after scripts have been reloaded.
    • InitializeOnLoad - Allow an editor class to be initialized when Unity loads without action from the user.
    From testing, it seems that whenever I change my scripts, all code is unloaded, and reloaded again, making the class marked with InitializeOnLoad execute automatically.

    What is the difference then, and when should I use which ?

    Thanks
     
    Last edited: Dec 27, 2017
  2. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,873
    Still not covered in the docs.

    Did you (or anyone else) ever get an answer to this?
     
  3. SolidAlloy

    SolidAlloy

    Joined:
    Oct 21, 2019
    Posts:
    58
    From what I've tested, the attributes do not differ in terms of how often they are called. Both attributes are executed after the scripts reload, so if you worry that some attribute won't execute after a domain reload - that's not an issue as both are called if there are no compilation errors.

    The main difference is that DidReloadScripts accepts a priority parameter, so if you have multiple classes that depend on each other and need to do things after a domain reload, you can arrange them the way you want so that one class is initialized before the other.

    If you don't need to set a specific priority, it only comes down to showing your intent through code. I like using InitializeOnLoad when I need to initialize some static members of the class, and DidReloadScripts when I need to check something after a domain reload (e.g. which new types were added or removed) and it's not about the class initialization (which is pretty rare).

    If you wonder about the order of InitializeOnLoad and DidReloadScripts, InitializeOnLoad and InitializeOnLoadMethod are always called before DidReloadScripts. But the order of different InitializeOnLoad and InitializeOnLoadMethod attributes cannot be determined, so don't rely on it if you got lucky and one class got initialized before the other one. Always rely on DidReloadScripts if you need to make sure one class is initialized before the other.

    Remember I said that both attributes are called after a domain reload if there are no compilation errors? There is a bug that I discovered the hard way: the methods assigned to the attributes are executed when the editor opens and there are compilation errors in the project. The bug won't happen when the project is already open and you accidentally create a compilation error. The assemblies with compilation errors won't be loaded into the domain, but the InitializeOnLoad and DidReloadScripts methods will be executed anyway, which may lead to some unexpected behavior, so be aware.
     
  4. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,873
    That bug would be an amazing feature. As far as I can tell there is no way to workaround bugs/missing features in Unity's assetdatabase refresh if they generate Build Errors - it runs some basic build checks before it fires any callbacks (from trial-and-error, and the docs on AssetDatabase refreshing say the same thing) which prevent you from doing anything to fix it.

    That first-time bug could be leveraged to fix things in this situation.

    In fact ... it might be the 'bug' is a deliberate feature because otherwise I'm not sure how Unity themself in the older versions of Editor (before some of this got refactored) would implement a lot of the rendering and reacting code that fires when Editor starts up and there are build errors.
     
  5. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,200
    Does DidReloadScripts get called when you start the editor?
     
  6. SolidAlloy

    SolidAlloy

    Joined:
    Oct 21, 2019
    Posts:
    58
    @Baste Yes, and as I mentioned, it gets called on editor start even if there are compilation errors in the project.

    @a436t4ataf Yeah, now that you mentioned it, it may be a deliberate feature to initialize some main EditorWindows, etc. However, I would prefer a separate attribute to be called on editor start, not the one with the name "DidReloadScripts". I searched for some types in TypeCache inside a DidReloadScripts method, and I sometimes got much fewer types inside TypeCache when the editor started up. It had confused the hell out of me until I realized it happened because sometimes there were compilation errors and some types weren't gathered by TypeCache because their respective assemblies weren't loaded into the domain.
     
    a436t4ataf likes this.