- Home /
Is there a way to save global shader variables?
Is there a good way to save global shader variables/properties?
I've got several different shaders which are supposed to all share the same variable, and I want the player to be able to change this value whenever they want. Right now I'm controlling this with a C# script and using the Shader.SetGlobalInt function to set the variable, and this does largely work, however, every time I exit Unity, the global variable isn't saved and resets to zero next time I open, and this is particularly annoying for this set of shaders specifically because a value of zero makes things invisible.
If I press play, the objects will become visible again and remain visible after exiting play mode (this is because Shader.SetGlobalInt will be used to correct the global variable in a start function on an empty game object), however, it's still rather annoying and I feel like there's probably a better way to do this.
Something I've noticed in writing shaders is that there are some built-in adjustable variables which can be used by shader code like unity_FogStart or unity_FogEnd. I think that ideally I'd want to be able to simply create a new custom variable like those which doesn't rely on any game object if that's possible.
Generally I just want to know what'd be the best way to go about this sort of problem. Thanks in advance!
Answer by SirSquid · Dec 11, 2021 at 09:16 PM
Okay, I managed to find a solution:
I saved my variable with PlayerPrefs.SetInt
so it'll persist every time I open/close Unity or the game.
I made a script utilizing [InitializeOnLoad]
to set the value as soon as I open the editor, and I put this script in a folder named "Editor" which Unity excludes from builds so I wouldn't have build errors.
And I made another script to cover setting the value when the game loads utilizing this: https://docs.unity3d.com/ScriptReference/RuntimeInitializeOnLoadMethodAttribute.html and using Shader.SetGlobalInt("Name", PlayerPrefs.GetInt("Name"))
to get the value from PlayerPrefs.
It's working great in both the editor and builds, so it's all good now.
Answer by Eno-Khaon · Dec 07, 2021 at 10:53 PM
If I'm not mistaking this, the problem comes up when starting the Unity Editor, and not the game itself (based on your mention of "press[ing] play" to get it into the right state).
You can make use of an editor script utilizing [InitializeOnLoad]
as mentioned in Unity's documentation on Running Editor Script Code on Launch.
using UnityEngine;
using UnityEditor;
[InitializeOnLoad]
public class Startup
{
static Startup()
{
Shader.SetGlobalInt(myGlobalShaderValue);
}
}
I tried it out and does work, however, the [InitializeOnLoad] line also prevents the game from building for some reason (at this point the startup script won't actually be needed, but this means in order to build I need to get rid of that line in the startup script every time I do it).
Yeah, editor scripts won't build into a game. You can get around that by putting them into an "Editor" folder in your project (any such folder is culled during the build process), or use conditional compilation blocks around them:
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
[InitializeOnLoad]
public class Startup
{
#if UNITY_EDITOR
static Startup()
{
Shader.SetGlobalInt(myGlobalShaderValue);
}
#endif
}
Your answer
![](https://koobas.hobune.stream/wayback/20220613050321im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Shader Problem 0 Answers
perform action on shader compilation/update 0 Answers
Unity 3d Sprite Shader (How do I limit Max Brightness to 1 with Multiple Lights Hitting) 0 Answers
Referencing the current pixel's world coordinates in the SURF block of a shader 1 Answer
Need help with outline shader 0 Answers