I want to have an object fade to transparency over time when OnTriggerEnter is called.
How do I best achieve this? (I’m using C#)
I have a function Fade() that Lerps the object’s opacity.
Do I:
set a bool on OnTriggerEnter, have it checked in Update and then execute Fade() directly from update?
create a new Thread and calculate the float without the help of Unity’s Mathf.Lerp
make my function Fade() into an IEnumerator Fade() containing a while() loop that yields return null after each run through?
I’m kind of leaning towards the third option, but I’m not sure it is a good idea because I feel like I don’t really understand a lot about Coroutines/ rarely see them used in other people’s scripts. Is there a disadvantage in executing a while loop inside an IEnumerator compared to just calling a function from Update()?
Update Loop:
You’ll always be running the condition check whether your fading code should still be executed, and this happens throughout the whole time your script is enabled. If that’s only a trivial check as in your case, it’s not a significant overhead at all.
Coroutine:
You might get a little extra garbage, which sounds bad at first, but isn’t a huge overhead either. The code will only be run as long as the coroutine keeps yielding, once it is done, there’s nothing left to process, not even a the ‘should this still be run’-flag in update.
Additional information:
Just like the ‘Start’ method, some other of the engine’s callbacks can be turned into a coroutine, this applies to the trigger and collision callbacks as well:
private IEnumerator OnTriggerEnter(Collider collider)
{
// do something
yield return ...
// do something
}
Keep in mind that you most-likely want to prevent multiple coroutines from running, it’s up to you how you want to handle the situation.
One way to handle this situation could be the following, in which any new coroutine will be signaled to to be removed immediately as long as there is an active one:
private bool _isCoroutineActive = false;
private IEnumerator OnTriggerEnter(Collider collider)
{
if (_isCoroutineActive)
{
// cancel the new routine
yield break;
}
// signal that a rountine is already running
_isCoroutineActive = true;
// do something
yield return null;
// do something
// signal that the active routine has finished
_isCoroutineActive = false;
}
After all, there’s nothing much to worry about. Both are commonly used techniques.
I’m one of the guys that appreciates the concept of coroutines, others do not like them at all.