예제 #1
0
    private IEnumerator BlendIn(PlayableDirector director, AnimationPlayableOutput output, float blendTime, float startTime = -1, Action onFinished = null)
    {
        director.time = startTime > 0 ? startTime : 0;
        director.Play();
        output.SetWeight(0);
        _abortBlendIn = false;

        float t = 0;

        while (t < blendTime)
        {
            if (_abortBlendIn)
            {
                //Debug.Log($"{name}: Aborted Blend in");
                _abortBlendIn = false;
                break;
            }

            var weight = Mathf.Clamp01(t / blendTime);

            output.SetWeight(weight);

            //Debug.Log($"{name}: BlendIn - t:{t:N2}, w={weight:N2}, dT={director.time:N2}");

            yield return(null);

            t += Time.deltaTime;
        }

        output.SetWeight(1);
        onFinished?.Invoke();
    }
예제 #2
0
    private void BuildOutput()
    {
        PlayableDirector.Evaluate();

        if (PlayableDirector.playableGraph.IsValid())
        {
            _outputTrackIndex       = 0;
            _trackAsset             = (PlayableDirector.playableAsset as TimelineAsset)?.GetOutputTrack(_outputTrackIndex);
            _originalOutput         = (AnimationPlayableOutput)PlayableDirector.playableGraph.GetOutputByType <AnimationPlayableOutput>(_outputTrackIndex);
            _originalSourcePlayable = _originalOutput.GetSourcePlayable();
            _clone         = PlayableDirector.playableAsset.CreatePlayable(PlayableDirector.playableGraph, PlayableDirector.gameObject);
            _mixer         = AnimationMixerPlayable.Create(PlayableDirector.playableGraph, 2);
            _cloneIndex    = _mixer.AddInput(_clone, 0);
            _originalIndex = _mixer.AddInput(_originalSourcePlayable, 0, 1f);

            if (_originalOutput.IsOutputValid() && _originalOutput.GetTarget() != null)
            {
                _output = AnimationPlayableOutput.Create(PlayableDirector.playableGraph, "OverridedDirectorOutput" + GetInstanceID(), _originalOutput.GetTarget());
                _output.SetSourcePlayable(_mixer);
                _output.SetSourceOutputPort(_originalOutput.GetSourceOutputPort());
                _output.SetWeight(1f);
                _originalOutput.SetTarget(null);
            }
            else
            {
                Debug.Log("Original Director Output is invalid");
            }
        }
    }
예제 #3
0
        /// <summary>
        /// Called by Unity.
        /// </summary>
        private void OnEnable()
        {
            _cubismFadeMotionList = GetComponent <CubismFadeController>().CubismFadeMotionList;

            // Fail silently...
            if (_cubismFadeMotionList == null)
            {
                Debug.LogError("CubismMotionController : CubismFadeMotionList doesn't set in CubismFadeController.");
                return;
            }

            // Get Animator.
            var animator = GetComponent <Animator>();

            if (animator.runtimeAnimatorController != null)
            {
                Debug.LogWarning("Animator Controller was set in Animator component.");
                return;
            }

            _isActive = true;

            // Disabble animator's playablegrap.
            var graph = animator.playableGraph;

            if (graph.IsValid())
            {
                graph.GetOutput(0).SetWeight(0);
            }

            // Create Playable Graph.
            _playableGrap = PlayableGraph.Create("Playable Graph : " + this.FindCubismModel().name);
            _playableGrap.SetTimeUpdateMode(DirectorUpdateMode.GameTime);

            // Create Playable Output.
            _playableOutput = AnimationPlayableOutput.Create(_playableGrap, "Animation", animator);
            _playableOutput.SetWeight(1);

            // Create animation layer mixer.
            _layerMixer = AnimationLayerMixerPlayable.Create(_playableGrap, LayerCount);

            // Create cubism motion layers.
            if (_motionLayers == null)
            {
                LayerCount    = (LayerCount < 1) ? 1 : LayerCount;
                _motionLayers = new CubismMotionLayer[LayerCount];
            }

            for (var i = 0; i < LayerCount; ++i)
            {
                _motionLayers[i] = CubismMotionLayer.CreateCubismMotionLayer(_playableGrap, _cubismFadeMotionList);
                _motionLayers[i].AnimationEndHandler += OnAnimationEnd;
                _layerMixer.ConnectInput(i, _motionLayers[i].PlayableOutput, 0);
                _layerMixer.SetInputWeight(i, 1.0f);
            }

            // Set Playable Output.
            _playableOutput.SetSourcePlayable(_layerMixer);
        }
예제 #4
0
        public void Evaluate()
        {
            m_Output.SetWeight(1);
            for (int i = 0; i < m_Mixers.Count; i++)
            {
                var   mixInfo = m_Mixers[i];
                float weight  = mixInfo.modulate ? mixInfo.parentMixer.GetInputWeight(mixInfo.port) : 1.0f;
                mixInfo.parentMixer.SetInputWeight(mixInfo.port, weight * WeightUtility.NormalizeMixer(mixInfo.mixer));
            }

            float normalizedWeight = WeightUtility.NormalizeMixer(m_LayerMixer);

            var animator = m_Output.GetTarget();

            if (animator == null)
            {
                return;
            }

#if UNITY_EDITOR
            // AnimationMotionXToDeltaPlayable must blend with default values when previewing tracks with absolute root motion.
            bool blendMotionX = !Application.isPlaying && m_MotionXPlayable.IsValid() && m_MotionXPlayable.IsAbsoluteMotion();

            if (blendMotionX)
            {
                if (!m_PoseMixer.Equals(AnimationLayerMixerPlayable.Null))
                {
                    m_PoseMixer.SetInputWeight(0, 1.0f);
                    m_PoseMixer.SetInputWeight(1, normalizedWeight);
                }
            }
            else
            {
                if (!m_PoseMixer.Equals(AnimationLayerMixerPlayable.Null))
                {
                    m_PoseMixer.SetInputWeight(0, 1.0f);
                    m_PoseMixer.SetInputWeight(1, 1.0f);
                }

                m_Output.SetWeight(normalizedWeight);
            }
#else
            m_Output.SetWeight(normalizedWeight);
#endif
        }
예제 #5
0
    private IEnumerator SeekBlend(float blendTime, float startTime = -1, Action onFinished = null)
    {
        float t = 0;

        // Set it to play exactly what the main output is currently playing.
        _clone.SetTime(PlayableDirector.time);
        _clone.Play();

        //Debug.Log($"{name}: CrossFade Start - OriginalTime: {PlayableDirector.time:N4}, w={_mixer.GetInputWeight(_originalIndex)} | CloneTime {_clone.GetTime():N4}, w={_mixer.GetInputWeight(_cloneIndex)} | oW={_output.GetWeight()}");

        // todo, blend main weight if nessesary e.g seeking half-way through a blend-in/out
        _output.SetWeight(1);

        // Let the clone take over control.
        _mixer.SetInputWeight(_cloneIndex, 1f);
        _mixer.SetInputWeight(_originalIndex, 0f);

        // Normally when time changes (and play() or evaluate() are called) it will reposition
        // the transform based on what should have happened by the new point in time (relative to the timeline start).
        // Which is not desirable! Instead we want everything to continue from its current position.
        // This issue can be circumvented by changing a playable while inactive.
        //_output.SetWeight(0);
        PlayableDirector.time = startTime;
        PlayableDirector.Play();
        PlayableDirector.Evaluate();

        //Debug.Log($"AnimationTransform: 1) {start} 2) {cur} Dist: {Vector3.Distance(start, cur)}");

        //float t = 0f;
        // Blend from the
        while (t < blendTime)
        {
            var normalizedTime = Mathf.Clamp01(t / blendTime);
            _decreasingWeight = 1 - normalizedTime;
            _increasingWeight = normalizedTime;

            _mixer.SetInputWeight(_cloneIndex, _decreasingWeight);
            _mixer.SetInputWeight(_originalIndex, _increasingWeight);

            //Debug.Log($"{name}: Seek - CloneTime: {_clone.GetTime():N2}, w={_decreasingWeight:N2} | OriginalTime: {PlayableDirector.time:N2}, w={_increasingWeight:N2}");

            yield return(null);

            t += Time.deltaTime;
        }

        _mixer.SetInputWeight(_cloneIndex, 0);
        _mixer.SetInputWeight(_originalIndex, 1f);

        _clone.Pause();



        onFinished?.Invoke();
        //Debug.Log("CrossFade Finished");
    }
예제 #6
0
        //...
        protected override void OnExit()
        {
            if (isMasterTrack)
            {
                animator.applyRootMotion = wasRootMotion;
                animator.cullingMode     = wasCullingMode;
                if (graph.IsValid())
                {
                    animationOutput.SetWeight(0);
                    graph.Evaluate();
                    graph.Destroy();
                }

                if (useRootMotion)
                {
                    ApplyBakedRootMotion(endTime - startTime);
                }
            }
        }
        public void Evaluate()
        {
            float weight = 1;

            m_Output.SetWeight(1);
            for (int i = 0; i < m_Mixers.Count; i++)
            {
                var mixInfo = m_Mixers[i];
                weight = WeightUtility.NormalizeMixer(mixInfo.mixer);
                mixInfo.parentMixer.SetInputWeight(mixInfo.port, weight);
            }

            // only write the final weight in player/playmode. In editor, we are blending to the appropriate defaults
            // the last mixer in the list is the final blend, since the list is composed post-order.
            if (Application.isPlaying)
            {
                m_Output.SetWeight(weight);
            }
        }
예제 #8
0
 private void EvaluateWeightsForAnimationPlayableOutput(TrackAsset track, AnimationPlayableOutput animOutput)
 {
     if (track as AnimationTrack != null)
     {
         this.m_EvaluateCallbacks.Add(new AnimationOutputWeightProcessor(animOutput));
     }
     else
     {
         animOutput.SetWeight(1f);
     }
 }
예제 #9
0
    private IEnumerator BlendOut(PlayableDirector director, AnimationPlayableOutput output, float blendTime, float fromWeight = 1f, Action onFinished = null)
    {
        float t = blendTime - blendTime * fromWeight;

        //Debug.Log($"{name}: Started blend out from {fromWeight} weight, oW={output.GetWeight()}, t={t}");

        while (t < blendTime)
        {
            var weight = 1 - Mathf.Clamp01(t / blendTime);

            if (!output.IsOutputValid())
            {
                //Debug.Log($"{name}: BlendOut has an invalid output graph");
                break;
            }

            //Debug.Log($"{name}: BlendOut - t:{t:N2}, w={weight:N2}, dT={director.time:N2}/{director.duration:N2}");
            output.SetWeight(weight);

            yield return(null);

            t += Time.deltaTime;
        }

        if (output.IsOutputValid())
        {
            output.SetWeight(0);
        }

        onFinished?.Invoke();

        if (director.isActiveAndEnabled)
        {
            director.Pause();
        }
    }
 public AnimationOutputWeightProcessor(AnimationPlayableOutput output)
 {
     m_Output = output;
     output.SetWeight(0);
     FindMixers();
 }