private void OnDestroy()
        {
            AnimationPlayerUpdater.DeregisterAnimationPlayer(this);

            if (graph.IsValid())
            {
                graph.Destroy();
            }
        }
        private void Awake()
        {
            if (hasAwoken)
            {
                return;
            }

            AnimationPlayerUpdater.RegisterAnimationPlayer(this);

            hasAwoken = true;
            EnsureVersionUpgraded();

            if (layers.Length == 0)
            {
                return;
            }
            bool anyLayersWithStates = false;

            for (int i = 0; i < layers.Length; i++)
            {
                if (layers[i].states.Count > 0)
                {
                    anyLayersWithStates = true;
                    break;
                }
            }

            if (!anyLayersWithStates)
            {
                return;
            }

            //The playable graph is a directed graph of Playables.
            graph = PlayableGraph.Create();

            // The AnimationPlayableOutput links the graph with an animator that plays the graph.
            // I think we can ditch the animator, but the documentation is kinda sparse!
            OutputAnimator = gameObject.EnsureComponent <Animator>();
            AnimationPlayableOutput animOutput = AnimationPlayableOutput.Create(graph, $"{name}_animation_player", OutputAnimator);

            for (var i = 0; i < layers.Length; i++)
            {
                layers[i].InitializeSelf(graph, defaultTransition, clipSwapCollections, blendVariableValues);
            }

            if (layers.Length <= 1)
            {
                rootPlayable = layers[0].stateMixer;
            }
            else
            {
                var layerMixer = AnimationLayerMixerPlayable.Create(graph, layers.Length);

                for (var i = 0; i < layers.Length; i++)
                {
                    layers[i].InitializeLayerBlending(graph, i, layerMixer);
                }

                rootPlayable = layerMixer;
            }

            var ikConnection = GetComponent <IIKAnimationPlayerConnection>();

            if (ikConnection != null)
            {
                var ikPlayable = ikConnection.GeneratePlayable(OutputAnimator, graph);
                ikPlayable.AddInput(rootPlayable, 0, 1f);
                animOutput.SetSourcePlayable(ikPlayable);
            }
            else
            {
                animOutput.SetSourcePlayable(rootPlayable);
            }

            //fun fact: default is DSPClock!
            graph.SetTimeUpdateMode(DirectorUpdateMode.GameTime);
            graph.Play();

            SetVizualizerName(name + " AnimationPlayer", true);
        }