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
  4. Dismiss Notice

[Solved] Run an editor script exactly once, when Unity launches

Discussion in 'Editor & General Support' started by nickfourtimes, Oct 27, 2020.

  1. nickfourtimes

    nickfourtimes

    Joined:
    Oct 13, 2010
    Posts:
    217
    I'm trying to run a little editor script exactly once, when Unity is launched. It looks something like this:

    Code (CSharp):
    1. [InitializeOnLoad]
    2. static class MyStartupCode {
    3.  
    4.     /// constructor
    5.     static MyStartupCode() {
    6.         // my code
    7.     }
    8.  
    9. }
    This does indeed run when the editor is first opened. However, it's also run every time my code recompiles (I'm assuming some assemblies are being reloaded/the static class is being reinitialised).

    I've seen someone mention using
    if (!EditorApplication.isPlayingOrWillChangePlaymode)
    , but this only prevents the code from running when I enter/exit Play mode.

    Can I prevent this code from being run every time my code compiles?
     
    Last edited: Oct 30, 2020
  2. enhawk

    enhawk

    Joined:
    Aug 22, 2013
    Posts:
    832
    have you tried using a boolean?
     
    nickfourtimes likes this.
  3. nickfourtimes

    nickfourtimes

    Joined:
    Oct 13, 2010
    Posts:
    217
    Yeah, I tried adding something like
    static bool hasRunOnce = false;
    to the class, and then setting it to "true" once the code runs. But it seems that the whole class is reinitialised when my code is recompiled... so it always reverts back to the default "false" value, and then my code runs again.
     
  4. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,184
    As far as I know, there is no callback for when the editor starts, and as you've already experienced, static variables will be deleted and recreated sooner or later (when the assembly reloads due to recompile or potentially enter play mode depending on your settings).

    So, you could use
    UnityEditor.SessionState
    to check if you've already initialized. This will persist for the entire duration while the editor is open.

    Code (CSharp):
    1. [InitializeOnLoad]
    2. static class MyStartupCode
    3. {
    4.     static MyStartupCode ()
    5.     {
    6.         if (!SessionState.GetBool("FirstInitDone", false))
    7.         {
    8.             // Startup code here...
    9.             Debug.Log("First Init.");
    10.          
    11.             SessionState.SetBool("FirstInitDone", true);
    12.         }
    13.     }
    14. }
     
    Last edited: Oct 28, 2020
  5. nickfourtimes

    nickfourtimes

    Joined:
    Oct 13, 2010
    Posts:
    217
    Hey, that's it – it works! I was considering a workaround using
    EditorPrefs
    but this is much more straightforward. Thanks so much!
     
  6. Tion-Gaming

    Tion-Gaming

    Joined:
    Jan 30, 2015
    Posts:
    28
    Honestly, this is one of the most helpful things ive read from unity forums. Thank you.
     
    xucian, DrSharky and Lanre like this.
  7. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    756
    Thanks! Available since v5.6 and I didn't know about this. Could've saved me some good hours here and there.
    I feel this info should be more available (not sure how)