Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question OnGUI only works when Game tab is visible (?)

Discussion in 'Editor & General Support' started by BuzzKirill, May 30, 2020.

  1. BuzzKirill

    BuzzKirill

    Joined:
    Nov 14, 2017
    Posts:
    51
    I'm working on a cinematic cutscene in the Timeline. There's a scene where I wanted the light to flicker, and have the lamp object's material's Emission value reflect the light Intensity via script (so I don't have to manually key-frame it).

    To that end, I've written a short script.
    Please keep in mind that I'm mostly just an artist working on the game, so the following might contain some horrible mistakes:
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. [ExecuteAlways] //so that it works in the Editor, which is what I want
    4. public class CeilingFanLightController : MonoBehaviour
    5. {
    6.     //I'm gonna take the light's intensity value and multiply my Emission color by it. And a few steps in-between.
    7.  
    8.     public GameObject myLamp;    //putting the lamp object here so I can access its material's Emission value.
    9.     public GameObject lightObject;    //putting the light object here so I can access its Light component.
    10.     public Color myColor;    //base color that's gonna be multiplied. I have it as ALMOST black, so that the emission almost doesn't show when off.
    11.     //if I make it pure black, then it won't brighten when multiplied.
    12.  
    13.     public float Multiplier = 22;   //A large enough value for the light's intensity value to be multiplied by.
    14.     [SerializeField]   //so I can visually see the following in the Editor:
    15.     private float MultipliedIntensity;   //equals to light intensity * Multiplier.
    16.     [SerializeField]
    17.     private Color finalColor;   //the color that I want to constantly* be assigned as the emissioncolor.
    18.        
    19.     private void OnGUI()   //*this is the CONSTANTLY part.
    20.     {
    21.         MultipliedIntensity = lightObject.GetComponent<Light>().intensity*Multiplier;    //so the small intensity changes become large enough to affect the color parameter.  
    22.         finalColor = myColor * MultipliedIntensity;   //getting that almost-black-but-not-quite initial Color and cranking it up a bunch.
    23.         myLamp.GetComponent<Renderer>().material.SetColor("_EmissionColor", finalColor);
    24.     }
    25. }
    26.  
    Even still, this works exactly as I intended! Except... for some reason, only when the Game tab is visible in the Editor.

    Strangely (for me), If I change the function to Update(), then it works even if the Game is not visible.
    Could anyone explain to a noob what's going on? Also, alternative more elegant solutions are welcome. Though, since I'm interested in scripting, I'd be glad to understand why my code has this unintended side-effect.

    Because Update seems to lag a frame behind (the emission changes a frame later than the intensity does), which is kind of unacceptable in this case.
    It's very inconvenient to have to launch the game and wait for it to compile, then get to a certain point, not being able to rewind, etc.
    Because I'm almost a total noob when it comes to scripting. I work as a 3D generalist, but I'd like to learn more about coding and stuff.

    Edit: Now that I notice it, even when using OnGUI, the emission still lags a frame behind in the Game window. It does not lag in the Editor, though.