- Home /
Mathf.lerp to increase intensity and range of pointlight
Hello hello dear people it's Anna! I am working on a piece where I have point lights with rigid bodies flying around. When they collide with certain game Objects they change color and make a sound. This already works perfectly. But now I want them to increase range and intensity over time and then go back to normal (maybe during 2 sec). For some reason it doesn't seem to be working. This is the code at the moment:
public float minimumIntensity = 7f; public float maximumIntensity = 100f; public float minimumRange = 1f; public float maximumRange = 10f;
//starting value for lerp
//Make slider
[SerializeField]
[Range(0f, 1f)]
public float t = 0.0f;
void OnCollisionEnter(Collision collisionInfo)
{
if (collisionInfo.collider.tag == "Musicplant" || collisionInfo.collider.tag == "Plant")
{
currentColor = colorList[random.Next(0, colorList.Count - 1)];
pointLight.intensity = Mathf.Lerp(minimumIntensity, maximumIntensity, t);
pointLight.range = Mathf.Lerp(minimumRange, maximumRange, t);
//increase the t interpolater
t += 0.2f * Time.deltaTime;
Once this works, I would add this second part to decrease it again:
// now check if the interpolator has reached 1.0
// and swap maximum and minimum so game object moves
// in the opposite direction.
if (t > 1.0f)
{
float temp = maximumIntensity;
maximumIntensity = minimumIntensity;
minimumIntensity = maximumIntensity;
minimumIntensity = temp;
float tempp = maximumRange;
maximumRange = minimumRange;
minimumRange = maximumRange;
minimumRange = tempp;
t = 0.0f;
}
}
}
I think the problem lies with time.deltaTime since pointLight.intensity += 20f works but pointLight.intensity += 20f * time.deltaTime doesn't do anything at all.
Anybody has an idea or a solution? Thanks for reading!
The thing is that OnCollisionEnter() gets called only once when colliding with something and thus, you barely see any effect. $$anonymous$$aybe you should start a coroutine once the collision starts. Also, do take a look at $$anonymous$$athf.PingPong() since you want to reverse the effect afterwards.
Oooh I see! Thank you so much for the quick answer @Dragate
OnCollisionEnter is a coroutine, so you can treat it as one, just changing void for IEnumerator and adding the yield instruction
Heey guys, So I put it in a coroutine and start it onCollision Enter. To test it I'm still simply using pointLight.intensity += 5f * Time.deltaTime; And it's still not working... without Time.deltaTime it is working though. What am I missing here?
void OnCollisionEnter(Collision collisionInfo) { if (collisionInfo.collider.tag == "$$anonymous$$usicplant" || collisionInfo.collider.tag == "Plant") { currentColor = colorList[random.Next(0, colorList.Count - 1)];
StartCoroutine(flashLight());
}
}
public float $$anonymous$$imumIntensity = 7f;
public float maximumIntensity = 100f;
public float $$anonymous$$imumRange = 1f;
public float maximumRange = 10f;
//starting value for lerp
[SerializeField]
[Range(0f, 1f)]
public float t = 0.0f;
IEnumerator flashLight()
{
pointLight.intensity += 5f * Time.deltaTime;
pointLight.range += 1f * Time.deltaTime;
/*
pointLight.intensity = $$anonymous$$athf.Lerp($$anonymous$$imumIntensity, maximumIntensity, t);
pointLight.range = $$anonymous$$athf.Lerp($$anonymous$$imumRange, maximumRange, t);
//increase the t interpolater
t += 0.2f * Time.deltaTime;
// now check if the interpolator has reached 1.0
// and swap maximum and $$anonymous$$imum so game object moves
// in the opposite direction.
if (t > 1.0f)
{
float temp = maximumIntensity;
maximumIntensity = $$anonymous$$imumIntensity;
$$anonymous$$imumIntensity = maximumIntensity;
$$anonymous$$imumIntensity = temp;
float tempp = maximumRange;
maximumRange = $$anonymous$$imumRange;
$$anonymous$$imumRange = maximumRange;
$$anonymous$$imumRange = tempp;
t = 0.0f;
}*/
yield return new WaitForSeconds(10);
}
Answer by mjahlv · Jul 30, 2019 at 06:30 PM
The problem is that OnCollisionEnter only runs when a collision is detected, and so your code only runs when it detects a collision.
Time.deltaTime is the time since the last frame. If you do 20f * time.Delta time your result will be a single value that you then add on. This approach is correct, however you're only doing it once when you register a collision when instead you need to do it every frame for 2 seconds.
What you want is a coroutine that executes on collision:
//We want somewhere to store the coroutine so we can stop it on another collision
Coroutine myCoroutine;
void OnCollisionEnter(Collision collisionInfo)
{
if (collisionInfo.collider.tag == "Musicplant" || collisionInfo.collider.tag == "Plant")
{
//Set the colour of the light on collision
currentColor = colorList[random.Next(0, colorList.Count - 1)];
//First we want to check for an existing coroutine. If we have one, we need to stop it!
if (myCoroutine != null)
StopCoroutine(myCoroutine);
//Then we initiate a new coroutine to run the light
myCoroutine = StartCoroutine(LightCoroutine());
}
}
IEnumerator LightCoroutine()
{
float t = 0;
while (t < 1f) //This will take 1 second
{
//T will work towards 1, giving us the maximum intensity
pointLight.intensity = Mathf.Lerp(minimumIntensity, maximumIntensity, t);
pointLight.range = Mathf.Lerp(minimumRange, maximumRange, t);
t += Time.deltaTime; //Add the time since the last frame
yield return null; //Wait for the next frame
}
while (t > 0f) //This will take 1 second
{
pointLight.intensity = Mathf.Lerp(minimumIntensity, maximumIntensity, t);
pointLight.range = Mathf.Lerp(minimumRange, maximumRange, t);
t -= Time.deltaTime; //Subtract the time since the last frame
yield return null; //Wait for the next frame
}
}
The coroutine is then called every time there is a valid collision. It will stop the old one beforehand too in case you get another collision within 2 seconds. What would happen is the coroutine will run again starting from 0!
There's probably other approaches towards this that might be better, but I thought I would try to retain the basic logic of your code in my answer!
More info on coroutines: https://docs.unity3d.com/Manual/Coroutines.html
This works and I understand now what I did wrong. Thank you soo much! I'm super happy to see the glows everywhere now :D