Light intensity Lerp not functioning properly
I'm working on a Day/Night cycle, while I've got the clock time sorted, I want the Directional Light to transition its intensity from 1 to 0.3 over the course of time a bool is active. And then vice versa 12 "hours" later.
When I try this the intensity of the light hovers around 0.99 (More like 0.998564) and will not go lower, the intensity seems to bounce around like the value is being constantly reset, but I can't see why.
Again, so long as the beginTransition
bool is active, the light should either go from [0.3 to 1] or [1 to 0.3]
Answer by Dragate · Jul 17, 2019 at 04:48 PM
I think you're misunderstanding the 3rd argument of the Mathf.Lerp() function. With a stable fps, Time.deltaTime is pretty much a fixed number and from the code snippet you've given, so is duration. This means that in every frame you're passing to the function the same value. In the docs it says:
Linearly interpolates between a and b by t.
The parameter t is clamped to the range [0, 1].
When t = 0 returns a.
When t = 1 return b.When t = 0.5 returns the midpoint of a and b.
So if t stays the same number (not a increasing/decreasing value), Lerp() will keep returning the same value. There's sample code on how you should use the function properly in the link given.
Thanks, while this sorted the problem of the intensity lerping properly, is there some way I can guarantee that the duration between maxIllu$$anonymous$$ation
and $$anonymous$$Illu$$anonymous$$ation
will always be the same? So far I'm having to manually find the right number and would rather have a way of it changing depending on what the maxDaytime
variable is
public class Daylightmanager : $$anonymous$$onoBehaviour { private float daytime; private float maxIllu$$anonymous$$ation = 1.0f; private float $$anonymous$$Illu$$anonymous$$ation = 0.3f;
public Light daylight;
public float maxDaytime;
public float duration;
public int transitionCounter;
public bool nightTime = false;
public bool beginTransition = false;
static float t = 0.0f;
void Start()
{
daytime = maxDaytime / 3 - 5;
}
void Update()
{
transitionCounter = $$anonymous$$athf.RoundToInt(daytime);
if (daytime <= maxDaytime)
{
daytime += Time.deltaTime;
}
else if (daytime >= maxDaytime)
{
if (nightTime == false)
{
nightTime = true;
daytime = 0.0f;
transitionCounter = 0;
}
else if (nightTime == true)
{
nightTime = false;
daytime = 0.0f;
transitionCounter = 0;
}
}
switch (transitionCounter)
{
case 240:
beginTransition = true;
break;
case 480:
beginTransition = false;
t = 0.0f;
break;
}
if (beginTransition == true && nightTime == false)
{
t += duration * Time.deltaTime;
daylight.intensity = $$anonymous$$athf.Lerp($$anonymous$$Illu$$anonymous$$ation, maxIllu$$anonymous$$ation, t);
}
else if (beginTransition == true && nightTime == true)
{
t += duration * Time.deltaTime;
daylight.intensity = $$anonymous$$athf.Lerp(maxIllu$$anonymous$$ation, $$anonymous$$Illu$$anonymous$$ation, t);
}
}
}
If I'm understanding your question correctly, you want to set the duration variable just like you did with daytime (in Start). To make the duration variable correspond to seconds, it'd be better to have it like this:
t += Time.deltaTime / duration;
Now if duration = 10, it'd always take 10 seconds for t to reach 1 (from 0).
Tried that, no matter what I set Duration
to it always moves from $$anonymous$$Illu$$anonymous$$osity
to maxIllu$$anonymous$$osity
(or vice versa) in about 1 second.
You're right about my question I've not really explained it well. In this game a day will last 24 $$anonymous$$utes (1 second per $$anonymous$$ute) equating to around 1440 seconds per game day.
I want the light to transition from $$anonymous$$in to $$anonymous$$ax (and VV) between "3am/pm" and "9am/pm" hence the Switch statement transitionCounter
the case values are actually: "Case 1 = maxDaytime / 3" and "Case 2 = maxDaytime / 3 * 2" This equates to the 3 & 9 system mentioned above.
I'm trying to make the duration fit perfectly between these two times, so that the fade starts at 3 and stops at 9, so far it's either stopping before the clock reaches 9 or the clock reaches 9 before the light reaches it's target intensity level.
Hopefully that makes sense ^_^
[Edit]: I have altered the Switch code to the following:
if (transitionCounter == maxDaytime / 3)
{
transitionCode = "Begin";
}
else if (transitionCounter == maxDaytime / 3 * 2)
{
transitionCode = "Stop";
}
switch (transitionCode)
{
case "Begin":
beginTransition = true;
break;
case "Stop":
beginTransition = false;
t = 0.0f;
break;
}
I should also note that the game works in a "12 hour clock" type sense, hence the "Night time" bool. So each run of the clock is only 720 seconds
I cannot reproduce your issue. The lerping always works for the specified duration for me. Also debugged with your code (after some modifications):
public int transitionCounter;
private float daytime;
public float maxDaytime;
public bool nightTime = false;
public bool transition = false;
private float transitionStart;
private float transitionEnd;
private float duration;
private float maxIllu$$anonymous$$ation = 10f;
private float $$anonymous$$Illu$$anonymous$$ation = .3f;
public Light daylight;
private float t;
void Start() {
daytime = maxDaytime / 3 - 5;
transitionStart = maxDaytime / 3;
transitionEnd = maxDaytime / 3 * 2;
duration = $$anonymous$$athf.Abs (transitionStart - transitionEnd);
Debug.Log ("Transition starts at " + transitionStart + " and ends at " + transitionEnd);
}
void Update(){
transitionCounter = $$anonymous$$athf.RoundToInt(daytime);
if (daytime < maxDaytime) {
daytime += Time.deltaTime;
} else if (daytime >= maxDaytime) {
nightTime = !nightTime;
daytime = .0f;
}
if (transitionCounter == transitionStart && !transition) {
Debug.Log ("Start: " + Time.time);
transition = true;
t = .0f;
} else if (transitionCounter == transitionEnd && transition) {
Debug.Log ("End: " + Time.time);
transition = false;
}
if (transition == true) {
t += Time.deltaTime / duration;
if (nightTime == false) {
daylight.intensity = $$anonymous$$athf.Lerp ($$anonymous$$Illu$$anonymous$$ation, maxIllu$$anonymous$$ation, t);
} else if (nightTime == true) {
daylight.intensity = $$anonymous$$athf.Lerp (maxIllu$$anonymous$$ation, $$anonymous$$Illu$$anonymous$$ation, t);
}
}
}
That's really odd. But I tried your tidied & debugged version of my code and now it works perfectly? $$anonymous$$aybe it was some odd typo or that the code was so violently untidy that it wasn't working? But I tried it now with the tidy code and it works fine with whatever maxDaytime
value I put in. $$anonymous$$any thanks!
Your answer
Follow this Question
Related Questions
Question about Array indexing 0 Answers
Attaching Light lerp to in-game clock 1 Answer
Time.deltaTime and difference of Time.time not matching 0 Answers
Time.DeltaTime Bug 1 Answer