Piotr
Piotr

Reputation: 11

Problem with synchornizing time and animations in Unity

My problem is that I want to play different animations basing on the time left for the user to guess. My current code doesn't work, because of the nature of the Unity Update. Not sure how to change it. Don't want to turn it into Coroutine, because I would have to change a lot of previous code. Will be extremely grateful for the help.

if(userGuessing)
{
    timerText.gameObject.SetActive(true);
    timer -= Time.deltaTime;
    timerText.text = timer.ToString("0.00");
    Debug.Log(timer);
}

if(timer > 90)
{
    bossArmature.animation.Play("BossVeryHappy", -1);
}
else if(timer > 70 && timer < 90)
{
    bossArmature.animation.Play("BossHappy", -1);
}
else if(timer > 50 && timer < 70)
{
    bossArmature.animation.Play("BossNeutral", -1);
}
else if(timer > 30 && timer < 50)
{
    bossArmature.animation.Play("BossAngry", -1);
}

Upvotes: 0

Views: 605

Answers (2)

derHugo
derHugo

Reputation: 90659

What BugFinder means was probably: Use Animator Parameters and transitions as in Tobenai's answer which I would prefer actually as it is way easier to maintain and extend. Unfortunately we don't really know if bossArmature.animation is really an Animator though it pretty much seems to be.


However, if you want to stick to your solution I would simply add an enum state

private enum BossState
{
    VeryHappy,
    Happy,
    Neutral,
    Angry
}

and have a field for storing such a value:

private BossState state;

and an according Property for automatically update the animator whenever the value is changed:

private BossState State
{
    get => state;
    set
    {
        state = value;
        switch(state)
        {
            case BossState.VeryHappy:
                bossArmature.animation.Play("BossVeryHappy", -1);
                break;
            case BossState.Happy:
                bossArmature.animation.Play("BossHappy", -1);
                break;
            case BossState.Neutral:
                bossArmature.animation.Play("BossNeutral", -1);
                break;
            case BossState.Angry:
                bossArmature.animation.Play("BossAngry", -1);
                break;
        }
    }
}

and then change your Update method to only check the according cases if you are not already in that state, otherwise you always restart the animation every frame.

if(userGuessing){
    timerText.gameObject.SetActive(true);
    timer -= Time.deltaTime;
    timerText.text = timer.ToString("0.00");
    Debug.Log(timer);
}

if(State != BossState.VeryHappy && timer > 90)
{
    State = BossState.VeryHappy;
}
else if(State != BossState.Happy && timer > 70 && timer < 90)
{
    State = BossState.Happy;
}
else if(State != BossState.Neutral && timer > 50 && timer < 70)
{
    State = BossState.Neutral;
}
else if(State != BossState.Angry && timer < 50)
{
    State = BossState.Angry;
}

Upvotes: 1

Tobenai
Tobenai

Reputation: 11

You can use animator conditions to control the behaviour based on your timer, simply set the 'Timer' parameter of the Animator to the current timer value. Then use the LessThan condition to progress through the different animations.

bossArmature.animation.SetFloat("Timer", timer);

It could then look like this

Upvotes: 1

Related Questions