- Home /
Camp fire light flicker control
Im trying to make a camp fire flicker. Its doing it, but its way too fast. How can i control the speed?
var minFlicker : float = 0.7;
var maxFlicker : float = 2;
function Update () {
light.intensity = (Random.Range (minFlicker, maxFlicker));
}
var flickerSpeed : float = 0.07;
private var randomizer : int = 0;
while (true)
{
if (randomizer == 0) {
light.enabled = false;
}
else light.enabled = true;
randomizer = Random.Range (0, 1.1);
yield WaitForSeconds (flickerSpeed);
}
or
// Properties
var waveFunction : String = "sin"; // possible values: sin, tri(angle), sqr(square), saw(tooth), inv(verted sawtooth), noise (random)
var base : float = 0.0; // start
var amplitude : float = 1.0; // amplitude of the wave
var phase : float = 0.0; // start point inside on wave cycle
var frequency : float = 0.5; // cycle frequency per second
// $$anonymous$$eep a copy of the original color
private var originalColor : Color;
// Store the original color
function Start () {
originalColor = GetComponent(Light).color;
}
function Update () {
var light : Light = GetComponent(Light);
light.color = originalColor * (EvalWave());
}
function EvalWave () {
var x : float = (Time.time + phase)*frequency;
var y : float;
x = x - $$anonymous$$athf.Floor(x); // normalized value (0..1)
if (waveFunction=="sin") {
y = $$anonymous$$athf.Sin(x*2*$$anonymous$$athf.PI);
}
else if (waveFunction=="tri") {
if (x < 0.5)
y = 4.0 * x - 1.0;
else
y = -4.0 * x + 3.0;
}
else if (waveFunction=="sqr") {
if (x < 0.5)
y = 1.0;
else
y = -1.0;
}
else if (waveFunction=="saw") {
y = x;
}
else if (waveFunction=="inv") {
y = 1.0 - x;
}
else if (waveFunction=="noise") {
y = 1 - (Random.value*2);
}
else {
y = 1.0;
}
return (y*amplitude)+base;
}
Answer by thornekey · Jul 07, 2014 at 10:37 AM
Thanks @Klarax
Your method worked. I changed it up a bit.
var minFlickerIntensity : float = 0.5;
var maxFlickerIntensity : float = 2.5;
var flickerSpeed : float = 0.035;
private var randomizer : int = 0;
while (true)
{
if (randomizer == 0) {
light.intensity = (Random.Range (minFlickerIntensity, maxFlickerIntensity));
}
else light.intensity = (Random.Range (minFlickerIntensity, maxFlickerIntensity));
randomizer = Random.Range (0, 1.1);
yield WaitForSeconds (flickerSpeed);
}
Answer by LaneFox · Sep 09, 2016 at 06:27 PM
Here's one in C#. It uses the base intensity of the light and adds/subtracts to it instead of directly changing the light value. This gives a little more flexibility so you can add the Flicker with a good flickering effect while not corrupting the light intensities.
using UnityEngine;
using System.Collections;
public class Flicker : MonoBehaviour
{
public float MaxReduction;
public float MaxIncrease;
public float RateDamping;
public float Strength;
public bool StopFlickering;
private Light _lightSource;
private float _baseIntensity;
private bool _flickering;
public void Reset()
{
MaxReduction = 0.2f;
MaxIncrease = 0.2f;
RateDamping = 0.1f;
Strength = 300;
}
public void Start()
{
_lightSource = GetComponent<Light>();
if (_lightSource == null)
{
Debug.LogError("Flicker script must have a Light Component on the same GameObject.");
return;
}
_baseIntensity = _lightSource.intensity;
StartCoroutine(DoFlicker());
}
void Update()
{
if (!StopFlickering && !_flickering)
{
StartCoroutine(DoFlicker());
}
}
private IEnumerator DoFlicker()
{
_flickering = true;
while (!StopFlickering)
{
_lightSource.intensity = Mathf.Lerp(_lightSource.intensity, Random.Range(_baseIntensity - MaxReduction, _baseIntensity + MaxIncrease), Strength * Time.deltaTime);
yield return new WaitForSeconds(RateDamping);
}
_flickering = false;
}
}
Answer by rogodoy · Feb 04, 2019 at 04:25 PM
Best way is using light intensy by creating a float value for light intensity in update function.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FlickeringLight : MonoBehaviour
{
public Light flickeringLight;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
float lickerIntensity = Random.Range(0.0f,5.0f);// use float values to get smoothing intensity variation
flickeringLight.intensity = lickerIntensity;
}
}
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class FlickeringLight : MonoBehaviour { public Light flickeringLight;
void Start()
{
}
void Update()
{
float lickerIntensity = Random.Range(0.0f,5.0f);// use float values to get smoothing intensity variation, using void update will update every frame.
flickeringLight.intensity = lickerIntensity;
}
Answer by Wollbobaggins · Mar 18, 2021 at 02:00 AM
In the event that anyone is still looking for this today, I elaborated off of @LaneFox's solution to make the light look more like a fire light rather than a light bulb. Here was my script.
Edit: I didn't really hypertune the variables, but the settings I found are okay.
/**
* File Name: LightFlicker.cs
* Description: Script for flickering a light source; the default configuration aims to mimic fire
* light
*
* Authors: LaneFox [Unity Forum Profile], Will Lacey
* Date Created: March 17, 2021
*
* Additional Comments:
* The original version of this file can be found here:
* https://answers.unity.com/questions/742466/camp-fire-light-flicker-control.html on the
* forum "Camp fire light flicker control" written by LaneFox; this file has been updated it
* to better fit this project
*
* Line Length: 100 Characters
**/
using UnityEngine;
/// <summary>
/// a flickering a light source
/// </summary>
[RequireComponent(typeof(Light))]
public class LightFlicker : MonoBehaviour
{
/************************************************************/
#region Variables
[Tooltip("maximum possible intensity the light can flicker to")]
[SerializeField, Min(0)] float maxIntensity = 150f;
[Tooltip("minimum possible intensity the light can flicker to")]
[SerializeField, Min(0)] float minIntensity = 50f;
[Tooltip("maximum frequency of often the light will flicker in seconds")]
[SerializeField, Min(0)] float maxFlickerFrequency = 1f;
[Tooltip("minimum frequency of often the light will flicker in seconds")]
[SerializeField, Min(0)] float minFlickerFrequency = 0.1f;
[Tooltip("how fast the light will flicker to it's next intensity (a very high value will)" +
"look like a dying lightbulb while a lower value will look more like an organic fire")]
[SerializeField, Min(0)] float strength = 5f;
float baseIntensity;
float nextIntensity;
float flickerFrequency;
float timeOfLastFlicker;
#endregion
/************************************************************/
#region Class Functions
private Light LightSource => GetComponent<Light>();
#endregion
/************************************************************/
#region Class Functions
#region Unity Functions
private void OnValidate()
{
if (maxIntensity < minIntensity) minIntensity = maxIntensity;
if (maxFlickerFrequency < minFlickerFrequency) minFlickerFrequency = maxFlickerFrequency;
}
private void Awake()
{
baseIntensity = LightSource.intensity;
timeOfLastFlicker = Time.time;
}
private void Update()
{
if (timeOfLastFlicker + flickerFrequency < Time.time)
{
timeOfLastFlicker = Time.time;
nextIntensity = Random.Range(minIntensity, maxIntensity);
flickerFrequency = Random.Range(minFlickerFrequency, maxFlickerFrequency);
}
Flicker();
}
#endregion
#region Other Light Functions
private void Flicker()
{
LightSource.intensity = Mathf.Lerp(
LightSource.intensity,
nextIntensity,
strength * Time.deltaTime
);
}
public void Reset()
{
LightSource.intensity = baseIntensity;
}
#endregion
#endregion
}