コード例 #1
0
 public void Evaluate()
 {
     if (m_Graph.IsValid())
     {
         m_Graph.Evaluate();
     }
 }
コード例 #2
0
        //...
        protected override void OnUpdate(float time, float previousTime)
        {
            if (isMasterTrack)
            {
                if (animator == null || !animator.gameObject.activeInHierarchy || !graph.IsValid())
                {
                    return;
                }

                var totalSiblingWeight = 0f;
                for (var i = 0; i < siblingTracks.Count; i++)
                {
                    var siblingWeight = siblingTracks[i].compoundTrackWeight;
                    masterMixer.SetInputWeight(i, siblingWeight);
                    totalSiblingWeight += siblingWeight;
                }


                var animatorWeight = totalSiblingWeight < 1 ? 1 - totalSiblingWeight : 0;
                masterMixer.SetInputWeight(siblingTracks.Count + 1, animatorWeight);

                graph.Evaluate(time - previousTime);
                if (useRootMotion && useBakedRootMotion)
                {
                    ApplyBakedRootMotion(time);
                }
            }
        }
コード例 #3
0
        protected override void OnUpdate(float time, float previousTime)
        {
            if (animator == null || !animator.gameObject.activeInHierarchy)
            {
                return;
            }

#if UNITY_2017_1_OR_NEWER
            if (!graph.IsValid())
            {
                return;
            }

            baseClipPlayable.SetTime(time * basePlaybackSpeed);
            graph.Evaluate(0);
#elif UNITY_5_6_OR_NEWER
            if (!graph.IsValid())
            {
                return;
            }

            baseClipPlayableHandle.time = time * basePlaybackSpeed;
            graph.Evaluate(0);
#else
            if (!mixerPlayable.IsValid())
            {
                return;
            }

            if (!animator.isInitialized)
            {
                animator.Play(mixerPlayable);
            }

            if (baseAnimationClip != null)
            {
                var basePlayable = mixerPlayable.GetInput(0);
                basePlayable.time = time * basePlaybackSpeed;
                mixerPlayable.SetInput(basePlayable, 0);
            }

            animator.Update(0);
#endif

            if (useRootMotion && useBakedRootMotion)
            {
                ApplyBakedRootMotion(time);
            }
        }
コード例 #4
0
        /// <summary>
        /// Use animation Playables API to control keyed values, blended between the first frame of 2 animation clips.
        /// </summary>
        /// <param name="valueForAdaptationCurve">A value to evaluate into adaptation curve producing a real blend value for 2 clips.</param>
        /// <param name="animator">The control target for animation playables. The clips used must be able to control the keyed fields traveling down from this animator component.</param>
        public void Adapt(float valueForAdaptationCurve, Animator animator)
        {
            if (!Adaptable)
            {
                return;
            }

            float blend = adaptationCurve.Evaluate(valueForAdaptationCurve);

            //Connect up a playable graph, evaluate once, then we're done with them.
            PlayableGraph pg = PlayableGraph.Create("AdaptationGraph");

            pg.SetTimeUpdateMode(DirectorUpdateMode.Manual);

            var mixer = AnimationMixerPlayable.Create(pg, 2, normalizeWeights: true);

            //Not sure if the mixer should be "cross fade" like this, or should we do 0~1 weight over 1 weight?
            //But I think that's for AnimationLayerMixerPlayable ?
            mixer.SetInputWeight(inputIndex: 0, weight: 1 - blend);
            mixer.SetInputWeight(inputIndex: 1, weight: blend);


            var normalStateAcp       = AnimationClipPlayable.Create(pg, normalState);
            var fullyAdaptedStateAcp = AnimationClipPlayable.Create(pg, fullyAdaptedState);

            pg.Connect(normalStateAcp, sourceOutputPort: 0, mixer, destinationInputPort: 0);
            pg.Connect(fullyAdaptedStateAcp, sourceOutputPort: 0, mixer, destinationInputPort: 1);

            var output = AnimationPlayableOutput.Create(pg, "AdaptationGraphOutput", animator);

            output.SetSourcePlayable(mixer);

            pg.Evaluate();
            pg.Destroy();
        }
コード例 #5
0
 private void FixedUpdate()
 {
     if (mode == DirectorUpdateMode.Manual)
     {
         graph.Evaluate(Time.fixedDeltaTime);
     }
 }
コード例 #6
0
        public void SampleAnimation(AnimationClip clip, float time)
        {
#if UNITY_2018_3_OR_NEWER
            ResetTranformRoot();

            va.UpdateSyncEditorCurveClip();

            if (animator != null)
            {
                PlayableGraphReady(clip);

#if UNITY_2019_1_OR_NEWER
                m_AnimationClipPlayable.SetTime(time);
#else
                //Loop cannot be disabled because there is no SetOverrideLoopTime
                var subTime = time;
                if (subTime > clip.length)
                {
                    subTime = clip.length - 0.0000001f;
                }
                m_AnimationClipPlayable.SetTime(subTime);
#endif
                m_PlayableGraph.Evaluate();
            }
            else if (animation != null)
            {
                SampleAnimationLegacy(clip, time);
            }
#else
            SampleAnimationLegacy(clip, time);
#endif
        }
コード例 #7
0
    void OnEnable()
    {
        m_Animator = GetComponent <Animator>();

        // Setting to Always animate because on the first frame the renderer can be not visible which break syncGoal on start up
        m_Animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;

        if (!m_Animator.avatar.isHuman)
        {
            throw new InvalidOperationException("Avatar must be a humanoid.");
        }

        m_Graph = PlayableGraph.Create();
        m_Graph.SetTimeUpdateMode(DirectorUpdateMode.GameTime);
        var output = AnimationPlayableOutput.Create(m_Graph, "output", m_Animator);

        var clip         = SampleUtility.LoadAnimationClipFromFbx("DefaultMale/Models/DefaultMale_Humanoid", "Idle");
        var clipPlayable = AnimationClipPlayable.Create(m_Graph, clip);

        clipPlayable.SetApplyFootIK(false);
        clipPlayable.SetApplyPlayableIK(false);

        var job = new FullBodyIKJob();

        job.stiffness        = stiffness;
        job.maxPullIteration = maxPullIteration;

        SetupIKLimbHandle(ref job.leftArm, HumanBodyBones.LeftUpperArm, HumanBodyBones.LeftLowerArm, HumanBodyBones.LeftHand);
        SetupIKLimbHandle(ref job.rightArm, HumanBodyBones.RightUpperArm, HumanBodyBones.RightLowerArm, HumanBodyBones.RightHand);
        SetupIKLimbHandle(ref job.leftLeg, HumanBodyBones.LeftUpperLeg, HumanBodyBones.LeftLowerLeg, HumanBodyBones.LeftFoot);
        SetupIKLimbHandle(ref job.rightLeg, HumanBodyBones.RightUpperLeg, HumanBodyBones.RightLowerLeg, HumanBodyBones.RightFoot);

        m_LeftFootEffector  = SetupEffector(ref job.leftFootEffector, "LeftFootEffector");
        m_RightFootEffector = SetupEffector(ref job.rightFootEffector, "RightFootEffector");
        m_LeftHandEffector  = SetupEffector(ref job.leftHandEffector, "LeftHandEffector");
        m_RightHandEffector = SetupEffector(ref job.rightHandEffector, "RightHandEffector");

        m_LeftKneeHintEffector   = SetupHintEffector(ref job.leftKneeHintEffector, "LeftKneeHintEffector");
        m_RightKneeHintEffector  = SetupHintEffector(ref job.rightKneeHintEffector, "RightKneeHintEffector");
        m_LeftElbowHintEffector  = SetupHintEffector(ref job.leftElbowHintEffector, "LeftElbowHintEffector");
        m_RightElbowHintEffector = SetupHintEffector(ref job.rightElbowHintEffector, "RightElbowHintEffector");

        m_LookAtEffector = SetupLookAtEffector(ref job.lookAtEffector, "LookAtEffector");

        m_BodyRotationEffector = SetupBodyEffector(ref job.bodyEffector, "BodyEffector");



        m_IKPlayable = AnimationScriptPlayable.Create <FullBodyIKJob>(m_Graph, job, 1);
        m_IKPlayable.ConnectInput(0, clipPlayable, 0, 1.0f);

        output.SetSourcePlayable(m_IKPlayable);

        m_Graph.Play();
        m_Graph.Evaluate(0);
        SyncIKFromPose();

        ResetIKWeight();
    }
コード例 #8
0
    private void AnimationFrameUpdate()
    {
        //mixerがない、アニメーション速度が0以下
        if ((!(mixer.IsValid())) || (animationSpeed <= 0))
        {
            return;
        }
        mixer.SetTime(0);
        //ブレンドフレームが設定されていれば
        if (changeWeightFrame > 0)
        {
            float changeMinus = (1.0f - ((float)frameCount / (float)changeWeightFrame));
            //フレームごとにブレンド
            mixer.SetInputWeight(0, 1.0f - changeMinus);
            mixer.SetInputWeight(1, changeMinus);
            //完全にブレンドしたら数字を0に
            if (frameCount >= changeWeightFrame)
            {
                changeWeightFrame = 0;
            }
        }
        //なければ普通に再生
        else
        {
            mixer.SetInputWeight(0, 1.0f);
            mixer.SetInputWeight(1, 0);
        }
        //更新
        if (beforeClipPlayable.IsValid())
        {
            beforeClipPlayable.SetTime(beforeClipTime);
        }
        playableGraph.Evaluate((1.0f / nowClip.frameRate) * animationSpeed);
        //フレーム取得
        nowFrame = (int)(((float)nowClipPlayable.GetTime() * nowClip.frameRate) * (1 / animationSpeed));
        bool endAnimation = (nowFrame >= (int)((nowClip.length * nowClip.frameRate * (1.0f / animationSpeed))));

        //現在のフレーム数が最大であれば
        if (endAnimation)
        {
            if (nowClip.isLooping)
            {
                mixer.SetTime(0);
                nowClipPlayable.SetTime(0);
                if (beforeClipPlayable.IsValid())
                {
                    beforeClipPlayable.SetTime(0);
                }
            }
        }
        //アニメーションが終わっているかどうかの判定
        endAnimFrag = endAnimation;

        frameCount++;
        if (frameCount >= int.MaxValue - 1)
        {
            frameCount = 0;
        }
    }
コード例 #9
0
 protected override void OnSetValue(float t)
 {
     if (this.enabled)
     {
         if (animator != null && playableGraph.IsValid())
         {
             clipPlayable.SetTime(t * clip.length);
             playableGraph.Evaluate();
         }
     }
 }
コード例 #10
0
        protected override void OnUpdate(float time, float previousTime)
        {
            if (animator == null || !animator.gameObject.activeInHierarchy)
            {
                return;
            }

            if (!graph.IsValid())
            {
                return;
            }

            baseClipPlayableHandle.time = time * basePlaybackSpeed;
            graph.Evaluate(0);

            if (useRootMotion && useBakedRootMotion)
            {
                ApplyBakedRootMotion(time);
            }
        }
コード例 #11
0
        public void Update()
        {
            if (!EditorApplication.isPlaying)
            {
                //graph.SetTimeUpdateMode(UnityEngine.Playables.DirectorUpdateMode.Manual);
                graph.Evaluate();
            }
            graph.Evaluate();

            for (int i = 0; i < poses.Count; i++)
            {
                try
                {
                    poseMixer.SetInputWeight(i, poses[i].Weight);
                }
                catch
                {
                    poses.RemoveAt(i);
                }
            }
        }
コード例 #12
0
        //...
        protected override void OnUpdate(float time, float previousTime)
        {
            if (isMasterTrack)
            {
                if (animator == null || !animator.gameObject.activeInHierarchy || !graph.IsValid())
                {
                    return;
                }

                for (var i = 0; i < siblingTracks.Count; i++)
                {
                    masterMixer.SetInputWeight(i, siblingTracks[i].compoundTrackWeight);
                }

                graph.Evaluate(0);
                if (useRootMotion && useBakedRootMotion)
                {
                    ApplyBakedRootMotion(time);
                }
            }
        }
コード例 #13
0
 public void UpdateGraph(float dt)
 {
     if (!isPlaying || isPause)
     {
         return;
     }
     sampleTimer += dt;
     if (sampleTimer > sampleIntervalp)
     {
         m_Graph.Evaluate(sampleTimer);
         sampleTimer = 0;
     }
 }
コード例 #14
0
 private void Update()
 {
     if (nowPlayAnimation == null)
     {
         if (mixer.IsValid())
         {
             mixer.Destroy();
         }
         _beforeNowPlayClip = null;
     }
     else if (_beforeNowPlayClip != nowPlayAnimation)
     {
         SetPlayAnimation(nowPlayAnimation, frameSpeed, changeFrameNow);
     }
     SetNextAnimationPlayable();
     if (playableGraph.IsValid() && mixer.IsValid())
     {
         if (frameSpeed <= 0)
         {
             return;
         }
         if (changeWeightFrame > 0)
         {
             mixer.SetInputWeight(0, (1.0f - num) - ((1.0f) - (((float)_nowChangeFrame) / ((float)changeWeightFrame))));
             mixer.SetInputWeight(1, num + ((1.0f) - (((float)_nowChangeFrame) / ((float)changeWeightFrame))));
             if (_nowChangeFrame >= changeWeightFrame)
             {
                 changeWeightFrame = 0;
                 _nowChangeFrame   = 0;
             }
             _nowChangeFrame++;
         }
         else
         {
             mixer.SetInputWeight(0, (1.0f - num));
             mixer.SetInputWeight(1, num);
         }
         playableGraph.Evaluate((1.0f / nowPlayAnimation.frameRate) * frameSpeed);
         nowFrame = (int)(((float)mixer.GetTime() * nowPlayAnimation.frameRate) * frameSpeed);
         //ループ
         if (nowFrame >= (nowPlayAnimation.length * nowPlayAnimation.frameRate * frameSpeed) && nowPlayAnimation.isLooping)
         {
             mixer.SetTime(0);
             _nowPlayAnimation.SetTime(0);
             if (_beforePlayAnimation.IsValid())
             {
                 _beforePlayAnimation.SetTime(0);
             }
         }
     }
 }
コード例 #15
0
ファイル: SingleAnimation.cs プロジェクト: r-kajiya/Framework
        public void AnimationManualUpdate()
        {
            if (!_isInitialized)
            {
                return;
            }

            if (_updateMode != DirectorUpdateMode.Manual)
            {
                return;
            }

            _playableGraph.Evaluate(Time.deltaTime);
        }
コード例 #16
0
        public void Update(float deltaTime)
        {
            _graph.Evaluate(deltaTime);

            // 更新所有层级
            for (int i = 0; i < _mixers.Count; i++)
            {
                var mixer = _mixers[i];
                if (mixer.IsConnect)
                {
                    mixer.Update(deltaTime);
                }
            }
        }
コード例 #17
0
        public void Update()
        {
            graph.Evaluate();

            for (int i = 0; i < poses.Count; i++)
            {
                try
                {
                    poseMixer.SetInputWeight(i, poses[i].Weight);
                }
                catch
                {
                    poses.RemoveAt(i);
                }
            }
        }
コード例 #18
0
    void Update()
    {
        if (!mixer.IsValid() || Speed == 0)
        {
            return;
        }
        var cWeight = mixer.GetInputWeight(0);

        if (cWeight < 1)
        {
            cWeight = Mathf.Lerp(0, 1, (Time.time - changeTime) / blendTime);
            mixer.SetInputWeight(0, cWeight);
            mixer.SetInputWeight(1, 1 - cWeight);
        }
        graph.Evaluate(Time.deltaTime * Speed);
    }
        public void Evaluate(float dt)
        {
            m_SyncSceneToStreamLayer?.Update(m_RigLayers);

            if (m_RigLayers != null)
            {
                foreach (var layer in m_RigLayers)
                {
                    if (layer.IsValid() && layer.active)
                    {
                        layer.Update();
                    }
                }
            }

            m_Graph.Evaluate(dt);
        }
コード例 #20
0
        public override void UpdateMovement(out Vector3 goalPosition, out Quaternion goalRotation, float deltaTime)
        {
            // Remember pose before animation
            Vector3    _positionBeforeAnim = _transform.position;
            Quaternion _rotationBeforeAnim = _transform.rotation;

            // Update animation
            _playableGraph.Evaluate(deltaTime);

            // Set our platform's goal pose to the animation's
            goalPosition = _transform.position;
            goalRotation = _transform.rotation;

            // Reset the actual transform pose to where it was before evaluating.
            // This is so that the real movement can be handled by the physics mover; not the animation
            _transform.position = _positionBeforeAnim;
            _transform.rotation = _rotationBeforeAnim;
        }
コード例 #21
0
        public void ApplyState(ref PlayerState state)
        {
            StateMachine.Presimulate(ref state);
            var stateInfo = GetControllerState(ref state);

            if (stateInfo == null)
            {
                return;
            }
            foreach (var controllerState in _states)
            {
                controllerState.Disconnect();
                controllerState.SetWeight(0f);
            }

            stateInfo.Connect();
            stateInfo.SetWeight(1f);
            stateInfo.SetTime(ref state);
            _playableGraph.Evaluate();
        }
コード例 #22
0
        public void Tick(float deltaTime)
        {
            _playableGraph.Evaluate(deltaTime);

            for (int i = 0; i < AnimationPlayLayers.Length; i++)
            {
                var currLayer = AnimationPlayLayers[i];

                if (currLayer.GetWeight(out var aW, out var bW))
                {
                    mixerPlayable.SetInputWeight(currLayer.aInputIndex, aW);
                    mixerPlayable.SetInputWeight(currLayer.bInputIndex, bW);

                    if (aW <= 0)
                    {
                        mixerPlayable.DisconnectInput(currLayer.aInputIndex);
                        currLayer.EndBInput();
                    }
                }
                currLayer.Time += deltaTime;
            }
        }
コード例 #23
0
        public void GenerateRootLookupTable()
        {
            AnimationClip primaryClip = this.TargetClip;

            if (primaryClip != null)
            {
                if (m_targetPrefab == null)
                {
                    if (m_targetPreProcessData != null)
                    {
                        m_targetPrefab = m_targetPreProcessData.Prefab;
                    }
                    else if(m_targetAnimModule != null)
                    {
                        m_targetPrefab = m_targetPreProcessData.Prefab;
                    }
                }

                if (m_targetPrefab != null)
                {
                    if (m_rootPosLookupTable == null)
                        m_rootPosLookupTable = new List<Vector3>();

                    if (m_rootRotLookupTable == null)
                        m_rootRotLookupTable = new List<Quaternion>();

                    if (m_rootSpeedLookupTable == null)
                        m_rootSpeedLookupTable = new List<float>();

                    m_rootPosLookupTable.Clear();
                    m_rootRotLookupTable.Clear();
                    m_rootSpeedLookupTable.Clear();

                    //Instantiate prefab and setup playable graph
                    GameObject previewPrefab = Instantiate(m_targetPrefab);
                    Animator previewAnimator = previewPrefab.GetComponent<Animator>();

                    if (previewAnimator == null)
                    {
                        previewAnimator = previewPrefab.AddComponent<Animator>();
                        previewAnimator.applyRootMotion = true;
                    }

                    PlayableGraph playableGraph = PlayableGraph.Create();
                    playableGraph.SetTimeUpdateMode(DirectorUpdateMode.Manual);

                    var playableOutput = AnimationPlayableOutput.Create(playableGraph, "Animation", previewAnimator);
                    AnimationMixerPlayable animationMixer = AnimationMixerPlayable.Create(playableGraph, 1, true);
                    playableOutput.SetSourcePlayable(animationMixer);
                    var playableClip = AnimationClipPlayable.Create(playableGraph, primaryClip);
                    animationMixer.ConnectInput(0, playableClip, 0);
                    animationMixer.SetInputWeight(0, 1f);
                    playableClip.SetTime(0.0);
                    playableClip.SetTime(0.0);

                    previewPrefab.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
                    playableGraph.Evaluate(0f);

                    double sampleRate = 1.0 / primaryClip.frameRate;

                    //Fill the lookup table with root positions
                    for (double animTime = 0.0; animTime <= primaryClip.length; animTime += sampleRate)
                    {
                        m_rootPosLookupTable.Add(previewPrefab.transform.position);
                        m_rootRotLookupTable.Add(previewPrefab.transform.rotation);
                        playableGraph.Evaluate((float)sampleRate);
                    }

                    playableGraph.Destroy();
                    GameObject.DestroyImmediate(previewPrefab);


                    if (m_rootPosLookupTable.Count > 1)
                    {
                        //Generate the linear speed lookup table
                        for (int i = 1; i < m_rootPosLookupTable.Count; ++i)
                        {
                            Vector3 startPos = m_rootPosLookupTable[i - 1];
                            Vector3 endPos = m_rootPosLookupTable[i];

                            m_rootSpeedLookupTable.Add(Vector3.Distance(endPos, startPos) / (float)sampleRate);
                        }
                    }
                    else
                    {
                        m_rootSpeedLookupTable.Add(0f);
                    }

                    m_rootSpeedLookupTable.Insert(0, m_rootSpeedLookupTable[0]);
                }
            }
        }
コード例 #24
0
        private void DrawAnimationStatePreview()
        {
            EditorUtilities.Splitter();

            var oldPreviewMode = previewMode;

            EditorUtilities.DrawHorizontal(() =>
            {
                EditorGUILayout.LabelField("Preview mode");

                EditorGUI.BeginDisabledGroup(previewMode == PreviewMode.Automatic);
                if (GUILayout.Button("Automatic"))
                {
                    previewMode = PreviewMode.Automatic;
                }
                EditorGUI.EndDisabledGroup();

                EditorGUI.BeginDisabledGroup(previewMode == PreviewMode.Manual);
                if (GUILayout.Button("Manual"))
                {
                    previewMode = PreviewMode.Manual;
                }
                EditorGUI.EndDisabledGroup();
            });

            if (oldPreviewMode == PreviewMode.Manual && previewMode == PreviewMode.Automatic)
            {
                automaticPreviewLastTime = Time.realtimeSinceStartup;
            }

            if (previewMode == PreviewMode.Manual)
            {
                var oldPreviewTime = previewTime;
                previewTime = EditorGUILayout.Slider(previewTime, 0f, currentPreviewedState.Duration);

                previewGraph.Evaluate(previewTime - oldPreviewTime);
            }
            else
            {
                var currentTime = Time.realtimeSinceStartup;
                var deltaTime   = currentTime - automaticPreviewLastTime;
                automaticPreviewLastTime = currentTime;

                previewTime = (previewTime + deltaTime) % currentPreviewedState.Duration;

                previewGraph.Evaluate(deltaTime);

                var oldVal = previewTime;
                previewTime = EditorGUILayout.Slider(previewTime, 0f, currentPreviewedState.Duration);
                if (oldVal != previewTime)
                {
                    previewMode = PreviewMode.Manual;
                }
            }

            SceneView.RepaintAll();

            if (GUILayout.Button("Stop preview"))
            {
                StopPreviewing();
            }
        }
コード例 #25
0
        public override void InitForAvatar()
        {
            StartVrcHooks();

            AvatarAnimator.applyRootMotion           = false;
            AvatarAnimator.runtimeAnimatorController = null;
            AvatarAnimator.updateMode  = AnimatorUpdateMode.Normal;
            AvatarAnimator.cullingMode = AnimatorCullingMode.CullCompletely;
            DestroyGraphs();

            var layerList = _avatarDescriptor.baseAnimationLayers.ToList();

            layerList.AddRange(_avatarDescriptor.specialAnimationLayers);
            layerList.Sort(ModuleVrc3Styles.Data.LayerSort);

            _playableGraph = PlayableGraph.Create("Gesture Manager 3.1");
            var externalOutput = AnimationPlayableOutput.Create(_playableGraph, "Gesture Manager", AvatarAnimator);
            var playableMixer  = AnimationLayerMixerPlayable.Create(_playableGraph, layerList.Count + 1);

            externalOutput.SetSourcePlayable(playableMixer);

            _fromBlend.Clear();
            _avatarClips.Clear();
            _weightControllers      = new RadialWeightController[layerList.Count];
            _humanAnimatorPlayables = new AnimatorControllerPlayable[layerList.Count];

            for (var i = 0; i < layerList.Count; i++)
            {
                var vrcAnimLayer = layerList[i];
                var iGraph       = i + 1;

                if (vrcAnimLayer.animatorController)
                {
                    foreach (var clip in vrcAnimLayer.animatorController.animationClips)
                    {
                        _avatarClips.Add(clip);
                    }
                }

                var isFx     = vrcAnimLayer.type == VRCAvatarDescriptor.AnimLayerType.FX;
                var isAdd    = vrcAnimLayer.type == VRCAvatarDescriptor.AnimLayerType.Additive;
                var isPose   = vrcAnimLayer.type == VRCAvatarDescriptor.AnimLayerType.IKPose || vrcAnimLayer.type == VRCAvatarDescriptor.AnimLayerType.TPose;
                var isAction = vrcAnimLayer.type == VRCAvatarDescriptor.AnimLayerType.Sitting || vrcAnimLayer.type == VRCAvatarDescriptor.AnimLayerType.Action;
                var limit    = isPose || isAction;

                var controller = vrcAnimLayer.animatorController ? vrcAnimLayer.animatorController : ModuleVrc3Styles.Data.ControllerOf[vrcAnimLayer.type];
                var mask       = vrcAnimLayer.isDefault || isFx ? ModuleVrc3Styles.Data.MaskOf[vrcAnimLayer.type] : vrcAnimLayer.mask;

                if (!controller)
                {
                    continue;
                }

                _humanAnimatorPlayables[i] = AnimatorControllerPlayable.Create(_playableGraph, Vrc3ProxyOverride.OverrideController(controller));
                _weightControllers[i]      = new RadialWeightController(playableMixer, iGraph);
                for (var j = 0; j < _humanAnimatorPlayables[i].GetLayerCount(); j++)
                {
                    _humanAnimatorPlayables[i].SetLayerWeight(j, 1f);
                }

                playableMixer.ConnectInput(iGraph, _humanAnimatorPlayables[i], 0, 1);
                _fromBlend[vrcAnimLayer.type] = _weightControllers[i];

                if (limit)
                {
                    playableMixer.SetInputWeight(iGraph, 0f);
                }
                if (isAdd)
                {
                    playableMixer.SetLayerAdditive((uint)iGraph, true);
                }
                if (mask)
                {
                    playableMixer.SetLayerMaskFromAvatarMask((uint)iGraph, mask);
                }
            }

            _playableGraph.SetTimeUpdateMode(DirectorUpdateMode.GameTime);
            _playableGraph.Play();
            _playableGraph.Evaluate(0f);

            RadialMenu.Set(AvatarAnimator, Menu, Parameters, _humanAnimatorPlayables);
            RadialMenu.GetParam("TrackingType")?.InternalSet(1f);
            RadialMenu.GetParam("Upright")?.InternalSet(1f);
            RadialMenu.GetParam("Grounded")?.InternalSet(1f);
            RadialMenu.GetParam("VelocityX")?.Amplify(-7f);
            RadialMenu.GetParam("VelocityZ")?.Amplify(7f);
            RadialMenu.GetParam("AvatarVersion")?.InternalSet(3f);
            RadialMenu.GetParam("Seated")?.OnChange(OnSeatedModeChange);
        }
コード例 #26
0
 public void Evaluate(float deltaTime)
 {
     graph.Evaluate(deltaTime);
 }
コード例 #27
0
    public override void ProcessFrame(Playable playable, FrameData info, object playerData)
    {
        if (animator == null)
        {
            if (playerData is GameObject)
            {
                animator = ((GameObject)playerData).GetComponent <Animator>();
            }
            else if (playerData is Animator)
            {
                animator = playerData as Animator;
            }
        }

        if (animator == null)
        {
            return;
        }

        Vector3    defaultPosition = animator.gameObject.transform.position;
        Quaternion defaultRotation = animator.gameObject.transform.rotation;

        int inputCount = playable.GetInputCount();

        if (clips.Count <= 0)
        {
            mixer = AnimationPlayableUtilities.PlayMixer(animator, inputCount, out playableGraph);
        }

        Vector3    blendedPosition           = Vector3.zero;
        Quaternion blendedRotation           = new Quaternion(0f, 0f, 0f, 0f);
        RuntimeAnimatorController controller = animator ? animator.runtimeAnimatorController as RuntimeAnimatorController : null;

        for (int i = 0; i < inputCount; i++)
        {
            ScriptPlayable <AnimatorControlBehavior> playableInput = (ScriptPlayable <AnimatorControlBehavior>)playable.GetInput(i);
            AnimatorControlBehavior input = playableInput.GetBehaviour();

            float inputWeight    = playable.GetInputWeight(i);
            float normalisedTime = (float)(playableInput.GetTime() * input.inverseDuration);

            if (input.Clip == null || input.Clip.name != input.ClipName)
            {
                for (int j = 0; j < controller.animationClips.Length; j++)
                {
                    AnimationClip clip = controller.animationClips[j];

                    if (clip.name == input.ClipName)
                    {
                        input.Clip = clip;
                    }
                }
            }
            if (input.Clip)
            {
                if (clips.Count <= i)
                {
                    AnimationClipPlayable clipplay = AnimationClipPlayable.Create(playableGraph, input.Clip);
                    playableGraph.Connect(clipplay, 0, mixer, i);
                    clips.Add(clipplay);
                }
                mixer.SetInputWeight(i, inputWeight);
                clips[i].SetTime((double)normalisedTime * input.Clip.length);
                clips[i].SetSpeed(0);
            }
        }
        if (!Application.isPlaying)
        {
            playableGraph.Evaluate();
        }
    }
コード例 #28
0
        public static void DetectFootsteps(IMxMAnim a_mxmAnim, GameObject a_targetModel, MxMPreProcessData a_preProcessData,
                                           AnimationModule a_animModule, float a_groundingThreshold, float a_minSpacing, float a_minDuration, float a_maxFootSpeed)
        {
            if ((a_preProcessData == null && a_animModule == null) || a_mxmAnim == null)
            {
                return;
            }

            AnimationClip targetClip = a_mxmAnim.TargetClip;

            if (targetClip == null)
            {
                return;
            }

            if (a_targetModel == null)
            {
                if (a_preProcessData == null)
                {
                    a_targetModel = a_preProcessData.Prefab;
                }
                else if (a_animModule == null)
                {
                    a_targetModel = a_animModule.Prefab;
                }

                if (a_targetModel == null)
                {
                    Debug.LogError("MxM Footstep Detection - The MxMAnim you are trying to detect footsteps for has no target" +
                                   "model. This could occur if your target model is not set on the pre-processor, or your animation module" +
                                   "doesn't have a MotionMatch Config referenced.");
                    return;
                }
            }

            List <FootStepData> leftFootStepData      = new List <FootStepData>();
            List <Vector2>      leftFootStepPositions = new List <Vector2>();

            List <FootStepData> rightFootStepData      = new List <FootStepData>();
            List <Vector2>      rightFootStepPositions = new List <Vector2>();

            GameObject model = GameObject.Instantiate(a_targetModel);

            model.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);

            Animator animator = model.GetComponent <Animator>();

            if (animator == null)
            {
                animator = model.AddComponent <Animator>();
            }

            animator.applyRootMotion = true;
            animator.cullingMode     = AnimatorCullingMode.AlwaysAnimate;

            Transform leftToeJoint  = null;
            Transform rightToeJoint = null;

            bool getBonesByName = false;

            if (a_preProcessData != null)
            {
                getBonesByName = a_preProcessData.GetBonesByName;
            }
            else if (a_animModule != null)
            {
                getBonesByName = a_animModule.GetBonesByName;
            }

            if (!getBonesByName)
            {
                leftToeJoint  = animator.GetBoneTransform(HumanBodyBones.LeftToes);
                rightToeJoint = animator.GetBoneTransform(HumanBodyBones.RightToes);
            }
            else
            {
                //Get generic joints?
                Debug.LogWarning("Automatic detection of footsteps is not currently supported for generic rigs");
                return;
            }

            PlayableGraph playableGraph = PlayableGraph.Create();

            playableGraph.SetTimeUpdateMode(DirectorUpdateMode.Manual);
            var playableOutput = AnimationPlayableOutput.Create(playableGraph, "Animation", animator);
            var animationMixer = AnimationMixerPlayable.Create(playableGraph, 1, true);

            playableOutput.SetSourcePlayable(animationMixer);

            var clipPlayable = AnimationClipPlayable.Create(playableGraph, targetClip);

            animationMixer.ConnectInput(0, clipPlayable, 0);
            animationMixer.SetInputWeight(0, 1f);

            clipPlayable.SetTime(0.0);
            clipPlayable.SetTime(0.0);
            playableGraph.Evaluate(0f);
            model.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);

            const float SixtyHz = 1f / 60f;

            float leftFootLowestY  = leftToeJoint.position.y;
            float rightFootLowestY = rightToeJoint.position.y;

            for (float time = 0f; time <= targetClip.length; time += SixtyHz)
            {
                float leftFootY  = leftToeJoint.position.y;
                float rightFootY = rightToeJoint.position.y;

                if (leftFootY < leftFootLowestY)
                {
                    leftFootLowestY = leftFootY;
                }

                if (rightFootY < rightFootLowestY)
                {
                    rightFootLowestY = rightFootY;
                }

                playableGraph.Evaluate(SixtyHz);
            }

            clipPlayable.SetTime(0.0);
            clipPlayable.SetTime(0.0);
            playableGraph.Evaluate(0f);
            bool leftFootGrounded  = false;
            bool rightFootGrounded = false;

            float leftStepStartTime = 0f;
            float leftStepEndTime   = 0f;

            float rightStepStartTime = 0f;
            float rightStepEndTime   = 0f;

            model.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);

            float leftToeSpeed  = 0f;
            float rightToeSpeed = 0f;

            Vector3 leftToeLastPos  = leftToeJoint.position;
            Vector3 rightToeLastPos = rightToeJoint.position;

            for (float time = 0f; time <= targetClip.length; time += SixtyHz)
            {
                //Velocities
                leftToeSpeed    = Vector3.Distance(leftToeLastPos, leftToeJoint.position) / SixtyHz;
                rightToeSpeed   = Vector3.Distance(rightToeLastPos, rightToeJoint.position) / SixtyHz;
                leftToeLastPos  = leftToeJoint.position;
                rightToeLastPos = rightToeJoint.position;

                //LEFT FOOT
                float leftFootDif = leftToeJoint.position.y - leftFootLowestY;
                if (leftFootDif < a_groundingThreshold && leftToeSpeed < a_maxFootSpeed)
                {
                    if (leftFootGrounded == false)
                    {
                        leftStepStartTime = time;
                    }

                    leftFootGrounded = true;
                }
                else
                {
                    if (leftFootGrounded == true)
                    {
                        leftStepEndTime = time;

                        leftFootStepData.Add(new FootStepData());
                        leftFootStepPositions.Add(new Vector2(leftStepStartTime, leftStepEndTime));
                    }

                    leftFootGrounded = false;
                }

                //RIGHT FOOT
                float rightFootDif = rightToeJoint.position.y - rightFootLowestY;

                if (rightFootDif < a_groundingThreshold && rightToeSpeed < a_maxFootSpeed)
                {
                    if (rightFootGrounded == false)
                    {
                        rightStepStartTime = time;
                    }

                    rightFootGrounded = true;
                }
                else
                {
                    if (rightFootGrounded == true)
                    {
                        rightStepEndTime = time;

                        rightFootStepData.Add(new FootStepData());
                        rightFootStepPositions.Add(new Vector2(rightStepStartTime, rightStepEndTime));
                    }

                    rightFootGrounded = false;
                }

                playableGraph.Evaluate(SixtyHz);
            }

            List <TagTrackBase> genericTagTracks = a_mxmAnim.GenericTagTracks;
            FootStepTagTrack    leftFootTagTrack = genericTagTracks[0] as FootStepTagTrack;

            leftFootTagTrack.RemoveAllTags();

            for (int i = 0; i < leftFootStepPositions.Count; ++i)
            {
                Vector2 footStepPosition = leftFootStepPositions[i];

                //Combine footsteps that are too close to be real (This should be recursive)
                if (i + 1 < leftFootStepPositions.Count)
                {
                    for (int k = i + 1; k < leftFootStepPositions.Count; ++k)
                    {
                        Vector2 nextFootStepPos = leftFootStepPositions[k];

                        if (nextFootStepPos.x - footStepPosition.y < a_minSpacing)
                        {
                            footStepPosition.y = nextFootStepPos.y;
                            leftFootStepPositions.RemoveAt(k);
                            --k;
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                //Ignore footsteps that are too short to be real
                if (footStepPosition.y - footStepPosition.x < a_minDuration)
                {
                    continue;
                }

                leftFootTagTrack.AddTag(footStepPosition.x, footStepPosition.y);
            }

            FootStepTagTrack rightFootTagTrack = genericTagTracks[1] as FootStepTagTrack;

            rightFootTagTrack.RemoveAllTags();

            for (int i = 0; i < rightFootStepPositions.Count; ++i)
            {
                Vector3 footStepPosition = rightFootStepPositions[i];

                //Combine footsteps that are too close to be real (This should be recursive)
                if (i + 1 < rightFootStepPositions.Count)
                {
                    for (int k = i + 1; k < rightFootStepPositions.Count; ++k)
                    {
                        Vector2 nextFootStepPos = rightFootStepPositions[k];

                        if (nextFootStepPos.x - footStepPosition.y < a_minSpacing)
                        {
                            footStepPosition.y = nextFootStepPos.y;
                            rightFootStepPositions.RemoveAt(k);
                            --k;
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                //Ignore footsteps that are too short to be real
                if (footStepPosition.y - footStepPosition.x < a_minDuration)
                {
                    continue;
                }

                rightFootTagTrack.AddTag(footStepPosition.x, footStepPosition.y);
            }

            GameObject.DestroyImmediate(model);
        }
コード例 #29
0
        public void OnGUI(Rect r, GUIStyle background)
        {
            if (Event.current.type == EventType.Repaint)
            {
                #region TimeControl
                {
                    var beforePlaying = uTimeControl.playing;
#if UNITY_2019_1_OR_NEWER
                    var beforeCurrentTime = uTimeControl.currentTime;
                    uTimeControl.Update();
                    if (uTimeControl.playing && uTimeControl.currentTime < beforeCurrentTime)
                    {
                        loopCount++;
                    }
#else
                    uTimeControl.Update();
#endif
                    if (beforePlaying != uTimeControl.playing)
                    {
                        uTimeControl.playing = beforePlaying;
                    }
                }
                #endregion

                {
                    var clip = dg_get_m_SourcePreviewMotion(instance);
                    uTimeControl.loop      = true;
                    uTimeControl.startTime = 0f;
                    uTimeControl.stopTime  = clip.length;
                    dg_set_fps(instance, (int)clip.frameRate);
                    if (!clip.legacy && animator != null)
                    {
                        dg_set_ShowIKOnFeetButton(animator.isHuman && clip.isHumanMotion);

#if UNITY_2019_1_OR_NEWER
                        if (m_PlayableGraph.IsValid())
                        {
                            if (m_AnimationOffsetPlayable.IsValid())
                            {
                                m_UAnimationOffsetPlayable.SetPosition(m_AnimationOffsetPlayable, transformPoseSave.startPosition);
                                m_UAnimationOffsetPlayable.SetRotation(m_AnimationOffsetPlayable, transformPoseSave.startRotation);
                            }
                            m_AnimationClipPlayable.SetApplyFootIK(isIKOnFeet);
                            m_AnimationClipPlayable.SetTime(loopCount * clip.length + uTimeControl.currentTime);
#if VERYANIMATION_ANIMATIONRIGGING
                            if (m_RigBuilder != null && m_RigBuilder.enabled && m_RigBuilder.layers.Count > 0)
                            {
                                m_RigBuilder.UpdatePreviewGraph(m_PlayableGraph);
                            }
#endif
                            m_PlayableGraph.Evaluate();
                        }
#else
                        if (animator.runtimeAnimatorController != null)
                        {
                            AnimationClipSettings animationClipSettings = AnimationUtility.GetAnimationClipSettings(clip);
                            if (m_State != null)
                            {
                                m_State.iKOnFeet = isIKOnFeet;
                            }

                            var normalizedTime = animationClipSettings.stopTime - animationClipSettings.startTime == 0.0 ? 0.0f : (float)((uTimeControl.currentTime - animationClipSettings.startTime) / (animationClipSettings.stopTime - animationClipSettings.startTime));
                            animator.Play(0, 0, normalizedTime);
                            animator.Update(uTimeControl.deltaTime);
                        }
#endif
                    }
                    else if (animation != null)
                    {
                        dg_set_ShowIKOnFeetButton(false);
                        clip.SampleAnimation(gameObject, uTimeControl.currentTime);
                    }
                }
            }

            dg_DoAvatarPreview(r, background);

            if (animator.applyRootMotion && transformPoseSave != null)
            {
                var rect = r;
                rect.yMin  = rect.yMax - 40f;
                rect.yMax -= 15f;
                var invRot = Quaternion.Inverse(transformPoseSave.originalRotation);
                var pos    = invRot * (gameObject.transform.position - transformPoseSave.originalPosition);
                var rot    = (invRot * gameObject.transform.rotation).eulerAngles;
                EditorGUI.DropShadowLabel(rect, string.Format("Root Motion Position {0}\nRoot Motion Rotation {1}", pos, rot));
            }
        }