I am trying to make "wet footprints", but am encountering some issues with fading out the color and resetting it to it's starting color when the step is reused. I have a gameObject array with a couple of footstep gameobject and they are placed on the position of the players foot when it touches the ground. It is currently pooling those steps, which is all working fine. Since I want to keep it as lightweight possible I am using a decal shader with a propertyblock and I need to fade out the _MainColor property when the object is placed, and when that same object is used again on a different position it needs to be reset. The problem is however the fading isn't working in it's current setup. What currently happens is the color is reset to black when it is reused and it's suppose to do the fade out again, but instead it just instantly transparent again.
void Update()
{
if (lastPos != transform.position)
{
stepPositioner = true;
lastPos = transform.position;
//Debug.Log("This Go changed position: ", this);
}
if (stepPositioner)
{
StartCoroutine(FadeTimer());
}
}
IEnumerator FadeTimer()
{
_renderer.GetPropertyBlock(_propertyBlock);
_propertyBlock.SetColor("_MainColor", startColor);
_renderer.SetPropertyBlock(_propertyBlock);
yield return new WaitForSeconds(1);
_renderer.GetPropertyBlock(_propertyBlock);
_propertyBlock.SetColor("_MainColor", Color.Lerp(startColor, endColor, Time.time * .5f));
_renderer.SetPropertyBlock(_propertyBlock);
stepPositioner = false;
}
That's not how Lerp
works.
Linearly interpolates between colors a and b by t.
t is clamped between 0 and 1. When t is 0 returns a. When t is 1 returns b.
You are calling it only once with a pritty small factor of about 0.5/60 so around 0.008333
resulting in almost the start value.
Additionally you wait one second before resetting the stepPositiontimet
so for one second you Update
method starts a few hundred concurrent Coroutines!
For fading out the color over one second use something like
IEnumerator FadeTimer(float duration)
{
// This has to be done right away!
// Otherwise you get concurrent routines!
stepPositioner = false;
_renderer.GetPropertyBlock(_propertyBlock);
_propertyBlock.SetColor("_MainColor", startColor);
_renderer.SetPropertyBlock(_propertyBlock);
var timePassed = 0f;
while (timePassed < duration)
{
_renderer.GetPropertyBlock(_propertyBlock);
_propertyBlock.SetColor("_MainColor", Color.Lerp(startColor, endColor, timePassed / duration));
_renderer.SetPropertyBlock(_propertyBlock);
// Add the time since last frame
timePassed += Time.deltaTime;
// Tells Unity to "pause" the routine, render this frame
// and continue from here in the next frame
yield return null;
}
// Just to be sure set the final value in the end
_renderer.GetPropertyBlock(_propertyBlock);
_propertyBlock.SetColor("_MainColor", endColor, );
_renderer.SetPropertyBlock(_propertyBlock);
}
Just added the duration as parameter to make it clearer and more flexible. So just call it as
StarCoroutine(FadeTimer(2));
e.g. to fade within 2 seconds
Note: Typed on smartphone but I hope the idea gets clear