Search Unity

Lighting dosent update when changing skybox via script

Discussion in 'Scripting' started by Duffey, May 26, 2015.

  1. Duffey

    Duffey

    Joined:
    Jun 27, 2013
    Posts:
    12
    I would like to change the skybox at runtime. I am able to do this and the ambient light color does change, but the skybox reflections dont update to the new skybox. It works when I manually change the skyboxes in the editor, but not via script at runtime.

    Is there any way to update the default reflection probes by script when I change the skybox?
    I would really appreciate any help! I am using 5.0.2.
     
    Last edited: May 26, 2015
    unity_8EfWW9zAYqYzJw likes this.
  2. Duffey

    Duffey

    Joined:
    Jun 27, 2013
    Posts:
    12
    Ok, I solved this.
    For anyone else having this problem, I had to set the switch the "reflection source" in the lighting panel from skybox to custom, and in my script change the reflection cubemap when I changed the skybox.
     
  3. ptblk

    ptblk

    Joined:
    Mar 27, 2015
    Posts:
    57
    Hey can you post the script for this? been struggling for hours trying to figure it out. Thanks
     
  4. Duffey

    Duffey

    Joined:
    Jun 27, 2013
    Posts:
    12
    Sure, here is the script in an abbreviated form using just two skys;

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Skys : MonoBehaviour
    5. {
    6.     private int numOfSkys = 2; // total num of skys used
    7.     private int currentSky = 1;
    8.     private int skyCounter = 1;
    9.     public Light sunLight;
    10.  
    11.     public Material skyBox01; // HDR image for skybox that does the lighting
    12.     public Cubemap skyRef01; // HDR image for reflections
    13.     public float skyExposure01 = 1.0f; // Exposure of HDR used for lighting and GI
    14.     public Vector3 sunDirection01 = Vector3.zero; // Directional Light (Sun) angle
    15.     public float sunIntensity01 = 1.0f; // Intensity of directional light (sun)
    16.     public Color sunColor01 = Color.white; // Color of directional light (sun)
    17.  
    18.     public Material skyBox02;
    19.     public Cubemap skyRef02;
    20.     public float skyExposure02 = 1.0f;
    21.     public Vector3 sunDirection02 = Vector3.zero;
    22.     public float sunIntensity02 = 1.0f;
    23.     public Color sunColor02 = Color.white;
    24.    
    25.     // make sure skybox 1 is used at startup
    26.     void Start()
    27.      {
    28.        RenderSettings.skybox = skyBox01;
    29.        RenderSettings.customReflection = skyRef01;
    30.        RenderSettings.skybox.SetFloat("_Exposure", skyExposure01);
    31.        sunLight.transform.eulerAngles = sunDirection01;
    32.        sunLight.intensity = sunIntensity01;
    33.        sunLight.color = sunColor01;
    34.        skyCounter = 1;
    35.        currentSky = skyCounter;
    36.      }
    37.    
    38.     // Update is called once per frame
    39.     void Update ()
    40.     {
    41.         if(Input.GetKeyDown(KeyCode.F1))
    42.          {
    43.            skyCounter += 1;
    44.            if(skyCounter > numOfSkys){skyCounter = 1;}
    45.          }
    46.         if(Input.GetKeyDown(KeyCode.F2))
    47.          {
    48.            skyCounter -= 1;
    49.            if(skyCounter < 1 ){skyCounter = numOfSkys;}
    50.          }
    51.  
    52.         if(skyCounter != currentSky)
    53.         {
    54.           switch(skyCounter)
    55.             {
    56.             case 1:
    57.                 RenderSettings.skybox = skyBox01;
    58.                 RenderSettings.customReflection = skyRef01;
    59.                 RenderSettings.skybox.SetFloat("_Exposure", skyExposure01);
    60.                 sunLight.transform.eulerAngles = sunDirection01;
    61.                 sunLight.intensity = sunIntensity01;
    62.                 sunLight.color = sunColor01;
    63.                 break;
    64.                
    65.             case 2:
    66.                 RenderSettings.skybox = skyBox02;
    67.                 RenderSettings.customReflection = skyRef02;
    68.                 RenderSettings.skybox.SetFloat("_Exposure", skyExposure02);
    69.                 sunLight.transform.eulerAngles = sunDirection02;
    70.                 sunLight.intensity = sunIntensity02;
    71.                 sunLight.color = sunColor02;
    72.                 break;
    73.  
    74.             default:
    75.                 RenderSettings.skybox = skyBox01;
    76.                 RenderSettings.customReflection = skyRef01;
    77.                 RenderSettings.skybox.SetFloat("_Exposure", skyExposure01);
    78.                 sunLight.transform.eulerAngles = sunDirection01;
    79.                 sunLight.intensity = sunIntensity01;
    80.                 sunLight.color = sunColor01;
    81.                 break;
    82.             }
    83.          currentSky = skyCounter;
    84.        }
    85.     }
    86. }
    87.  
    This script will allow you to switch skys and its reflection map. "F1" key changes to the next sky (forwards) and "F2" changes to the previous sky (backwards). In my script I use ten skys, but I shortened this script for clarity using only two skys.

    For each sky it will also;
    - adjust the intensity of each lighting cubemap,
    - adjust the position of a directional "sun" light,
    - adjust the intensity of the directional light,
    - adjust the color of the directional light.
    This way you can set up the sky and its directional lighting to match each other.

    This script will create some slots in the inspector in which you will have to drag two versions of each sky, one slot is for the material which holds the lighting cupemap and uses the "skybox/cubemap" shader, and the other slot is for is a downsized version of the hdr in a cubemap which is for reflections. You will also need to drag the directional light into the appropriate slot.

    Since the sky and light parameters are only read at runtime, then placed into the other components, you can not adjust the settings in this script and see the changes in the editor. Instead, use the skybox/cubmap materal settings and the directional light component settings to set up the sky as you like, then copy the settings into this script. Run it and use the F1 and F2 keys to cycle through each sky.

    Another "trick" I have found is you can add a regular skybox component with the same hdr cubemap as a background. You will see this cubemap, but the other one (in the script above) will be used for the lighting. This way you can adjust the intensity of the lighting HDR without "blowing out" or changing the one you actually see, but you will have to switch it with the skys so it matchs (not included in the above script for clarity).

    Hope this helps!
     
  5. Arycama

    Arycama

    Joined:
    May 25, 2014
    Posts:
    184
    For my situation, calling "DynamicGI.UpdateEnvironment()" after assigning the new skybox at runtime would fix the issue.
     
  6. Christop

    Christop

    Joined:
    Aug 21, 2012
    Posts:
    60
    I used both approaches combined the DynamicGI.UpdateEnvironment() did not update the reflection source only recomputed the ambient light used by the dynamic GI.
    Unity 2017.4
     
    DCordoba likes this.
  7. Olninyo

    Olninyo

    Joined:
    Dec 17, 2012
    Posts:
    7
    magic, dynamic GI update worked for me too. much appreciated.
     
  8. dimitroff

    dimitroff

    Joined:
    Apr 3, 2013
    Posts:
    131
    For some reason DynamicGI.UpdateEnvironment did not work for me, in order to force an update of the Ambient lighting, I needed to set RenderSettings.ambientMode to Custom and set it back to Skybox, after I change the Skybox material. I guess this is a bug or something.
     
  9. bourp147

    bourp147

    Joined:
    Apr 1, 2022
    Posts:
    1
    Hey, mind if i get a look at the code for this?