- Home /
Incomplete reverse animation
I have a cube with a quite simple set of animations. Each animation have 10 frames and go from one face to another. I have 6 animations in total and each one begins in face, rotates and ends with the next face like this: Face1 - 8 frames of rotation - Face2; Face2 - 8 frames of rotation - Face3 and so on. With this code forward animation, triggered by the J key, works just fine but reverse animation, triggered with the K key, doesn't reverse all the way to the first frame, the frame with the starting position with no rotations.
3D modeling is done with Blender.
void Update() {
if (!animating) {
if (Input.GetKeyDown(KeyCode.J)) {
i++;
if (i > 5)
i = 0;
animation [animationsArray [i]].speed = 3.0f;
animation [animationsArray [i]].time = 0;
animation.Play(animationsArray [i]);
animating = true;
}
if (Input.GetKeyDown(KeyCode.K)) {
animation [animationsArray [i]].speed = -3.0f;
animation [animationsArray [i]].time = animation [animationsArray [i]].length;
animation.Play(animationsArray [i]);
animating = true;
i--;
if (i < 0)
i = 5;
}
} else {
animation [animationsArray [i]].normalizedTime = Mathf.Clamp01(animation [animationsArray [i]].normalizedTime);
if (!animation.isPlaying)
animating = false;
}
}<code>
Answer by Bunny83 · Aug 05, 2012 at 11:06 PM
The problem is that you probably use the wrapmode "once", so when the animation reaches the "end" it automatically stops. At the bottom of your code you check if the animation has stopped and you prepare for the next one. However, if you run the animation backwards it doesn't stop when it reaches the "start".
You could use the speed variable to determine in which direction you're animating and check the normalized time if it reaches the corresponding "end" / "start"
edit:
I've finally tested it myself. I created some animations in Unity, and attached the script. This is my final modified version ;)
// C#
public class AnimationControl : MonoBehaviour
{
public string[] animationsArray;
public float speed = 3;
AnimationState currentAnim = null;
int i = 0;
void Start ()
{
foreach (string AName in animationsArray)
animation[AName].wrapMode = WrapMode.ClampForever;
}
void Update()
{
if (currentAnim == null)
{
if (Input.GetKeyDown(KeyCode.J))
{
i++;
if (i > animationsArray.Length-1)
i = 0;
currentAnim = animation [animationsArray [i]];
animation.Play(currentAnim.name);
currentAnim.speed = speed;
currentAnim.normalizedTime = 0.0f;
}
if (Input.GetKeyDown(KeyCode.K))
{
currentAnim = animation [animationsArray [i]];
animation.Play(currentAnim.name);
currentAnim.speed = -speed;
currentAnim.normalizedTime = 1.0f;
i--;
if (i < 0)
i = animationsArray.Length-1;
}
}
else
{
if (currentAnim.speed > 0)
{
if (currentAnim.normalizedTime >= 1.0f)
currentAnim = null;
}
else
{
if (currentAnim.normalizedTime <= 0.0f)
currentAnim = null;
}
if (currentAnim == null)
animation.Stop();
}
}
}
Thank you for your reply. I still have incomplete reverse animation using your code. For the forward animation, I had to change
if (currentAnim.normalizedTime >= 1.0f)
for
if (currentAnim.normalizedTime >= 0.85f)
because the first time the forward animation plays the variable currentAnim.normalizedTime will try to go up to 1 but stops in 0.97 or some near value and then changes to 0. This makes an infinite loop because normalizedTime will never be 1.
By the way, using AnimationState make the animation code clearer. Will use that for now on =D.
You might try ClampForever.
It acts just like PlayOnce, except when it hits time 1 it just keeps moving to 2, 3 ... with the animation clamped at the time=1 position. You can safely check for time past 1.
Likewise it will gladly freeze position at 0, while time becomes negative.
Doing a
animation.wrap$$anonymous$$ode = Wrap$$anonymous$$ode.ClampForever;
at Start() certainly helped to the above if sentence and the value 1.0f. Thanks. Now, how the reverse animation doesn't go to the first frame if I can clearly see the normalizedTime moving from 1 to 0?
Disclaimer: I don't understand the setup -- five animations play forwards or backwards in sequence? But, I'm thinking the problem is you have two playing at a time. With PlayOnce, they auto-stop just as you start the next, so that never happens. I wonder if now the clamped but still active forwards animation is "covering up" the backwards one.
I'm thinking right when you set animating=false;
you'd also, if using clamped, have to stop the current animation.
I just need one animation playing everytime I press the J o $$anonymous$$ key. If the cube is showing the face A when I press J the cube will now show the face B. In this moment, if a press $$anonymous$$ the cube now shows face B. The animation can be the cube rotating 90 degrees on the X axis.
Added
animation.Stop(currentAnim.name)
when animating
is set to false and the reverse animation keeps stopping before the last frame.
Your answer

Follow this Question
Related Questions
FBX import from blender rotation slightly off 2 Answers
Blender Scaling Import Problem. 1 Answer
Character won't play animation 8 Answers
Blender Animation ? 0 Answers
creating a disolvable ik rig in blender for unity3D mecanim 0 Answers