- Home /
Toggling between states of animation
I have an object that is supposed to toggle between glowing or not glowing on anyKeyDown. To toggle between my states (large/small halo size and light/dark emission colour) I have an animator using variables from a script, with 3 animations: glow (gradually increase the halo size and emission colour) pale (the opposite), and idle (some passive idle movement). The transitions between the states are like this:
and my script is as follows
public class glowControl : MonoBehaviour {
MeshRenderer MR;
Animator A;
public bool transitionPlay = false;
public bool glowing = false;
public Color notGlowingColour;
public Color glowingColour;
public float colourScale;
void Start () {
A = this.GetComponent<Animator> ();
MR = this.GetComponent<MeshRenderer> ();
}
void Update () {
if (Input.anyKeyDown) {
glowing = !glowing;
transitionPlay = true;
}
A.SetBool ("Transition Play", transitionPlay);
A.SetBool ("Glowing", glowing);
MR.material.SetColor ("_EmissionColor", Color.Lerp(notGlowingColour, glowingColour, colourScale)); //Set the colour of emission
}
}
So what I've tried to do is at the end of the pale and glow animations is to set transitionPlay to false, and set the condition for either of them to return to idle as that transitionPlay must be false (so that once the animation is complete, the object returns to idling). The condition to change from idle to either glow or pale is that transitionPlay must be true (which happens on anyKeyDown in the script) and that glowing is either true or false respectively (which gets toggled every anyKeyDown).
So I thought that this should work fine, but what actually happens when I play is that the object starts halfway between glowing and not glowing (halo size and colourScale half of what they should be when glowing) and on anyKeyDown, the objects flickers (looping the glow and pale animations of the object transitioning) for a bit and then returns to be halfway between the states.
If anyone has any idea what I'm doing wrong then please bless me with your knowledge.
Answer by Blue-Cut · Jan 21, 2017 at 06:15 PM
Hello,
I reformulate what I understand :
Game start, object is idle
I press a key
The object "Glow" once (it's not a looping animation) then back to idle
I press a key
The object "Pale" once (it's not a looping animation) then back to idle
Tell me if something is wrong and I'll correct the answer.
Maybe the way you deal with 2 booleans is too complex.
Your Animator component has a property "Has Exit Time". If true, you want to leave the state when the animation is over, so don't check it for Idle and check it for Glow and Pale.
I would do something like this :
public class GlowNotGlow : MonoBehaviour
{
// use a int to switch between -1 and 1 : it replaces the bool glowing you had
private int glowstate = 1;
void Update () {
if (Input.anyKeyDown)
{
// switch the state for the next anim
glowstate = glowstate*(-1);
// And set this state in the only parameter of your animator (a int parameter)
A.SetInteger("GlowState", glowstate);
}
// This line was good for me
MR.material.SetColor ("_EmissionColor", Color.Lerp(notGlowingColour, glowingColour, colourScale));
}
public void EndAnim()
{
// when the anim is over, reset to 0 the parameter, that corresponds to the idle state
A.SetInteger("GlowState", 0);
}
}
In the code I suggest, I didn't write the declaration of all variables that were already in your script. The function EndAnim is the function that is supposed to be called when one of your Glow/Pale animation is over.
You simplify a bit the way to deal with the animator by replacing your 2 bool by a single int that allow you to directly represent your 3 cases in 1 variable.
This solution works fine in my test (still in the way I understand your problem)
First, your understanding of what I'm trying to do is perfectly correct.
Second, it's almost working, but for some reason what happens is that even once EndAnim has been triggered, Glow/Pale plays again (GlowState is at 0 while this happens) but after that goes back to Idle and halfway between glowing and not glowing. As far as I can tell this has something to do with Unity trying to smoothly transition between Glow/Pale and Idle.
Ah, I am able to reproduce your bug ^^
Actually my code is not "exactly" as I put it in my answer. I did something faster with a "animStarted" bool used in the update function. Like this :
void Update()
{
if (animStarted)
{
animStarted = false;
A.SetInteger("GlowState", 0);
}
if (Input.any$$anonymous$$eyDown)
{
animStarted = true;
// rest of the code
}
}
But I was sure the animation event would give the same result. So I tried the method with the animation event and I have the same bug as you.
If you use Debug.Log("some text")
in the EndAnim() function, you can see that the function is not called at the end of the glow animation. But for now, I can't figure out what the problem is.
Anyway, the method with animStarted
works, but the method with the animation was cleaner... :/