Need your help with the PlayableGraph that is not Destroyed

Hello,

i’m trying to use Playable to manage my enemy animation, I works but when I quit the game I have a lot of this warning :

Assets/Scripts/Enemy/EnemyAnimator.cs(34): PlayableGraph was not destroyed.

The idea is to have 4 animation clips for four different directions of a walking cycle.
Being able to switch the animation clip depending on the direction of the enemy on update.
Also being able to pause all the animations when the game is paused and resume them when returning to the game.

I have a MonoBehavior to manage this, the code is pretty simple.
I wanted to know I make a good usage of the Playables (certainly not) and how I can achieve this whithout the need of manually defining an animator for each of my different enemies. Thanks !

public class EnemyAnimator : MonoBehaviour
{
    private Animator m_animator;
    private Enemy m_enemy;
    private PlayableGraph m_playableGraph;
    private int m_direction = -1;
    private AnimationClip[] m_animations;

    public AnimationClip east;
    public AnimationClip west;
    public AnimationClip north;
    public AnimationClip south;

    private void Awake()
    {
        m_animations = new AnimationClip[4] { east, north, west, south };
       
        m_animator = GetComponent<Animator>();
        m_enemy = GetComponent<Enemy>();
    }
   
    private void Update()
    {
        if (m_direction != m_enemy.Direction)
        {
            m_direction = m_enemy.Direction;
           
            if (m_direction != -1)
            {
                AnimationPlayableUtilities.PlayClip(m_animator, m_animations[m_enemy.Direction], out m_playableGraph);
            }
        }

        if (!GameManager.Instance.game.playing)
        {
            m_playableGraph.GetRootPlayable(0).Pause();
        }
        else
        {
            m_playableGraph.GetRootPlayable(0).Play();
        }
    }

    private void OnApplicationQuit()
    {
        m_playableGraph.Destroy();
    }

    private void OnDestroy()
    {
        m_playableGraph.Destroy();
    }
}

Any idea ?

In case you didn’t figure it out, AnimationPlayableUtilities.PlayClip creates a new PlayableGraph every time but you are only destroying the last one that was created when your script is destroyed.

1 Like

Thanks for your answer @Kybernetik
How would you code this feature, I’m really not sure how to do this well.
Thanks for your help !

Putting:

if (m_playableGraph.IsValid())
    m_playableGraph.Destroy();

Before you call PlayClip would make sure you always clean up the old graph first, but that’s still pretty inefficient because there is no need to create and destroy graphs all the time.

Check out Animancer (link in my signature). It lets you easily play whatever AnimationClips you want on demand without needing to directly mess around with the Playables API. The Directional Sprites examples demonstrate pretty much exactly what you are trying to do and if you are only working with simple Sprite animations then you probably only need the features of the Free version.

Thanks @Kybernetik your plugin looks really awesome !
I think I’ll buy it if I do more complex things in animation, sounds like very helpful, optimized and robust.

I’ve put it in my favorites, and I’ll definitely will check out your other plugins !

In the meantime I did something else with AnimatorOverrideController that fits my basic needs …
With this I just replace clips at runtime for the different enemies for the four directions.

Thanks again for your answer!

PS : I love the “Praise the Sun” mention in your signature, big fan too :wink: