Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How to Reverse Animation

Discussion in 'Scripting' started by Mashimaro7, Jul 23, 2020.

  1. Mashimaro7

    Mashimaro7

    Joined:
    Apr 10, 2020
    Posts:
    723
    How do you make an animation reverse? I read somewhere you could just reverse the speed, but I don't really know how to access the animation's speed, adjusting the animator speed doesn't seem to do anything... I have this script,
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class DoorOpen : MonoBehaviour
    6. {
    7.     List<BimbuStats> bimbi = new List<BimbuStats>();
    8.     public Animator anim;
    9.  
    10.     private void Start()
    11.     {
    12.         bimbi.Add(GameObject.FindObjectOfType<BimbuStats>());
    13.         anim = GetComponentInParent<Animator>();
    14.     }
    15.     private void Update()
    16.     {
    17.         foreach(var bimbus in bimbi)
    18.         {
    19.             if (Vector3.Distance(transform.position, bimbus.transform.position) < 10f)
    20.             {
    21.                 anim.speed = 1;
    22.             }
    23.             else
    24.             {
    25.                 anim.speed = -1;
    26.             }
    27.         }
    28.         print(bimbi.Count);
    29.     }
    30. }
    31.  
    It's basically just a door, and I want the door to open when one of the creatures gets close to it, but close when any one is far enough away. I can get it to open, and then instantly slam shut by setting a bool, but I'd like it to close gradually.

    Thanks in advance.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,713
  3. slow_izzm

    slow_izzm

    Joined:
    Feb 9, 2018
    Posts:
    9
    I feels like added work to duplicate an animation, rename it, and flip the keyframes ...

    why are we no longer able to set anim.speed = -1f anymore?

    Is there a less redundant work around via script that will reverse our animations?
     
  4. Mashimaro7

    Mashimaro7

    Joined:
    Apr 10, 2020
    Posts:
    723
    You can reverse animations, it just requires a weird work around lol, here's how I did it. I just recently used this in a project in 2020.3.1f1 so it should work. No need to create a second animation.

    Code (CSharp):
    1.         anim.SetFloat("direction", -1);
    2.         anim.Play("bubbleAnim",-1,float.NegativeInfinity);
    Just go into your animator and add a parameter called direction, and set it as your animation's multiplier, like so,
    upload_2021-3-25_15-3-18.png
     
    Last edited: Mar 25, 2021
  5. slow_izzm

    slow_izzm

    Joined:
    Feb 9, 2018
    Posts:
    9

    My project is in 2019 lts ...

    I tried this workaround and it wouldn't play the animation state from the end of the clip.

    I figured out a new workaround, just adding an animation component and populating it with my animation clips. This forces me to set clips as legacy to add them, and then disable legacy to work with the timeline, which is fine ... but I am trying to set them back to legacy from my customeditor. Sometimes this works, sometimes not ...

    Code (CSharp):
    1. animation = GetComponent<Animation>();
    2.         List<AnimationState> states = new List<AnimationState>();
    3.  
    4.         foreach (AnimationState state in animation)
    5.         {
    6.             states.Add(state);
    7.         }
    animation
    doesn't always populate my animation states. I know they need to be non legacy, which is the state they are in when I run the code above, but like I said, sometimes they are not available in
    animation
    .
     
  6. slow_izzm

    slow_izzm

    Joined:
    Feb 9, 2018
    Posts:
    9


    Since I'm just updating via custom editor, this works ...


    Code (CSharp):
    1. public void UpdateLegacy()
    2.     {
    3.         animation = this.GetComponent<Animation>();
    4.  
    5.         DirectoryInfo dir = new DirectoryInfo($"Assets/Animations/{gameObject.name}/");
    6.         FileInfo[] info = dir.GetFiles("*.anim");
    7.  
    8.         foreach (FileInfo f in info)
    9.         {
    10.             AnimationClip clip = (AnimationClip)AssetDatabase.LoadAssetAtPath($"Assets/Animations/{gameObject.name}/{f.Name}", typeof(AnimationClip));
    11.             clip.legacy = true;
    12.         }
    13.     }
     
  7. Mashimaro7

    Mashimaro7

    Joined:
    Apr 10, 2020
    Posts:
    723
    Sorry for the late response, I've never really tried adding animations to a list from an animator, but why are you running your foreach loop for the animation and not the animator? Why are you even getting a reference to your animations? Not judging if that's what you want to do, just genuinely curious lol

    Edit: also this should work just fine in 2020 and 2019. I think the issue is you're getting a reference and setting the speed of the animation directly, instead of the animator. Sorry, I just realized I never specified that my "anim" was the animator, not animation.
     
    Last edited: Mar 29, 2021
  8. slow_izzm

    slow_izzm

    Joined:
    Feb 9, 2018
    Posts:
    9
    Because I am no longer adding an Animator Component, just an Animation Component.

    I was trying to access the each animation state to enable legacy so they play at run time due to having to have legacy disabled to create the animations in the timeline. It was working at first but then began to more times than not return a null array. So, because I am just doing this all in editor I switched to just updating the legacy setting to the clips directly in the directory.

    I tried the conventional method of updating the custom parameter, but the animation would never play from the end.

    I tried ...

    Code (CSharp):
    1. anim.SetFloat("direction", -1);
    2. anim.Play("bubbleAnim",-1,float.NegativeInfinity);
    also ...

    Code (CSharp):
    1. anim.StartPlayback();
    2. anim.speed = -1;
    3. anim.Play("animation");
    the last method did nothing, although I feel like it used to, and the first method (your suggestion) I had tried and it would play the animation (viewable in the animator), but never from the end, so it looks as if it was not animating.

    Either way, the method I have implemented works great ... was a little extra work on the initial back end ... but that's all done now and the front end works all the same. Well, almost, one added step on the front end of either toggling the legacy off to be able adjust the timeline or legacy on to play the animation on run.