In my game, I play an animation, wait for the animation to end, and then I change the sprite image. Next I fade the sprite out, wait for the fade to end, then I disable the gameObject. Here's the code:
IEnumerator UnlockSequence()
{
anim.Play("unlock");
unlocking = false; // stops UnlockSequence from being called again
yield return new WaitForSeconds(1.7f);
sr.sprite = sprite1; //change sprite
StartCoroutine(FadeTo(0.0f, 2.0f));
yield return new WaitForSeconds(2f);
gameObject.SetActive(false);
}
IEnumerator FadeTo(float aValue, float aTime)
{
float alpha = sr.color.a;
for (float t = 0.0f; t < 1.0f; t += Time.deltaTime / aTime)
{
Color newColor = new Color(sr.color.r, sr.color.g, sr.color.b, Mathf.Lerp(alpha, aValue, t));
sr.color = newColor;
yield return null;
}
}
This works great, except when I get to yield return new WaitForSeconds(2f); the sprite image goes back to the one it was originally, before the animation. I have no clue why this happens. I know that sr.sprite = sprite1; works because when I take out yield return new WaitForSeconds(2f); the sprite is the correct one. Any help to fix this would be greatly appreciated.
EDIT:
Here is a gif of the problem, I'm sorry for it's terrible quality, but hopefully you can see the problem.
It is definitely not
WaitForSecondswhich changes the sprite but yourAnimator!Reason
If somewhere in any of the
AnimatorStates you have only one single keyframe for a certain property (like in your case apparently theSprite) theAnimatorgains full control over this property and you can not overwrite it via a script anymore!Further the
AnimatorStatehas an optionWrite Defaultsto which UnityTechnologies said in this threadWhat it means is that for every property that in this AnimatorState has no keyframes it uses the default value which the object would have if there was no
Animatoron it.One Solution
So if you want your
Defaultstate to not overwrite theSpritesince there is no keyframe for theSpritein that state then simply turn of this option.Pure Animator Solution
However, I think you could setup your Animator in a way it could actually handle the entire thing without you needing your script except for starting the animation once.
You say your Animator setup looks like
So allow me to ask:
Why not simply remove that transition back to
Default? This would make it stay in theunlockstate until you tell it otherwise. By having theLoop Timeturned of as you already have this means it stays at the last keyframe and wouldn't jump back to defaults anyway.Why not simply include the fading-out into your
unlockanimation itself as well? Simply set keyframes for thecolorproperty as well. This way you wouldn't need to use a script for that.Alternatively if you want to control Fading independently from the (un)lock you could use multiple Animation Layers! On the main layer you do your (un)locking. On a different layer you do the Fading via the
Colorproperty.In general I would usually suggest an Animator setup using
boolAnimation Parameters for transitions. Then using multiple layers it could lok likeIf you want to go sure set keyframes for all according properties in all of the states including the single keyframe states. Meaning e.g. in the FadingLayer you set
and the BaseLayer the same way.
This way the
Animatorcan not mess it up when force jumping between states via script.And then in code rather simply set
and then
Finally instead of the last script call you could enhance this even more setting up Animation Events that automatically invoke the
FadeOutchange when done. You could then still control it as well via script but wouldn't have to "manually" wait until the unlock animation is done before starting the fadeout.I know this is a lot of information but I hope the idea gets clear and you can make your way through the documentation ;)