Esempio n. 1
0
        internal Playable CreatePlayableGraph(PlayableGraph graph, GameObject go, IntervalTree <RuntimeElement> tree, Playable timelinePlayable)
        {
            UpdateDuration();
            var mixerPlayable = Playable.Null;

            if (CanCompileClipsRecursive())
            {
                mixerPlayable = OnCreateClipPlayableGraph(graph, go, tree);
            }

            var notificationsPlayable = CreateNotificationsPlayable(graph, mixerPlayable, go, timelinePlayable);

            // clear the temporary build data to avoid holding references
            // case 1253974
            s_BuildData.Clear();
            if (!notificationsPlayable.IsValid() && !mixerPlayable.IsValid())
            {
                Debug.LogErrorFormat("Track {0} of type {1} has no notifications and returns an invalid mixer Playable", name,
                                     GetType().FullName);

                return(Playable.Create(graph));
            }

            return(notificationsPlayable.IsValid() ? notificationsPlayable : mixerPlayable);
        }
Esempio n. 2
0
        Playable CreateInfiniteTrackPlayable(PlayableGraph graph, GameObject go, IntervalTree <RuntimeElement> tree, AppliedOffsetMode mode)
        {
            if (m_InfiniteClip == null)
            {
                return(Playable.Null);
            }

            var mixer = AnimationMixerPlayable.Create(graph, 1);

            // In infinite mode, we always force the loop mode of the clip off because the clip keys are offset in infinite mode
            //  which causes loop to behave different.
            // The inline curve editor never shows loops in infinite mode.
            var playable = AnimationPlayableAsset.CreatePlayable(graph, m_InfiniteClip, m_InfiniteClipOffsetPosition, m_InfiniteClipOffsetEulerAngles, false, mode, infiniteClipApplyFootIK, AnimationPlayableAsset.LoopMode.Off);

            if (playable.IsValid())
            {
                tree.Add(new InfiniteRuntimeClip(playable));
                graph.Connect(playable, 0, mixer, 0);
                mixer.SetInputWeight(0, 1.0f);
            }

            if (!AnimatesRootTransform())
            {
                return(mixer);
            }

            var rootTrack = isSubTrack ? (AnimationTrack)parent : this;

            return(rootTrack.ApplyTrackOffset(graph, mixer, go, mode));
        }
Esempio n. 3
0
        internal Playable CreatePlayableGraph(PlayableGraph graph, GameObject go, IntervalTree <RuntimeElement> tree, Playable timelinePlayable)
        {
            var mixerPlayable = Playable.Null;

            if (CanCompileClipsRecursive())
            {
                UpdateDuration();
                mixerPlayable = OnCreateClipPlayableGraph(graph, go, tree);
            }

            var notificationsPlayable = CreateNotificationsPlayable(graph, mixerPlayable, go, timelinePlayable);

            if (!notificationsPlayable.IsValid() && !mixerPlayable.IsValid())
            {
                Debug.LogErrorFormat("Track {0} of type {1} has no notifications and returns an invalid mixer Playable", name,
                                     GetType().FullName);

                return(Playable.Create(graph));
            }

            var playableGraph = CanCompileNotifications() ? notificationsPlayable : mixerPlayable;

            ConfigureTrackAnimation(tree, go, playableGraph);

            return(playableGraph);
        }
Esempio n. 4
0
        internal void ConfigureTrackAnimation(IntervalTree<RuntimeElement> tree, GameObject go, Playable blend)
        {
            if (!hasCurves)
                return;

            blend.SetAnimatedProperties(m_Curves);
            tree.Add(new InfiniteRuntimeClip(blend));

            if (OnTrackAnimationPlayableCreate != null)
                OnTrackAnimationPlayableCreate.Invoke(this, go, blend);
        }
        Playable CreateInfiniteTrackPlayable(PlayableGraph graph, GameObject go, IntervalTree <RuntimeElement> tree, AppliedOffsetMode mode)
        {
            if (m_InfiniteClip == null)
            {
                return(Playable.Null);
            }

            var mixer    = AnimationMixerPlayable.Create(graph, 1);
            var playable = AnimationPlayableAsset.CreatePlayable(graph, m_InfiniteClip, m_InfiniteClipOffsetPosition, m_InfiniteClipOffsetEulerAngles, false, mode, infiniteClipApplyFootIK);

            if (playable.IsValid())
            {
                tree.Add(new InfiniteRuntimeClip(playable));
                graph.Connect(playable, 0, mixer, 0);
                mixer.SetInputWeight(0, 1.0f);
            }

            return(ApplyTrackOffset(graph, mixer, go, mode));
        }
Esempio n. 6
0
        void InitializeClips(PlayableGraph graph, GameObject go, IntervalTree <RuntimeElement> tree, AudioMixerPlayable clipBlender)
        {
            for (int i = 0; i < clips.Length; i++)
            {
                var c     = clips[i];
                var asset = c.asset as PlayableAsset;
                if (asset == null)
                {
                    continue;
                }

                var buffer     = 0.1f;
                var audioAsset = c.asset as AudioPlayableAsset;
                if (audioAsset != null)
                {
                    buffer = audioAsset.bufferingTime;
                }

                var source = asset.CreatePlayable(graph, go);
                if (!source.IsValid())
                {
                    continue;
                }

                if (source.IsPlayableOfType <AudioClipPlayable>())
                {
                    // Enforce initial values on all clips
                    var audioClipPlayable   = (AudioClipPlayable)source;
                    var audioClipProperties = audioClipPlayable.GetHandle().GetObject <AudioClipProperties>();

                    audioClipPlayable.SetVolume(Mathf.Clamp01(m_TrackProperties.volume * audioClipProperties.volume));
                    audioClipPlayable.SetStereoPan(Mathf.Clamp(m_TrackProperties.stereoPan, -1.0f, 1.0f));
                    audioClipPlayable.SetSpatialBlend(Mathf.Clamp01(m_TrackProperties.spatialBlend));
                }

                tree.Add(new ScheduleRuntimeClip(c, source, clipBlender, buffer));
                graph.Connect(source, 0, clipBlender, i);
                source.SetSpeed(c.timeScale);
                source.SetDuration(c.extrapolatedDuration);
                clipBlender.SetInputWeight(source, 1.0f);
            }
        }
Esempio n. 7
0
 public IntervalTreeRebalancer(IntervalTree <RuntimeElement> tree)
 {
     m_Tree = tree;
 }
 private static Playable CreatePlayableGraph(PlayableGraph graph, TrackAsset asset, GameObject go, IntervalTree <RuntimeElement> tree, Playable timelinePlayable)
 {
     return(asset.CreatePlayableGraph(graph, go, tree, timelinePlayable));
 }
Esempio n. 9
0
        internal virtual Playable OnCreateClipPlayableGraph(PlayableGraph graph, GameObject go, IntervalTree <RuntimeElement> tree)
        {
            if (tree == null)
            {
                throw new ArgumentException("IntervalTree argument cannot be null", "tree");
            }

            if (go == null)
            {
                throw new ArgumentException("GameObject argument cannot be null", "go");
            }

            s_BuildData.Clear();
            GatherCompilableTracks(s_BuildData.trackList);

            // nothing to compile
            if (s_BuildData.trackList.Count == 0)
            {
                return(Playable.Null);
            }

            // check if layers are supported
            Playable   layerMixer = Playable.Null;
            ILayerable layerable  = this as ILayerable;

            if (layerable != null)
            {
                layerMixer = layerable.CreateLayerMixer(graph, go, s_BuildData.trackList.Count);
            }

            if (layerMixer.IsValid())
            {
                for (int i = 0; i < s_BuildData.trackList.Count; i++)
                {
                    var mixer = s_BuildData.trackList[i].CompileClips(graph, go, s_BuildData.trackList[i].clips, tree);
                    if (mixer.IsValid())
                    {
                        graph.Connect(mixer, 0, layerMixer, i);
                        layerMixer.SetInputWeight(i, 1.0f);
                    }
                }
                return(layerMixer);
            }

            // one track compiles. Add track mixer and clips
            if (s_BuildData.trackList.Count == 1)
            {
                return(s_BuildData.trackList[0].CompileClips(graph, go, s_BuildData.trackList[0].clips, tree));
            }

            // no layer mixer provided. merge down all clips.
            for (int i = 0; i < s_BuildData.trackList.Count; i++)
            {
                s_BuildData.clipList.AddRange(s_BuildData.trackList[i].clips);
            }

#if UNITY_EDITOR
            bool applyWarning = false;
            for (int i = 0; i < s_BuildData.trackList.Count; i++)
            {
                applyWarning |= i > 0 && s_BuildData.trackList[i].hasCurves;
            }

            if (applyWarning)
            {
                Debug.LogWarning("A layered track contains animated fields, but no layer mixer has been provided. Animated fields on layers will be ignored. Override CreateLayerMixer in " + s_BuildData.trackList[0].GetType().Name + " and return a valid playable to support animated fields on layered tracks.");
            }
#endif
            // compile all the clips into a single mixer
            return(CompileClips(graph, go, s_BuildData.clipList, tree));
        }
Esempio n. 10
0
        internal virtual Playable CompileClips(PlayableGraph graph, GameObject go, IList <TimelineClip> timelineClips, IntervalTree <RuntimeElement> tree)
        {
            var blend = CreateTrackMixer(graph, go, timelineClips.Count);

            for (var c = 0; c < timelineClips.Count; c++)
            {
                var source = CreatePlayable(graph, go, timelineClips[c]);
                if (source.IsValid())
                {
                    source.SetDuration(timelineClips[c].duration);
                    var clip = new RuntimeClip(timelineClips[c], source, blend);
                    tree.Add(clip);
                    graph.Connect(source, 0, blend, c);
                    blend.SetInputWeight(c, 0.0f);
                }
            }
            ConfigureTrackAnimation(tree, go, blend);
            return(blend);
        }
        internal override Playable OnCreatePlayableGraph(PlayableGraph graph, GameObject go, IntervalTree <RuntimeElement> tree)
        {
            if (base.isSubTrack)
            {
                throw new InvalidOperationException("Nested animation tracks should never be asked to create a graph directly");
            }
            List <AnimationTrack> list = new List <AnimationTrack>();

            if (this.compilableIsolated)
            {
                list.Add(this);
            }
            foreach (TrackAsset trackAsset in base.GetChildTracks())
            {
                AnimationTrack animationTrack = trackAsset as AnimationTrack;
                if (animationTrack != null && animationTrack.compilable)
                {
                    list.Add(animationTrack);
                }
            }
            AnimationMotionXToDeltaPlayable animationMotionXToDeltaPlayable = AnimationMotionXToDeltaPlayable.Create(graph);
            AnimationLayerMixerPlayable     animationLayerMixerPlayable     = AnimationTrack.CreateGroupMixer(graph, go, list.Count);

            graph.Connect <AnimationLayerMixerPlayable, AnimationMotionXToDeltaPlayable>(animationLayerMixerPlayable, 0, animationMotionXToDeltaPlayable, 0);
            animationMotionXToDeltaPlayable.SetInputWeight(0, 1f);
            for (int i = 0; i < list.Count; i++)
            {
                Playable source = (!list[i].inClipMode) ? list[i].CreateInfiniteTrackPlayable(graph, go, tree) : this.CompileTrackPlayable(graph, list[i], go, tree);
                graph.Connect <Playable, AnimationLayerMixerPlayable>(source, 0, animationLayerMixerPlayable, i);
                animationLayerMixerPlayable.SetInputWeight(i, (float)((!list[i].inClipMode) ? 1 : 0));
                if (list[i].applyAvatarMask && list[i].avatarMask != null)
                {
                    animationLayerMixerPlayable.SetLayerMaskFromAvatarMask((uint)i, list[i].avatarMask);
                }
            }
            return(animationMotionXToDeltaPlayable);
        }
Esempio n. 12
0
        Playable CompileTrackPlayable(PlayableGraph graph, TrackAsset track, GameObject go, IntervalTree <RuntimeElement> tree, AppliedOffsetMode mode)
        {
            var mixer = AnimationMixerPlayable.Create(graph, track.clips.Length);

            for (int i = 0; i < track.clips.Length; i++)
            {
                var c     = track.clips[i];
                var asset = c.asset as PlayableAsset;
                if (asset == null)
                {
                    continue;
                }

                var animationAsset = asset as AnimationPlayableAsset;
                if (animationAsset != null)
                {
                    animationAsset.appliedOffsetMode = mode;
                }

                var source = asset.CreatePlayable(graph, go);
                if (source.IsValid())
                {
                    var clip = new RuntimeClip(c, source, mixer);
                    tree.Add(clip);
                    graph.Connect(source, 0, mixer, i);
                    mixer.SetInputWeight(i, 0.0f);
                }
            }

            return(ApplyTrackOffset(graph, mixer, go, mode));
        }
Esempio n. 13
0
        internal override Playable OnCreateClipPlayableGraph(PlayableGraph graph, GameObject go, IntervalTree <RuntimeElement> tree)
        {
            if (isSubTrack)
            {
                throw new InvalidOperationException("Nested animation tracks should never be asked to create a graph directly");
            }

            List <AnimationTrack> flattenTracks = new List <AnimationTrack>();

            if (CanCompileClips())
            {
                flattenTracks.Add(this);
            }


            bool animatesRootTransform = AnimatesRootTransform();

            foreach (var subTrack in GetChildTracks())
            {
                var child = subTrack as AnimationTrack;
                if (child != null && child.CanCompileClips())
                {
                    animatesRootTransform |= child.AnimatesRootTransform();
                    flattenTracks.Add(child);
                }
            }

            // figure out which mode to apply
            AppliedOffsetMode mode = GetOffsetMode(go, animatesRootTransform);
            var layerMixer         = CreateGroupMixer(graph, go, flattenTracks.Count);

            for (int c = 0; c < flattenTracks.Count; c++)
            {
                var compiledTrackPlayable = flattenTracks[c].inClipMode ?
                                            CompileTrackPlayable(graph, flattenTracks[c], go, tree, mode) :
                                            flattenTracks[c].CreateInfiniteTrackPlayable(graph, go, tree, mode);
                graph.Connect(compiledTrackPlayable, 0, layerMixer, c);
                layerMixer.SetInputWeight(c, flattenTracks[c].inClipMode ? 0 : 1);
                if (flattenTracks[c].applyAvatarMask && flattenTracks[c].avatarMask != null)
                {
                    layerMixer.SetLayerMaskFromAvatarMask((uint)c, flattenTracks[c].avatarMask);
                }
            }

            Playable mixer = (Playable)layerMixer;

#if UNITY_EDITOR
            if (!Application.isPlaying)
            {
                var motionXMixer = AnimationMixerPlayable.Create(graph, 2);

                var      animator     = GetBinding(go != null ? go.GetComponent <PlayableDirector>() : null);
                Playable blendDefault = Playable.Null;
                if (animator != null && animator.isHuman)
                {
                    blendDefault = AnimationClipPlayable.Create(graph, GetDefaultHumanoidClip());
                }
                else
                {
                    blendDefault = AnimationPosePlayable.Create(graph);
                    ((AnimationPosePlayable)blendDefault).SetReadDefaultPose(true);
                }

                var offsetPlayable = AnimationOffsetPlayable.Create(graph, m_SceneOffsetPosition, Quaternion.Euler(m_SceneOffsetRotation), 1);

                graph.Connect(blendDefault, 0, offsetPlayable, 0);
                graph.Connect(layerMixer, 0, motionXMixer, 0);
                graph.Connect(offsetPlayable, 0, motionXMixer, 1);

                offsetPlayable.SetInputWeight(0, 1.0f);
                motionXMixer.SetInputWeight(1, 1.0f);
                motionXMixer.SetInputWeight(0, 0.0f);

                mixer = (Playable)motionXMixer;
            }
#endif

            // motionX playable not required in scene offset mode, or root transform mode
            if (!RequiresMotionXPlayable(mode, go))
            {
                return(mixer);
            }

            // If we are animating a root transform, add the motionX to delta playable as the root node
            var motionXToDelta = AnimationMotionXToDeltaPlayable.Create(graph);
            graph.Connect(mixer, 0, motionXToDelta, 0);
            motionXToDelta.SetInputWeight(0, 1.0f);
            motionXToDelta.SetAbsoluteMotion(UsesAbsoluteMotion(mode));
            return(motionXToDelta);
        }
 public IntervalTreeRebalancer(IntervalTree <RuntimeElement> tree)
 {
     this.m_Tree = tree;
     this.m_Hash = this.m_Tree.GetHash();
 }
Esempio n. 15
0
        internal override Playable OnCreateClipPlayableGraph(PlayableGraph graph, GameObject go, IntervalTree <RuntimeElement> tree)
        {
            var clipBlender = AudioMixerPlayable.Create(graph, clips.Length);

            // In the player, we do not add the AudioMixerProperties behaviour to the track if it contains no animation
            // however in the editor we want to always have it present to be able to preview changes live.
#if UNITY_EDITOR
            clipBlender.GetHandle().SetScriptInstance(m_TrackProperties.Clone());
            m_LiveMixerPlayable = clipBlender;
#else
            if (hasCurves)
            {
                clipBlender.GetHandle().SetScriptInstance(m_TrackProperties.Clone());
            }
#endif

            InitializeClips(graph, go, tree, clipBlender);

            return(clipBlender);
        }
Esempio n. 16
0
        internal virtual Playable OnCreatePlayableGraph(PlayableGraph graph, GameObject go, IntervalTree <RuntimeElement> tree)
        {
            if (tree == null)
            {
                throw new ArgumentException("IntervalTree argument cannot be null", "tree");
            }
            if (go == null)
            {
                throw new ArgumentException("GameObject argument cannot be null", "go");
            }
            Playable playable = this.CreateTrackMixer(graph, go, this.clips.Length);

            for (int i = 0; i < this.clips.Length; i++)
            {
                Playable playable2 = this.CreatePlayable(graph, go, this.clips[i]);
                if (playable2.IsValid <Playable>())
                {
                    playable2.SetDuration(this.clips[i].duration);
                    RuntimeClip item = new RuntimeClip(this.clips[i], playable2, playable);
                    tree.Add(item);
                    graph.Connect <Playable, Playable>(playable2, 0, playable, i);
                    playable.SetInputWeight(i, 0f);
                }
            }
            return(playable);
        }
Esempio n. 17
0
 internal Playable CreatePlayableGraph(PlayableGraph graph, GameObject go, IntervalTree <RuntimeElement> tree)
 {
     this.UpdateDuration();
     return(this.OnCreatePlayableGraph(graph, go, tree));
 }
        private Playable CreateInfiniteTrackPlayable(PlayableGraph graph, GameObject go, IntervalTree <RuntimeElement> tree)
        {
            Playable result;

            if (base.animClip == null)
            {
                result = Playable.Null;
            }
            else
            {
                if (this.m_FakeAnimClip == null || this.m_AnimationPlayableAsset == null)
                {
                    this.m_AnimationPlayableAsset = ScriptableObject.CreateInstance <AnimationPlayableAsset>();
                    this.m_FakeAnimClip           = new TimelineClip(null)
                    {
                        asset                 = this.m_AnimationPlayableAsset,
                        displayName           = "Animation Clip",
                        timeScale             = 1.0,
                        start                 = 0.0,
                        postExtrapolationMode = TimelineClip.ClipExtrapolation.Hold,
                        preExtrapolationMode  = TimelineClip.ClipExtrapolation.Hold
                    };
                    this.m_FakeAnimClip.SetPostExtrapolationTime(TimelineClip.kMaxTimeValue);
                }
                this.m_AnimationPlayableAsset.clip              = base.animClip;
                this.m_AnimationPlayableAsset.position          = this.m_OpenClipOffsetPosition;
                this.m_AnimationPlayableAsset.rotation          = this.m_OpenClipOffsetRotation;
                this.m_AnimationPlayableAsset.removeStartOffset = false;
                this.m_FakeAnimClip.start = 0.0;
                this.m_FakeAnimClip.SetPreExtrapolationTime(0.0);
                this.m_FakeAnimClip.duration = (double)base.animClip.length;
                AnimationMixerPlayable animationMixerPlayable = AnimationMixerPlayable.Create(graph, 1, false);
                Playable playable = this.m_AnimationPlayableAsset.CreatePlayable(graph, go);
                if (playable.IsValid <Playable>())
                {
                    tree.Add(new RuntimeClip(this.m_FakeAnimClip, playable, animationMixerPlayable));
                    graph.Connect <Playable, AnimationMixerPlayable>(playable, 0, animationMixerPlayable, 0);
                    animationMixerPlayable.SetInputWeight(0, 1f);
                }
                result = this.ApplyTrackOffset(graph, animationMixerPlayable);
            }
            return(result);
        }
Esempio n. 19
0
        internal override Playable OnCreateClipPlayableGraph(PlayableGraph graph, GameObject go, IntervalTree <RuntimeElement> tree)
        {
            if (isSubTrack)
            {
                throw new InvalidOperationException("Nested animation tracks should never be asked to create a graph directly");
            }

            List <AnimationTrack> flattenTracks = new List <AnimationTrack>();

            if (CanCompileClips())
            {
                flattenTracks.Add(this);
            }


            bool animatesRootTransform = AnimatesRootTransform();

            foreach (var subTrack in GetChildTracks())
            {
                var child = subTrack as AnimationTrack;
                if (child != null && child.CanCompileClips())
                {
                    animatesRootTransform |= child.AnimatesRootTransform();
                    flattenTracks.Add(child);
                }
            }

            // figure out which mode to apply
            AppliedOffsetMode mode = GetOffsetMode(go, animatesRootTransform);
            var layerMixer         = CreateGroupMixer(graph, go, flattenTracks.Count);

            for (int c = 0; c < flattenTracks.Count; c++)
            {
                var compiledTrackPlayable = flattenTracks[c].inClipMode ?
                                            CompileTrackPlayable(graph, flattenTracks[c], go, tree, mode) :
                                            flattenTracks[c].CreateInfiniteTrackPlayable(graph, go, tree, mode);
                graph.Connect(compiledTrackPlayable, 0, layerMixer, c);
                layerMixer.SetInputWeight(c, flattenTracks[c].inClipMode ? 0 : 1);
                if (flattenTracks[c].applyAvatarMask && flattenTracks[c].avatarMask != null)
                {
                    layerMixer.SetLayerMaskFromAvatarMask((uint)c, flattenTracks[c].avatarMask);
                }
            }

            bool requiresMotionXPlayable = RequiresMotionXPlayable(mode, go);

            Playable mixer = layerMixer;

            mixer = CreateDefaultBlend(graph, go, mixer, requiresMotionXPlayable);

            // motionX playable not required in scene offset mode, or root transform mode
            if (requiresMotionXPlayable)
            {
                // If we are animating a root transform, add the motionX to delta playable as the root node
                var motionXToDelta = AnimationMotionXToDeltaPlayable.Create(graph);
                graph.Connect(mixer, 0, motionXToDelta, 0);
                motionXToDelta.SetInputWeight(0, 1.0f);
                motionXToDelta.SetAbsoluteMotion(UsesAbsoluteMotion(mode));
                mixer = (Playable)motionXToDelta;
            }



#if UNITY_EDITOR
            if (!Application.isPlaying)
            {
                var animator = GetBinding(go != null ? go.GetComponent <PlayableDirector>() : null);
                if (animator != null)
                {
                    GameObject targetGO = animator.gameObject;
                    IAnimationWindowPreview[] previewComponents = targetGO.GetComponents <IAnimationWindowPreview>();

                    m_HasPreviewComponents = previewComponents.Length > 0;
                    if (m_HasPreviewComponents)
                    {
                        foreach (var component in previewComponents)
                        {
                            mixer = component.BuildPreviewGraph(graph, mixer);
                        }
                    }
                }
            }
#endif

            return(mixer);
        }
Esempio n. 20
0
        internal override Playable CompileClips(PlayableGraph graph, GameObject go, IList <TimelineClip> timelineClips, IntervalTree <RuntimeElement> tree)
        {
            var clipBlender = AudioMixerPlayable.Create(graph, timelineClips.Count);

#if UNITY_EDITOR
            clipBlender.GetHandle().SetScriptInstance(m_TrackProperties.Clone());
            m_LiveMixerPlayable = clipBlender;
#else
            if (hasCurves)
            {
                clipBlender.GetHandle().SetScriptInstance(m_TrackProperties.Clone());
            }
#endif

            for (int i = 0; i < timelineClips.Count; i++)
            {
                var c     = timelineClips[i];
                var asset = c.asset as PlayableAsset;
                if (asset == null)
                {
                    continue;
                }

                var buffer     = 0.1f;
                var audioAsset = c.asset as AudioPlayableAsset;
                if (audioAsset != null)
                {
                    buffer = audioAsset.bufferingTime;
                }

                var source = asset.CreatePlayable(graph, go);
                if (!source.IsValid())
                {
                    continue;
                }

                if (source.IsPlayableOfType <AudioClipPlayable>())
                {
                    // Enforce initial values on all clips
                    var audioClipPlayable   = (AudioClipPlayable)source;
                    var audioClipProperties = audioClipPlayable.GetHandle().GetObject <AudioClipProperties>();

                    audioClipPlayable.SetVolume(Mathf.Clamp01(m_TrackProperties.volume * audioClipProperties.volume));
                    audioClipPlayable.SetStereoPan(Mathf.Clamp(m_TrackProperties.stereoPan, -1.0f, 1.0f));
                    audioClipPlayable.SetSpatialBlend(Mathf.Clamp01(m_TrackProperties.spatialBlend));
                }

                tree.Add(new ScheduleRuntimeClip(c, source, clipBlender, buffer));
                graph.Connect(source, 0, clipBlender, i);
                source.SetSpeed(c.timeScale);
                source.SetDuration(c.extrapolatedDuration);
                clipBlender.SetInputWeight(source, 1.0f);
            }

            ConfigureTrackAnimation(tree, go, clipBlender);

            return(clipBlender);
        }
Esempio n. 21
0
        internal virtual Playable OnCreateClipPlayableGraph(PlayableGraph graph, GameObject go, IntervalTree <RuntimeElement> tree)
        {
            if (tree == null)
            {
                throw new ArgumentException("IntervalTree argument cannot be null", "tree");
            }

            if (go == null)
            {
                throw new ArgumentException("GameObject argument cannot be null", "go");
            }

            var blend = CreateTrackMixer(graph, go, clips.Length);

            for (var c = 0; c < clips.Length; c++)
            {
                var source = CreatePlayable(graph, go, clips[c]);
                if (source.IsValid())
                {
                    source.SetDuration(clips[c].duration);
                    var clip = new RuntimeClip(clips[c], source, blend);
                    tree.Add(clip);
                    graph.Connect(source, 0, blend, c);
                    blend.SetInputWeight(c, 0.0f);
                }
            }

            return(blend);
        }
Esempio n. 22
0
        internal override Playable OnCreatePlayableGraph(PlayableGraph graph, GameObject go, IntervalTree <RuntimeElement> tree)
        {
            AudioMixerPlayable audioMixerPlayable = AudioMixerPlayable.Create(graph, base.clips.Length, false);

            for (int i = 0; i < base.clips.Length; i++)
            {
                TimelineClip  timelineClip  = base.clips[i];
                PlayableAsset playableAsset = timelineClip.asset as PlayableAsset;
                if (!(playableAsset == null))
                {
                    float num = 0.1f;
                    AudioPlayableAsset audioPlayableAsset = timelineClip.asset as AudioPlayableAsset;
                    if (audioPlayableAsset != null)
                    {
                        num = audioPlayableAsset.bufferingTime;
                    }
                    Playable playable = playableAsset.CreatePlayable(graph, go);
                    if (playable.IsValid <Playable>())
                    {
                        tree.Add(new ScheduleRuntimeClip(timelineClip, playable, audioMixerPlayable, (double)num, 0.1));
                        graph.Connect <Playable, AudioMixerPlayable>(playable, 0, audioMixerPlayable, i);
                        playable.SetSpeed(timelineClip.timeScale);
                        playable.SetDuration(timelineClip.extrapolatedDuration);
                        audioMixerPlayable.SetInputWeight(playable, 1f);
                    }
                }
            }
            return(audioMixerPlayable);
        }
Esempio n. 23
0
        internal override Playable OnCreateClipPlayableGraph(PlayableGraph graph, GameObject go, IntervalTree <RuntimeElement> tree)
        {
            if (isSubTrack)
            {
                throw new InvalidOperationException("Nested animation tracks should never be asked to create a graph directly");
            }

            List <AnimationTrack> flattenTracks = new List <AnimationTrack>();

            if (CanCompileClips())
            {
                flattenTracks.Add(this);
            }

            var genericRoot = GetGenericRootNode(go);
            var animatesRootTransformNoMask = AnimatesRootTransform();
            var animatesRootTransform       = animatesRootTransformNoMask && !IsRootTransformDisabledByMask(go, genericRoot);

            foreach (var subTrack in GetChildTracks())
            {
                var child = subTrack as AnimationTrack;
                if (child != null && child.CanCompileClips())
                {
                    var childAnimatesRoot = child.AnimatesRootTransform();
                    animatesRootTransformNoMask |= child.AnimatesRootTransform();
                    animatesRootTransform       |= (childAnimatesRoot && !child.IsRootTransformDisabledByMask(go, genericRoot));
                    flattenTracks.Add(child);
                }
            }

            // figure out which mode to apply
            AppliedOffsetMode mode = GetOffsetMode(go, animatesRootTransform);
            int defaultBlendCount  = GetDefaultBlendCount();
            var layerMixer         = CreateGroupMixer(graph, go, flattenTracks.Count + defaultBlendCount);

            for (int c = 0; c < flattenTracks.Count; c++)
            {
                int blendIndex = c + defaultBlendCount;
                // if the child is masking the root transform, compile it as if we are non-root mode
                var childMode = mode;
                if (mode != AppliedOffsetMode.NoRootTransform && flattenTracks[c].IsRootTransformDisabledByMask(go, genericRoot))
                {
                    childMode = AppliedOffsetMode.NoRootTransform;
                }

                var compiledTrackPlayable = flattenTracks[c].inClipMode ?
                                            CompileTrackPlayable(graph, flattenTracks[c], go, tree, childMode) :
                                            flattenTracks[c].CreateInfiniteTrackPlayable(graph, go, tree, childMode);
                graph.Connect(compiledTrackPlayable, 0, layerMixer, blendIndex);
                layerMixer.SetInputWeight(blendIndex, flattenTracks[c].inClipMode ? 0 : 1);
                if (flattenTracks[c].applyAvatarMask && flattenTracks[c].avatarMask != null)
                {
                    layerMixer.SetLayerMaskFromAvatarMask((uint)blendIndex, flattenTracks[c].avatarMask);
                }
            }

            var requiresMotionXPlayable = RequiresMotionXPlayable(mode, go);

            // In the editor, we may require the motion X playable if we are animating the root transform but it is masked out, because the default poses
            //  need to properly update root motion
            requiresMotionXPlayable |= (defaultBlendCount > 0 && RequiresMotionXPlayable(GetOffsetMode(go, animatesRootTransformNoMask), go));

            // Attach the default poses
            AttachDefaultBlend(graph, layerMixer, requiresMotionXPlayable);

            // motionX playable not required in scene offset mode, or root transform mode
            Playable mixer = layerMixer;

            if (requiresMotionXPlayable)
            {
                // If we are animating a root transform, add the motionX to delta playable as the root node
                var motionXToDelta = AnimationMotionXToDeltaPlayable.Create(graph);
                graph.Connect(mixer, 0, motionXToDelta, 0);
                motionXToDelta.SetInputWeight(0, 1.0f);
                motionXToDelta.SetAbsoluteMotion(UsesAbsoluteMotion(mode));
                mixer = (Playable)motionXToDelta;
            }


#if UNITY_EDITOR
            if (!Application.isPlaying)
            {
                var animator = GetBinding(go != null ? go.GetComponent <PlayableDirector>() : null);
                if (animator != null)
                {
                    GameObject targetGO = animator.gameObject;
                    IAnimationWindowPreview[] previewComponents = targetGO.GetComponents <IAnimationWindowPreview>();

                    m_HasPreviewComponents = previewComponents.Length > 0;
                    if (m_HasPreviewComponents)
                    {
                        foreach (var component in previewComponents)
                        {
                            mixer = component.BuildPreviewGraph(graph, mixer);
                        }
                    }
                }
            }
#endif

            return(mixer);
        }
        internal Playable CompileTrackPlayable(PlayableGraph graph, TrackAsset track, GameObject go, IntervalTree <RuntimeElement> tree)
        {
            AnimationMixerPlayable animationMixerPlayable = AnimationMixerPlayable.Create(graph, track.clips.Length, false);

            for (int i = 0; i < track.clips.Length; i++)
            {
                TimelineClip  timelineClip  = track.clips[i];
                PlayableAsset playableAsset = timelineClip.asset as PlayableAsset;
                if (!(playableAsset == null))
                {
                    if (timelineClip.recordable)
                    {
                        AnimationPlayableAsset animationPlayableAsset = playableAsset as AnimationPlayableAsset;
                        if (animationPlayableAsset != null)
                        {
                            animationPlayableAsset.removeStartOffset = !timelineClip.recordable;
                        }
                    }
                    Playable playable = playableAsset.CreatePlayable(graph, go);
                    if (playable.IsValid <Playable>())
                    {
                        RuntimeClip item = new RuntimeClip(timelineClip, playable, animationMixerPlayable);
                        tree.Add(item);
                        graph.Connect <Playable, AnimationMixerPlayable>(playable, 0, animationMixerPlayable, i);
                        animationMixerPlayable.SetInputWeight(i, 0f);
                    }
                }
            }
            return(this.ApplyTrackOffset(graph, animationMixerPlayable));
        }