Get _Time from shader for script

I have an ocean shader that uses a vertex sine wave to make waves on a grid mesh.

I have an object that I want to float in the ocean. I can use the exact same sine wave to get a y position for the floating object. I have done this in a shader for the floating object and it works perfect.

I have a water vehicle that I want to float in the ocean. I can use the exact same sine wave to get a y position for the floating object. But I can’t do it in a shader because I need the collision working and that gets all messed up. Therefore I need to do this using a script. And that’s simple. Except I can’t figure out how to sync up the time in the script to the time in the shader.

Script time is Time.time.

Shader time is _Time.

They do not appear to be in sync.

I tried to use the following:

float timeY = renderer.material.GetVector(“_Time”);

But it only returns (0, 0, 0, 0).

Any suggestions on how to sync my times between script and shaders?

Thanks

Anton

Pass the Time.time variable to the shader with:

On Update(){
  float theUnityTime = Time.time;
  myCustomMaterial.SetFloat("unityTime",theUnityTime);
}

Then declare this in your shader to access it:

float unityTime;

yeah, that is what i did. it was right in front of my face too. :stuck_out_tongue_winking_eye:

You can get the shader’s _Time value from a C# script by calling this:

Shader.GetGlobalVector("_Time")

This way, you don’t have to modify your shaders to use a custom time variable.

Shader.GetGlobalVector(“_Time”)[1] or Shader.GetGlobalVector(“_Time”)[0]? Seems to be out of sync for me

1 Like

It depends if you are in play mode or not, otherwise EditorApplication.timeSinceStartup is what’s being fed to the _Time parameter in shaderland. While in play mode it’s Time.time. This what I use in my buoyancy script and it matches the _Time.x value used in shaders:

private static float _Time
        {
            get
            {
#if UNITY_EDITOR
                return Application.isPlaying ? Time.time : Shader.GetGlobalVector("_Time").x;
#else
                return Time.time;
#endif
            }
        }
4 Likes

By Unity docs, _Time.y is the game time, _Time.x is the 1/20 of time.