Source file unity-csharp/2d-lighting/TorchFlicker2D.cs from the GDnD code examples. Download raw file
// GDnD wiki example
// Demonstrates: a flickering torch or candle made by driving Light2D.intensity and pointLightOuterRadius with Perlin noise
// Related pages: [[unity-2d-lighting]], [[lighting-for-mood-and-guidance]]
using UnityEngine;
using UnityEngine.Rendering.Universal; // Light2D lives in the URP package
// Put this on a GameObject that has a Light 2D component set to Light Type: Spot.
// Perlin noise changes smoothly, so the flame wavers instead of strobing the way
// Random.Range would every frame.
[RequireComponent(typeof(Light2D))]
public class TorchFlicker2D : MonoBehaviour
{
[Header("Intensity")]
[SerializeField] private float baseIntensity = 1.2f;
[SerializeField] private float intensityVariation = 0.35f;
[Header("Radius (Spot lights only)")]
[SerializeField] private float baseOuterRadius = 4f;
[SerializeField] private float radiusVariation = 0.3f;
[Header("Speed")]
[Tooltip("How fast the flicker changes. 2 to 6 suits a torch; above 10 looks electrical.")]
[SerializeField] private float flickerSpeed = 4f;
private Light2D light2D;
private float noiseOffset;
private void Awake()
{
light2D = GetComponent<Light2D>();
// A different starting point in the noise for each torch, so a row of
// torches does not flicker in perfect step.
noiseOffset = Random.Range(0f, 1000f);
}
private void Update()
{
float t = Time.time * flickerSpeed + noiseOffset;
// PerlinNoise returns roughly 0..1; shift it to -1..1 so the light
// goes both brighter and dimmer than its base value.
float flicker = Mathf.PerlinNoise(t, 0f) * 2f - 1f;
light2D.intensity = Mathf.Max(0f, baseIntensity + flicker * intensityVariation);
// Sample a second row of the noise so size and brightness are not identical.
if (light2D.lightType == Light2D.LightType.Point) // shown as "Spot" in the Inspector
{
float sizeFlicker = Mathf.PerlinNoise(t, 7.3f) * 2f - 1f;
light2D.pointLightOuterRadius = Mathf.Max(0.1f, baseOuterRadius + sizeFlicker * radiusVariation);
}
}
private void OnValidate()
{
baseIntensity = Mathf.Max(0f, baseIntensity);
baseOuterRadius = Mathf.Max(0.1f, baseOuterRadius);
flickerSpeed = Mathf.Max(0f, flickerSpeed);
}
}