Reputation: 2244
Context
I got two transform states on a GameObject, A
and B
. I also have two animations that transition between the two states: A->B
and B->A
. The animations have different animation curves. The user can change the state of the GameObject at any moment.
What I want to achieve
If the state is changed while no animations are playing, the animations A->B
and B->A
are played normally. However, if the state is changed while an animation is playing, I want the current animation to reverse. For example, let's say that the user changes the state to B, and the animation A->B
starts playing. Then the user suddenly changes back to state A before the animation A->B
has finished. Here I want the A->B
animation to start reversing to state A again, not playing the animation B->A
.
What I currently have
I have tried to use Unity's Animator but have found no function to reverse an ongoing animation. I am open to using something else than the Animator but prefer not to use any external libraries.
Here is the current code I have with no reverse logic, only changing between state A
and B
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestAnimation : MonoBehaviour
{
private Animator _animator;
private bool _isOpen = true;
void Awake()
{
this._animator = GetComponent<Animator>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
if (this._isOpen)
this._animator.SetTrigger("A");
else
this._animator.SetTrigger("B");
this._isOpen = !this._isOpen;
}
}
}
Upvotes: 0
Views: 1080
Reputation: 2244
Found a solution now. Do not know if it is the most simple one but it works. What I did was to activate the animation by playing them via script, not using any triggers or floats in the animator as I tried first.
I also created two new animation states that are the reversed version of A->B
and B->A
. I looked at the normelizedTime
variable in the animator to determine if any animation was currently playing. If so, I played the reversed animation at where it ended, see the code below.
Here is the animator with the different animation states:
And here is the code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestAnimation : MonoBehaviour
{
private Animator _animator;
private bool _toggle = true;
private bool _isPlayingReverse = true;
void Awake()
{
this._animator = GetComponent<Animator>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
var animationTime = Mathf.Clamp(this._animator.GetCurrentAnimatorStateInfo(0).normalizedTime, 0.0f, 1.0f);
bool animationOngoing = animationTime < 1;
if (this._toggle)
{
if (animationOngoing && !this._isPlayingReverse)
{
this._animator.Play("A->B - Reversed", 0, 1 - animationTime);
this._isPlayingReverse = true;
}
else
{
this._animator.Play("B->A", 0, 1 - animationTime);
this._isPlayingReverse = false;
}
}
else
{
if (animationOngoing && !this._isPlayingReverse)
{
this._animator.Play("B->A - Reversed", 0, 1 - animationTime);
this._isPlayingReverse = true;
}
else
{
this._animator.Play("A->B", 0, 1 - animationTime);
this._isPlayingReverse = false;
}
}
this._toggle = !this._toggle;
}
}
}
Upvotes: 0