protected override void OnDrawSubTrack(Rect rect, int index, bool selected, bool focused)
                    {
                        float columnWidth = rect.width / 3f;
                        Spine3DAnimatorChannelTrack track = _channelTracks.list[index] as Spine3DAnimatorChannelTrack;

                        if (track != null)
                        {
                            rect.width = columnWidth;
                            GUI.Label(rect, track._animationChannel.ToString(), EditorStyles.label);
                            rect.x += columnWidth;
                            GUI.Label(rect, track.duration.ToString(), EditorStyles.label);
                            rect.x += columnWidth;
                            GUI.Label(rect, ArrayUtils.GetCount(track.GetClips()).ToString(), EditorStyles.label);
                        }
                    }
                    protected override void AddChanelToTrack(SpineAnimatorTrack spineAnimatorTrack)
                    {
                        if (spineAnimatorTrack != null)
                        {
                            //Work out next free channel to add
                            int channel = 0;

                            foreach (Spine3DAnimatorChannelTrack track in spineAnimatorTrack.GetChildTracks())
                            {
                                if (track != null)
                                {
                                    channel = Mathf.Max(channel, track._animationChannel + 1);
                                }
                            }

                            Spine3DAnimatorChannelTrack newTrack = TimelineEditorUtils.CreateChildTrack <Spine3DAnimatorChannelTrack>(spineAnimatorTrack, "Channel " + channel);
                            newTrack._animationChannel = channel;
                        }
                    }
                protected override void PrepareChannelFrame(Playable playable)
                {
                    int numInputs = playable.GetInputCount();

                    Spine3DAnimatorTrackMixer.ChannelAnimationData        primaryAnimation     = new Spine3DAnimatorTrackMixer.ChannelAnimationData();
                    List <Spine3DAnimatorTrackMixer.ChannelAnimationData> backgroundAnimations = new List <Spine3DAnimatorTrackMixer.ChannelAnimationData>();

                    for (int i = 0; i < numInputs; i++)
                    {
                        ScriptPlayable <Spine3DAnimatorPlayableBehaviour> scriptPlayable = (ScriptPlayable <Spine3DAnimatorPlayableBehaviour>)playable.GetInput(i);
                        Spine3DAnimatorPlayableBehaviour inputBehaviour = scriptPlayable.GetBehaviour();

                        if (inputBehaviour != null && (!string.IsNullOrEmpty(inputBehaviour._animationId) || inputBehaviour._proxyAnimation != null))
                        {
                            float inputWeight = playable.GetInputWeight(i);

                            if (inputWeight > 0.0f)
                            {
                                TimelineClip clip = TimelineUtils.GetClip(_trackAsset, inputBehaviour._clipAsset);

                                if (clip != null)
                                {
                                    double clipStart    = clip.hasPreExtrapolation ? clip.extrapolatedStart : clip.start;
                                    double clipDuration = clip.hasPreExtrapolation || clip.hasPostExtrapolation ? clip.extrapolatedDuration : clip.duration;

                                    if (_director.time >= clipStart && _director.time <= clipStart + clipDuration)
                                    {
                                        bool isPrimaryClip = IsPrimaryClip(clip);

                                        //Work out track time
                                        float animationDuration = inputBehaviour._animationDuration;
                                        float trackTime         = GetExtrapolatedTrackTime(clip, _director.time, animationDuration);

                                        if (isPrimaryClip)
                                        {
                                            primaryAnimation._animationId                = inputBehaviour._animationId;
                                            primaryAnimation._animationTime              = trackTime;
                                            primaryAnimation._animationWeight            = inputWeight;
                                            primaryAnimation._animationSpeed             = inputBehaviour._animationSpeed;
                                            primaryAnimation._proxyAnimation             = inputBehaviour._proxyAnimation;
                                            primaryAnimation._proxyAnimationOrientations = inputBehaviour._proxyAnimationOrientations;
                                        }
                                        else
                                        {
                                            Spine3DAnimatorTrackMixer.ChannelAnimationData backroundAnimation = new Spine3DAnimatorTrackMixer.ChannelAnimationData
                                            {
                                                _animationId                = inputBehaviour._animationId,
                                                _animationTime              = trackTime,
                                                _animationWeight            = 1.0f,
                                                _animationSpeed             = inputBehaviour._animationSpeed,
                                                _proxyAnimation             = inputBehaviour._proxyAnimation,
                                                _proxyAnimationOrientations = inputBehaviour._proxyAnimationOrientations,
                                            };
                                            backgroundAnimations.Add(backroundAnimation);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    Spine3DAnimatorTrackMixer   parentMixer = (Spine3DAnimatorTrackMixer)_parentMixer;
                    Spine3DAnimatorChannelTrack track       = (Spine3DAnimatorChannelTrack)_trackAsset;

                    parentMixer.SetChannelData(track._animationChannel, primaryAnimation, backgroundAnimations.ToArray());
                }