Home > Enterprise >  How to make 2D Flickering light in Unity?
How to make 2D Flickering light in Unity?

Time:03-08

i need help, please. I just need to make flickering 2Dlight (using Unviversal Pipeline). After some time, the light begins to flickering and returns to its original value(light.intensivity = 0.36f), and after some time he start flickering again. But with this bad code i can't do that, flickering only works because coroutine everytime restarting(StartCoroutine(LightFlicker()); in coroutine). but i don't have ideas anymore how to make this thing. Maybe use another method to flickering light ?

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering.Universal;
using UnityEngine.Experimental;

using UnityEngine.Experimental.Rendering.LWRP;



public class FlickeringLight : MonoBehaviour {
    public UnityEngine.Experimental.Rendering.Universal.Light2D renderLight;
    public AudioSource AS; // AudioSource to play the audio.
    public AudioClip LightAudio; // Audio to play. 
    [SerializeField] float firstValue = 0f;
    [SerializeField] float secondValue = 0.36f;
    [SerializeField] float secondsBetweenFlickers = 2f;

    void Start ()
    {
        renderLight.intensity = renderLight.intensity;
        StartCoroutine(LightFlicker());
    }
    private void Awake()
    {
    renderLight = GetComponent​<UnityEngine.Experimental.Rendering.Universal.Light2D​>();
    }

    IEnumerator LightFlicker()
    {    
            renderLight.intensity = Random.Range(firstValue, secondValue);
            yield return new WaitForSeconds(secondsBetweenFlickers);
            AS.PlayOneShot(LightAudio); // Play the audio.
            StartCoroutine(LightFlicker());
    }

    //failed try to pause Coroutine LightFLicker
   /* IEnumerator TimerLight()
    {
        StopCoroutine(LightFlicker());
        renderLight.intensity = 0.36f;
        yield return new WaitForSeconds(3f);
        StartCoroutine(LightFlicker());
     
    }
   */
   
}```

CodePudding user response:

Add a while loop to never stop the coroutine

IEnumerator TimerLight()
{
    while (true)
    {
        renderLight.intensity = Random.Range(firstValue, secondValue);
        yield return new WaitForSeconds(secondsBetweenFlickers);
    }
}

Then you can try playing with random wait time if you like

IEnumerator TimerLight()
{
    while (true)
    {
        renderLight.intensity = Random.Range(firstValue, secondValue);
        var randomTime = Random.Range(0, secondsBetweenFlickers);
        yield return new WaitForSeconds(randomTime);
    }
}

And perhaps you want some kind of moving average to make it smooth at times.

private Queue<float> queue; // TODO: initialize
private int smoothing = 5;

IEnumerator TimerLight()
{
    var sum = 0f;

    while (true)
    {
        while (queue.Count > smoothing)
        {
            sum -= queue.Dequeue();
        }
        var newValue = Random.Range(firstValue, secondValue);
        queue.enque(newValue);
        sum  = newValue;
        renderLight.intensity = sum / queue.Count;

        yield return new WaitForEndOfFrame();
    }
}

I haven't tested this code, but it should be almost functional. Cause I've used this moving average queue for flickering light in unity before. I think it was running every frame...

  • Related