Search code examples
c#unity-game-engineunity-editor

Get Unity Editor-Only Variable (color of splash screen background) at Runtime


To create a dynamic fade-in effect from Unity's splash screen, I am trying to get the color of the splash screen background at runtime.

In the editor, the color can be found at Edit > Project Settings > Player > Splash Image > Background.

While researching on how to get this color, I stumbled upon PlayerSettings.SplashScreen.backgroundColor. However, the PlayerSettings class is contained in the UnityEditor namespace, which cannot be accessed at runtime.

How could I dynamically during runtime get the color of the splash screen background?


Edit: Using an IL decompiler I discovered that the UnityEditor assembly solves this with an external method. However, I still don't see a way to fetch the background color out of the editor assembly.

public static Color backgroundColor
{
    get
    {
        Color result;
        PlayerSettings.SplashScreen.INTERNAL_get_backgroundColor(out result);
        return result;
    }
    // ...
}

private static extern void INTERNAL_get_backgroundColor(out Color value);

Solution

  • Unity's built with the assumption that you'll never need this value at runtime so you'll need to pull some tricks to get around that. Something I've often done to solve this particular issue of making editor-only variables accessable is writing a pre-build step that saves any wanted data to a resource file that can then be read during runtime.

    The only API's you'd need to do this are the IPreprocessBuild interface, Resources.Load, and the MenuItem attribute (MenuItem is optional but will make your workflow a bit easier).

    First, implement an IPreprocessBuild (this one goes in an "Editor" directory and references UnityEditor) to save off the setting to a resource:

    class BackgroundColorSaver : IPreprocessBuild
    {
        public int callbackOrder { get { return 0; } } // Set this accordingly
        public void OnPreprocessBuild(BuildTarget target, string path)
        {
            SaveBkgColor();
        }
    
        [MenuItem("MyMenu/Save Background Splash Color")]
        public static void SaveBkgColor()
        {
            // Save PlayerSettings.SplashScreen.backgroundColor to a
            // file somewhere in your "Resources" directory 
        }
    }
    

    This class will have SaveBkgColor() called any time a build is kicked off and the MenuItem tag gives you the option to also call the function whenever you'd like (makes testing/iteration easier).

    Afterwards, you'll want to write a runtime script that simply uses Resources.Load to load your asset and parse it/convert it into a Color object.


    Those are the basics when it comes to making "editor-only" resources available during runtime. Some specifics for the most straight-forward way of doing this with a Color:

    Also keep in mind that since you want this to be a blend from the splash screen, you're going to need to have this code run immediately (probably in an Awake() function on some behaviour in your first scene).


    Side note: There are more efficient ways to save/load the Color as a binary blob instead of a raw text asset but this is straight-forward and that part can easily be swapped in and out while leaving the IPreprocessBuild implementation intact.