- Home /
How to Randomly Change the Intensity of a Point Light with a Script
I am creating a fire and I made it emit some light using a Point Light. How can I randomly change the intensity of the Point Light using a script?
Answer by Statement · Jan 08, 2011 at 11:13 PM
I cooked you a script that looks rather nice. Just add it to a light and adjust min and max intensity to suit your flavor. The random part is there so that different lights behave slightly differently. Otherwise they would all flicker in sync. You can probably also do something similar with your lights range, if you want to as well.
It works by sampling perlin noise which is gradient with respect to neighboring values. I then use Time.time to step through these values smoothly over time. I add a random value to avoid repetition among lights. The script only changes the attached lights intensity between minIntensity and maxIntensity. If you want to change how rapidly the flicker changes then you can multiply Time.time with some value, as that will cycle through the set much faster. Since PerlinNoise return noise in the interval 0 to 1, we can use this with linear interpolation to flicker between two set values.
using UnityEngine;
[RequireComponent(typeof(Light))]
public class SoftFlicker : MonoBehaviour
{
public float minIntensity = 0.25f;
public float maxIntensity = 0.5f;
float random;
void Start()
{
random = Random.Range(0.0f, 65535.0f);
}
void Update()
{
float noise = Mathf.PerlinNoise(random, Time.time);
light.intensity = Mathf.Lerp(minIntensity, maxIntensity, noise);
}
}
Here's the JS version if you rather prefer that.
@script RequireComponent(Light)
var minIntensity = 0.25f;
var maxIntensity = 0.5f;
private var random : float;
random = Random.Range(0.0f, 65535.0f);
function Update()
{
var noise = Mathf.PerlinNoise(random, Time.time);
light.intensity = Mathf.Lerp(minIntensity, maxIntensity, noise);
}
Answer by Jesse Anders · Jan 08, 2011 at 09:06 PM
I haven't done much scripting with Unity's light components, but I'd guess this could be accomplished by modifying properties of the light component (e.g. color, intensity, range) via scripting in real time.
The 'intensity' parameter might be a good place to start. Something that would be fairly easy to try would be simply to assign the value of Random.value to the 'intensity' field/property (with the range of the value adjusted appropriately).
To get a more realistic effect though, you may want to apply some sort of smoothing or hysteresis, or use a 'less random' method of generating the random input.
The smoothing you talk about can be easily achieved with $$anonymous$$athf.PerlinNoise
Answer by Noise crime · Jan 08, 2011 at 10:32 PM
Personally i'd use an animation for this and not a script. It will be far easier to control, tweak and obtain the effect you are after. Light.Intensity as well as other light properties are all exposed in the animation editor so its simple to generate the animation.
The problem with animations is that they loop. This doesn't look nice when looking at a fire for a long time.
Then you just create an arbitrarily long animation, besides how long do you stare at a fire? I seriously doubt anyone would notice it repeating if you made it a decent length (e.g. 10 seconds). But your script is a nice alternative.
I am not saying it's a no no. I just brought up a problem with it, worth considering. I actually upvoted you and Jesses answers. I think both contribute to the better.
Answer by Antigen_Z · Jul 12, 2015 at 09:41 PM
using System;
using UnityEngine;
using Random = UnityEngine.Random;
[RequireComponent(typeof (Light))]
public class TorchLight : MonoBehaviour {
public float MinLightIntensity = 0.6F;
public float MaxLightIntensity = 1.0F;
public float AccelerateTime = 0.15f;
private float _targetIntensity = 1.0f;
private float _lastIntensity = 1.0f;
private float _timePassed = 0.0f;
private Light _lt;
private const double Tolerance = 0.0001;
private void Start() {
_lt = GetComponent<Light>();
_lastIntensity = _lt.intensity;
FixedUpdate();
}
private void FixedUpdate() {
_timePassed += Time.deltaTime;
_lt.intensity = Mathf.Lerp(_lastIntensity, _targetIntensity, _timePassed/AccelerateTime);
if (Math.Abs(_lt.intensity - _targetIntensity) < Tolerance) {
_lastIntensity = _lt.intensity;
_targetIntensity = Random.Range(MinLightIntensity, MaxLightIntensity);
_timePassed = 0.0f;
}
}
}