AudioSource GetAudioSource()
        {
            var source = ObjectUtil.GetFirst <AudioSource>(this);

            if (source == null)
            {
                source = new GameObject(gameObject.name + "_Audio").AddComponent <AudioSource>();
                source.transform.parent = transform;
                source.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
            }
            return(source);
        }
        public Task Initialize(PlayerConfig config, bool isView = false)
        {
            var animator = ObjectUtil.GetFirst <Animator>(this);

            if (animator == null)
            {
                return(Task.CompletedTask);
            }
            //OptimizeHierarchy();

            _playableGraph = PlayableGraph.Create(name);
            _playableGraph.SetTimeUpdateMode(DirectorUpdateMode.Manual);

            var controller = new ControllerInfo {
                Graph = _playableGraph,
                Owner = gameObject,
            };

            _stateMap = new Dictionary <uint, StateInfo>();
            // TODO(james7132): Set up proper state blending
            foreach (var state in StateMachine.StateController.States)
            {
                _stateMap[state.Id] = new StateInfo(state, controller);
                _stateMap[state.Id].Disconnect();
            }
            _states = _stateMap.Values.ToArray();

            controller.Animation = CreateAnimationBinding(_playableGraph, animator);
            controller.Audio     = CreateAudioBinding(_playableGraph, GetAudioSource());

            if (!isView)
            {
                animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
            }

            Assert.IsTrue(_playableGraph.IsValid());

            return(Task.CompletedTask);
        }