I am using URP with Rendering Layers enabled. I am trying to edit different Light’s renderLayerMask property at runtime. But the changes are never saved to the Light component. I’ve created this repo that demonstrates the issue:
Could someone help me figure out if I am doing something wrong, or if this is expected behavior? Thank you!
Here is the code that doesn’t seem to work:
using UnityEngine;
public class DemonstrateLightRenderLayerBug : MonoBehaviour
{
[SerializeField] private Light m_Light;
private bool toggle;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
toggle = !toggle;
Debug.Log($"Light mask was: {m_Light.renderingLayerMask}");
if (toggle)
{
m_Light.renderingLayerMask = 1 << (int)RenderLayer.RL0;
}
else
{
m_Light.renderingLayerMask = 1 << (int)RenderLayer.RL1;
}
Debug.Log($"Light mask became: {m_Light.renderingLayerMask}");
}
}
// RenderLayer is just a way to map the ints setup in Project Settings > Graphics > URP Global Settings > Rendering Layers (3D)
// 0 maps to RL0
// 1 maps to RL1
enum RenderLayer
{
RL0 = 0,
RL1 = 1,
}
}
Did you try disabling the light, changing the render layer, then enabling it?
Or simply disable/enable cycling it after you set the render layer?
ALSO: make sure whatever you’re after here… that you consider if you perhaps actually want the bitwise-NOT of your value (done with tilde operator). Are you masking or enabling, essentially.
Thanks for the tips! Just tried them to no effect unfortunately:
Disabling the Light component, changing the mask, then re-enabling the component did not fix
Changing the mask, then Disabling/Re-enabling, did not fix
Setting the Light gameobject to inactive, changing the mask, then re-activating the gameobject, did not fix
Changing the mask, then setting the Light gameobject to inactive, then re-activating did not fix
For my actual game, I want to enable a few specific Render Layers on the light, and change the enabled layers at runtime depending on what the player does. I think the bitwise-NOT would require I specify a lot more layers to ignore when setting the layer mask, right?
FWIW, I did try this code with a bitwise-NOT and it still didn’t update the Light when running the game in the editor:
Wanted to note that changing a MeshRenderer renderLayerMask at runtime in the same fashion works as I would expect it to. But I would also like to do this for Lights:
It almost feels like you’re not tweaking the light that you think you are… this often happens when your code references the light in the prefab (an asset on disk) when you think it is referencing the one in the scene at runtime.
Yea but I was able to reproduce the issue in a new project (the repo in the original post).
The scene in that project just has 1 directional light attached via SerializeField. So I am pretty sure I am not editing the wrong light in the example, and yet no update propagates into the scene runtime.