- Home /
The question is answered, right answer was accepted :)
[Solved] Reverse animation help
Hello, I would like to know how I can play an animation backwards. I tried with animation.time = animation.length, or something like this, but it played the animation only once. How can I play it continuously while pressing "S" ?
Answer by Bunny83 · Jun 20, 2013 at 11:52 AM
I'm not entirely sure what exactly you want but maybe it's this ?
https://dl.dropboxusercontent.com/u/7761356/UnityAnswers/Web/PingPongAnimation/WebPlayer.html
You need to set the animations wrapmode to ClampForever or the animation will stop at the end and need to be restarted.
edit
Here's an editor script i've written to reverse an AnimationClip. Since it's an editor script you have to put it in a folder called "Editor". Once it's there a new mainmenu item called "Tools" will appear (if not just click the "File" menu once).
Now you have to duplicate the AnimationClip in Unity by pressing CTRL+D while you have selected the AnimationClip of you character. Select the duplicated Clip and click on Tools/ReverseAnimation. This will reverse the animation. Now you can add this new animation to your Animation component of your character as seperate animation by increasing the animations-array size by one and assigning the animationclip to the new slot. Keep in mind to give your AnimationClip a meaningful name ;)
//ReverseAnimation.cs
using UnityEngine;
using UnityEditor;
using System.Collections;
public class ReverseAnimation : Editor
{
public static AnimationClip GetSelectedClip()
{
var clips = Selection.GetFiltered(typeof(AnimationClip),SelectionMode.Assets);
if (clips.Length > 0)
{
return clips[0] as AnimationClip;
}
return null;
}
[MenuItem("Tools/ReverseAnimation")]
public static void Reverse()
{
var clip = GetSelectedClip();
if (clip == null)
return;
float clipLength = clip.length;
var curves = AnimationUtility.GetAllCurves(clip,true);
clip.ClearCurves();
foreach(AnimationClipCurveData curve in curves)
{
var keys = curve.curve.keys;
int keyCount = keys.Length;
var postWrapmode = curve.curve.postWrapMode;
curve.curve.postWrapMode = curve.curve.preWrapMode;
curve.curve.preWrapMode = postWrapmode;
for(int i = 0; i < keyCount; i++ )
{
Keyframe K = keys[i];
K.time = clipLength - K.time;
var tmp = -K.inTangent;
K.inTangent = -K.outTangent;
K.outTangent = tmp;
keys[i] = K;
}
curve.curve.keys = keys;
clip.SetCurve(curve.path,curve.type,curve.propertyName,curve.curve);
}
var events = AnimationUtility.GetAnimationEvents(clip);
if (events.Length > 0)
{
for (int i = 0; i < events.Length; i++)
{
events[i].time = clipLength - events[i].time;
}
AnimationUtility.SetAnimationEvents(clip,events);
}
Debug.Log("Animation reversed!");
}
}
Thanks, but it's not what I want.
I have downloaded the free Spartan model from the assets store that has a "walk" animation. I want to make an RPG game, so I need the animation to play inverted when I press "S" so it seems like the player is walking back
Well, that's something that's nearly impossible beside the fact that playing a forward character animation backwards just looks wrong. Your main problem is that Unity won't auto loop the animation when played backwards.
The best solution would be to duplicate the animation and reverse the keyframes, if you really want that...
Thanks for the code. In case anyone wants to use this to reverse animation clips on the timeline, here is something I put together real quickly. Just replace the method at the top:
public static AnimationClip GetSelectedClip() {
object selectionObject = Selection.objects[0];
// EditorClip is a protected class, but we only need the AnimationClip inside of it.
dynamic editorClip = selectionObject.GetType().GetProperty("clip").GetValue(selectionObject);
if (editorClip != null && editorClip.animationClip) {
return editorClip.animationClip;
}
return null;
}
I'm struggling with exactly that (Timeline without any way to -1 anim speed). I'm doing sprite animations tho, and they don't utilize animation curves... Any ideas?
[$$anonymous$$ETA]: Btw something is wrong with the code highlighting on UA. The indention level decreases by one each level....So the first tab is 4 spaces the second 3 the third 2 and the forth is just one space. That makes the code look really strange...
Answer by tsmitro · Jun 18, 2013 at 07:37 PM
I had a hard time figuring this out, too, since most of the documentation states to set animation.speed to -1. What I found works is to negate the animation and set the time to the end of the animation: animation.speed = -animation.speed; animation.time = animation.length
It works only when I release the button, I want to play the animation while I press "S"
#pragma strict
function Start () {
}
function Update () {
Walking();
}
function Walking () {
if(Input.Get$$anonymous$$ey($$anonymous$$eyCode.S))
{
animation["walk"].speed = -animation["walk"].speed;
animation["walk"].time = animation["walk"].length;
animation.Play("walk");
}
}
Follow this Question
Related Questions
animation to play faster over time 2 Answers
Clamp animation to a certain amount of time? 1 Answer
How to loop an animation in reverse? 0 Answers
Animation Stop and Stay 1 Answer
Play whole animation over specified time via script 1 Answer