/// <summary> /// Create motion state. /// </summary> /// <param name="playableGraph">Playable graph.</param> /// <param name="clip">Animation clip.</param> /// <param name="isLoop">Animation is loop.</param> /// <param name="speed">Animation speed.</param> public static CubismMotionState CreateCubismMotionState(PlayableGraph playableGraph, AnimationClip clip, bool isLoop = true, float speed = 1.0f) { var ret = new CubismMotionState(); ret.Clip = clip; // Create animation clip mixer. ret.ClipMixer = AnimationMixerPlayable.Create(playableGraph, 2); ret.ClipMixer.SetSpeed(speed); // Connect AnimationClip Playable ret.ClipPlayable = AnimationClipPlayable.Create(playableGraph, ret.Clip); if (!isLoop) { ret.ClipPlayable.SetDuration(clip.length - 0.0001f); } ret.ClipMixer.ConnectInput(0, ret.ClipPlayable, 0); ret.ClipMixer.SetInputWeight(0, 1.0f); return(ret); }
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); } return(ApplyTrackOffset(graph, mixer, go, mode)); }
public static int PlayMixer_s(IntPtr l) { int result; try { Animator animator; LuaObject.checkType <Animator>(l, 1, out animator); int inputCount; LuaObject.checkType(l, 2, out inputCount); PlayableGraph playableGraph; AnimationMixerPlayable animationMixerPlayable = AnimationPlayableUtilities.PlayMixer(animator, inputCount, out playableGraph); LuaObject.pushValue(l, true); LuaObject.pushValue(l, animationMixerPlayable); LuaObject.pushValue(l, playableGraph); result = 3; } catch (Exception e) { result = LuaObject.error(l, e); } return(result); }
public Mixer(PlayableGraph playableGraph, ref AnimationLayerMixerPlayable animationLayerMixerPlayable, AnimationCurve blendingCurve, List <AnimationClip> animationClips) { animationMixerPlayable = AnimationMixerPlayable.Create(playableGraph, animationClips.Count, true); animationLayerMixerPlayable.AddInput(animationMixerPlayable, 0, 1); this.blendingCurve = blendingCurve; for (var i = 0; i < animationClips.Count; i++) { var animationClipPlayable = AnimationClipPlayable.Create(playableGraph, animationClips[i]); animationMixerPlayable.ConnectInput(i, animationClipPlayable, 0); animationClipPlayables.Add(animationClipPlayable); index.Add(animationClips[i].name, i); times.Add(animationClips[i].name, animationClips[i].length); } Observable .EveryUpdate() .Subscribe(_ => { for (var i = 0; i < animationClipPlayables.Count; i++) { animationMixerPlayable.SetInputWeight(i, 0); } if (string.IsNullOrEmpty(prev)) { animationMixerPlayable.SetInputWeight(index[next], 1.0f); } else { var dt = Time.timeSinceLevelLoad - currentTime; var ratio = blendingCurve.Evaluate(dt); animationMixerPlayable.SetInputWeight(index[prev], 1 - ratio); animationMixerPlayable.SetInputWeight(index[next], ratio); } }); }
// Use this for initialization void Start() { playableGraph = PlayableGraph.Create("My Graph"); playableGraph.SetTimeUpdateMode(DirectorUpdateMode.GameTime); var playableOutput = AnimationPlayableOutput.Create(playableGraph, "animation output", GetComponent <Animator>()); clipPlayable = AnimationClipPlayable.Create(playableGraph, clip); clipPlayable2 = AnimationClipPlayable.Create(playableGraph, clip2); mixer = AnimationMixerPlayable.Create(playableGraph, 2); playableOutput.SetSourcePlayable(mixer, 0); playableGraph.Connect(clipPlayable2, 0, mixer, 0); playableGraph.Connect(clipPlayable, 0, mixer, 1); //mixer.AddInput(clipPlayable, 0); //mixer.AddInput(clipPlayable2, 0); var p = Playable.Create(playableGraph); // Plays the Graph. playableGraph.Play(); }
public static void SetPreviewObject(GameObject a_previewObj) { if (a_previewObj == null) { Debug.LogError("Trying to set preview object in the preview " + "scene but the passed object is null. Aborting"); return; } if (PreviewObject != null) { PlayableGraph.Destroy(); GameObject.DestroyImmediate(PreviewObject); } PreviewObject = GameObject.Instantiate(a_previewObj); PreviewObject.hideFlags = HideFlags.DontSaveInEditor; PreviewObject.name = "PreviewModel_MxM"; PreviewAnimator = PreviewObject.GetComponent <Animator>(); if (PreviewAnimator == null) { PreviewAnimator = PreviewObject.AddComponent <Animator>(); } PlayableGraph = PlayableGraph.Create("PreviewCharacter"); PlayableGraph.SetTimeUpdateMode(DirectorUpdateMode.Manual); var playableOutput = AnimationPlayableOutput.Create(PlayableGraph, "Animation", PreviewAnimator); Mixer = AnimationMixerPlayable.Create(PlayableGraph, 1, true); playableOutput.SetSourcePlayable(Mixer); Mixer.SetInputWeight(0, 1f); }
private void Start() { // Creates the graph, the mixer and binds them to the Animator. playableGraph = PlayableGraph.Create(); var playableOutput = AnimationPlayableOutput.Create(playableGraph, "Animation", GetComponent <Animator>()); mixerPlayable = AnimationMixerPlayable.Create(playableGraph, 2); playableOutput.SetSourcePlayable(mixerPlayable); // Creates AnimationClipPlayable and connects them to the mixer. var clipPlayable0 = AnimationClipPlayable.Create(playableGraph, clip0); var clipPlayable1 = AnimationClipPlayable.Create(playableGraph, clip1); playableGraph.Connect(clipPlayable0, 0, mixerPlayable, 0); playableGraph.Connect(clipPlayable1, 0, mixerPlayable, 1); // Plays the Graph. playableGraph.Play(); }
// Use this for initialization void Start() { // Create the PlayableGraph. m_Graph = PlayableGraph.Create(); // Add an AnimationPlayableOutput to the graph. var animOutput = AnimationPlayableOutput.Create(m_Graph, "AnimationOutput", GetComponent <Animator>()); // Add an AnimationMixerPlayable to the graph. var mixerPlayable = AnimationMixerPlayable.Create(m_Graph, 2, false); // Add two AnimationClipPlayable to the graph. var clipPlayableA = AnimationClipPlayable.Create(m_Graph, clipA); var clipPlayableB = AnimationClipPlayable.Create(m_Graph, clipB); // Add a custom PlayableBehaviour to the graph. // This behavior will change the weights of the mixer dynamically. var blenderPlayable = ScriptPlayable <BlenderPlayableBehaviour> .Create(m_Graph, 1); blenderPlayable.GetBehaviour().mixerPlayable = mixerPlayable; // Create the topology, connect the AnimationClipPlayable to the // AnimationMixerPlayable. Also add the BlenderPlayableBehaviour. m_Graph.Connect(clipPlayableA, 0, mixerPlayable, 0); m_Graph.Connect(clipPlayableB, 0, mixerPlayable, 1); m_Graph.Connect(mixerPlayable, 0, blenderPlayable, 0); // Use the ScriptPlayable as the source for the AnimationPlayableOutput. // Since it's a ScriptPlayable, also set the source input port to make the // passthrough to the AnimationMixerPlayable. animOutput.SetSourcePlayable(blenderPlayable); animOutput.SetSourceInputPort(0); // Play the graph. m_Graph.Play(); }
public Instance(EntityManager entityManager, Entity owner, PlayableGraph graph, Entity animStateOwner, AnimGraph_InAir settings) { m_settings = settings; m_EntityManager = entityManager; m_Owner = owner; m_AnimStateOwner = animStateOwner; GameDebug.Assert(entityManager.HasComponent <Character>(m_AnimStateOwner), "Owner has no Character component"); m_character = entityManager.GetComponentObject <Character>(m_AnimStateOwner); m_mainMixer = AnimationMixerPlayable.Create(graph); m_animInAir = AnimationClipPlayable.Create(graph, settings.animInAir); m_animInAir.Play(); m_animInAir.SetApplyFootIK(false); inAirPort = m_mainMixer.AddInput(m_animInAir, 0); m_animLandAntic = AnimationClipPlayable.Create(graph, settings.animLandAntic); m_animInAir.Play(); m_animLandAntic.SetApplyFootIK(false); landAnticPort = m_mainMixer.AddInput(m_animLandAntic, 0); m_layerMixer = AnimationLayerMixerPlayable.Create(graph); var port = m_layerMixer.AddInput(m_mainMixer, 0); m_layerMixer.SetInputWeight(port, 1); // Aim if (settings.animAimDownToUp != null) { m_aimHandler = new AimVerticalHandler(m_layerMixer, settings.animAimDownToUp); } // Actions m_actionAnimationHandler = new ActionAnimationHandler(m_layerMixer, settings.actionAnimations); }
Playable CompileTrackPlayable(PlayableGraph graph, AnimationTrack 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); } } if (!track.AnimatesRootTransform()) { return(mixer); } return(ApplyTrackOffset(graph, mixer, go, mode)); }
void Awake() { var animator = GetComponent <Animator>(); _playableGraph = PlayableGraph.Create(); _playableGraph.SetTimeUpdateMode(DirectorUpdateMode.Manual); playableOutput = AnimationPlayableOutput.Create(_playableGraph, "Animation", animator); mixerPlayable = AnimationMixerPlayable.Create(_playableGraph, 1); if (AnimationPlayLayers.Length > 1) {//如果有多层混合 layerMixerPlayable = AnimationLayerMixerPlayable.Create(_playableGraph, 1); _playableGraph.Connect(mixerPlayable, 0, layerMixerPlayable, 0); playableOutput.SetSourcePlayable(layerMixerPlayable); layerMixerPlayable.SetInputWeight(0, 1f); } else { playableOutput.SetSourcePlayable(mixerPlayable); } _playableGraph.Play(); }
/************************************************************************************************************************/ /// <summary>Creates and assigns the <see cref="AnimationMixerPlayable"/> managed by this layer.</summary> protected override void CreatePlayable(out Playable playable) => playable = AnimationMixerPlayable.Create(Root._Graph);
protected virtual Playable CreateAnimationPlayable(PlayableGraph graph, GameObject owner) { return(AnimationMixerPlayable.Create(graph)); }
AnimationClipPlayable CreateAimPlayable(PlayableGraph graph, AnimationClip clip, AnimationMixerPlayable mixer, AimMixerPort mixerPort) { AnimationClipPlayable playable = AnimationClipPlayable.Create(graph, clip); playable.Pause(); playable.SetDuration(clip.length); graph.Connect(playable, 0, mixer, (int)mixerPort); return(playable); }
static AnimationClipPlayable CreateTurnPlayable(PlayableGraph graph, AnimationClip clip, AnimationMixerPlayable mixer, LocoMixerPort mixerPort) { AnimationClipPlayable playable = AnimationClipPlayable.Create(graph, clip); playable.SetApplyFootIK(true); playable.Pause(); playable.SetDuration(clip.length); graph.Connect(playable, 0, mixer, (int)mixerPort); mixer.SetInputWeight((int)mixerPort, 0.0f); return(playable); }
//private float mainLoopTriggerTime = 1.0f; // Time over which a main loop is interpolated with itself. [TODO] Should be made relative to main clip duration, as it will behave strangely for small durations. /* * Awake */ private void Awake() { animator = GetComponent <Animator>(); goToEmotionList = new List <GoToEmotionEntry>(); currentlyPlayingClips = new List <IFAClip>(); // Create Playable Graph playableGraph = PlayableGraph.Create("ClairePlayableGraph"); playableGraph.SetTimeUpdateMode(DirectorUpdateMode.GameTime); var playableOutput = AnimationPlayableOutput.Create(playableGraph, "Animation", animator); // Create Top Level Layer Mixer AnimationLayerMixerPlayable mixerLayerPlayable = AnimationLayerMixerPlayable.Create(playableGraph, 2); playableOutput.SetSourcePlayable(mixerLayerPlayable); // Create an Emotion Mixer int numberOfClips = 0; for (int i = 0; i < emotionObjects.Count; i++) { for (int j = 0; j < emotionObjects[i].animationGroupList.Count; j++) { if (emotionObjects[i].animationGroupList[j].main) { numberOfClips++; } if (emotionObjects[i].animationGroupList[j].transitionIn) { numberOfClips++; } } } mixerEmotionPlayable = AnimationMixerPlayable.Create(playableGraph, numberOfClips); // Second argument sets number of inputs for clips to connect. // Wrap AnimController runtimeAnimController = animator.runtimeAnimatorController; var runtimeAnimControllerPlayable = AnimatorControllerPlayable.Create(playableGraph, runtimeAnimController); // Connect to Top Level Layer Mixer playableGraph.Connect(runtimeAnimControllerPlayable, 0, mixerLayerPlayable, 0); playableGraph.Connect(mixerEmotionPlayable, 0, mixerLayerPlayable, 1); mixerLayerPlayable.SetInputWeight(0, 1.0f); mixerLayerPlayable.SetInputWeight(1, 1.0f); mixerLayerPlayable.SetLayerMaskFromAvatarMask(1, headMask); //mixerLayerPlayable.SetLayerAdditive(1, true); // 1. Wraps each clip in a playable and connects them to the emotion mixer // 2. Also populate "playablesDict" to later be able to access the AnimationClipPlayables by their Index in the emotionMixer // 3. Main animations are not connected directly: Instead another MixerPlayable (mainMixer) is connected. // The main playable is copied and both the original and copy are connected to the new MainMixer. // This is to allow for smoothly looping main animations playablesDict = new Dictionary <string, int>(); // String: "Name"+"Index of Emotion Variation"; Int: Index in mixerEmotionPlayable int playablesCount = 0; int tempPlayablesCount = 0; for (int i = 0; i < emotionObjects.Count; i++) { tempPlayablesCount = playablesCount; for (int j = 0; j < emotionObjects[i].animationGroupList.Count; j++) { if (emotionObjects[i].animationGroupList[j].main) { playablesDict.Add(emotionObjects[i].name + j, playablesCount); AnimationMixerPlayable mainMixer = AnimationMixerPlayable.Create(playableGraph, 2); //var mainMixerBehaviour = ScriptPlayable<IFAMainMixerBehaviour>.Create(playableGraph, 1); // Throwing a behaviour controller between emotionMixer and mainMixer //mainMixerBehaviour.GetBehaviour().constructor2(mainMixer, mainLoopTriggerTime, mainMixerMainIndex, mainMixerCopyIndex); // To automize looping of the main clip //playableGraph.Connect(mainMixerBehaviour, 0, mixerEmotionPlayable, playablesCount); playableGraph.Connect(mainMixer, 0, mixerEmotionPlayable, playablesCount); playablesCount++; AnimationClipPlayable main = AnimationClipPlayable.Create(playableGraph, emotionObjects[i].animationGroupList[j].main); playableGraph.Connect(main, 0, mainMixer, mainMixerMainIndex); mainMixer.SetInputWeight(mainMixerMainIndex, 1.0f); // Set first clip to active main.SetDuration(emotionObjects[i].animationGroupList[j].main.length); AnimationClipPlayable mainCopy = AnimationClipPlayable.Create(playableGraph, emotionObjects[i].animationGroupList[j].main); playableGraph.Connect(mainCopy, 0, mainMixer, mainMixerCopyIndex); mainMixer.SetInputWeight(mainMixerCopyIndex, 0.1f); // Set second clip to inactive mainCopy.SetDuration(emotionObjects[i].animationGroupList[j].main.length); } if (emotionObjects[i].animationGroupList[j].transitionIn) { playablesDict.Add(emotionObjects[i].name + "TransitionIn" + j, playablesCount); AnimationClipPlayable transition = AnimationClipPlayable.Create(playableGraph, emotionObjects[i].animationGroupList[j].transitionIn); playableGraph.Connect(transition, 0, mixerEmotionPlayable, playablesCount); transition.SetDuration(emotionObjects[i].animationGroupList[j].transitionIn.length); playablesCount++; } } // If an emotion has any animationClips, it can be transitioned to if (tempPlayablesCount < playablesCount) { goToEmotionList.Add(new GoToEmotionEntry(emotionObjects[i].name, false, i)); } } // Unrelated to Playables; For Display Purposes if (GOWithDrawGraphOnImage) { drawGraphOnImage = GOWithDrawGraphOnImage.GetComponent <DrawGraphOnImage>(); } }
public CharacterAnimGraph_3PStand(EntityManager entityManager, Entity owner, PlayableGraph graph, Entity animStateOwner, AnimGraph_Stand template) { if (s_Instances == null) { s_Instances = new List <CharacterAnimGraph_3PStand>(16); } s_Instances.Add(this); m_template = template; m_EntityManager = entityManager; m_Owner = owner; m_AnimStateOwner = animStateOwner; GameDebug.Assert(entityManager.HasComponent <Animator>(owner), "Owner has no Animator component"); var animator = entityManager.GetComponentObject <Animator>(owner); GameDebug.Assert(entityManager.HasComponent <Skeleton>(owner), "Owner has no Skeleton component"); var skeleton = entityManager.GetComponentObject <Skeleton>(owner); GameDebug.Assert(entityManager.HasComponent <CharPredictedStateData>(m_AnimStateOwner), "Owner has no CharPredictedState component"); var leftToes = skeleton.bones[skeleton.GetBoneIndex(template.leftToeBone.GetHashCode())]; var rightToes = skeleton.bones[skeleton.GetBoneIndex(template.rightToeBone.GetHashCode())]; // Locomotion mixer and loco animation m_locomotionMixer = AnimationMixerPlayable.Create(graph, (int)LocoMixerPort.Count); // Idle m_animIdle = AnimationClipPlayable.Create(graph, template.animIdle); m_animIdle.SetApplyFootIK(true); graph.Connect(m_animIdle, 0, m_locomotionMixer, (int)LocoMixerPort.Idle); m_locomotionMixer.SetInputWeight((int)LocoMixerPort.Idle, 1.0f); // Turns and trasitions m_animTurnL = CreateTurnAnim(graph, template.animTurnL, LocoMixerPort.TurnL); m_animTurnR = CreateTurnAnim(graph, template.animTurnR, LocoMixerPort.TurnR); var ports = new int[] { (int)LocoMixerPort.Idle, (int)LocoMixerPort.TurnL, (int)LocoMixerPort.TurnR }; m_Transition = new SimpleTranstion <AnimationMixerPlayable>(m_locomotionMixer, ports); // Foot IK if (m_template.animTurnL.events.Length != 0) { m_LeftTurnFootFalls = ExtractFootFalls(m_template.animTurnL); m_RightTurnFootFalls = ExtractFootFalls(m_template.animTurnR); } var ikJob = new FootIkJob { settings = m_template.footIK, leftToe = animator.BindStreamTransform(leftToes), rightToe = animator.BindStreamTransform(rightToes) }; m_footIk = AnimationScriptPlayable.Create(graph, ikJob, 1); graph.Connect(m_locomotionMixer, 0, m_footIk, 0); m_footIk.SetInputWeight(0, 1f); m_defaultLayer = LayerMask.NameToLayer("Default"); m_playerLayer = LayerMask.NameToLayer("collision_player"); m_platformLayer = LayerMask.NameToLayer("Platform"); m_mask = 1 << m_defaultLayer | 1 << m_playerLayer | 1 << m_platformLayer; // Aim and Aim mixer m_aimMixer = AnimationMixerPlayable.Create(graph, (int)AimMixerPort.Count, true); m_animAimLeft = CreateAimAnim(graph, template.animAimLeft, AimMixerPort.AimLeft); m_animAimMid = CreateAimAnim(graph, template.animAimMid, AimMixerPort.AimMid); m_animAimRight = CreateAimAnim(graph, template.animAimRight, AimMixerPort.AimRight); // Setup other additive mixer m_additiveMixer = AnimationLayerMixerPlayable.Create(graph); var locoMixerPort = m_additiveMixer.AddInput(m_footIk, 0); m_additiveMixer.SetInputWeight(locoMixerPort, 1); var aimMixerPort = m_additiveMixer.AddInput(m_aimMixer, 0); m_additiveMixer.SetInputWeight(aimMixerPort, 1); m_additiveMixer.SetLayerAdditive((uint)aimMixerPort, true); // Actions m_actionAnimationHandler = new ActionAnimationHandler(m_additiveMixer, template.actionAnimations); m_ReloadActionAnimation = m_actionAnimationHandler.GetActionAnimation(CharPredictedStateData.Action.Reloading); // Shoot pose m_animShootPose = AnimationClipPlayable.Create(graph, template.animShootPose); m_animShootPose.SetApplyFootIK(false); m_animShootPose.SetDuration(template.animShootPose.length); m_animShootPose.Pause(); m_ShootPosePort = m_additiveMixer.AddInput(m_animShootPose, 0); m_additiveMixer.SetInputWeight(m_ShootPosePort, 0.0f); m_additiveMixer.SetLayerAdditive((uint)m_ShootPosePort, true); }
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 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]); } } }
public static ReductionSyntax <PlayableSyntax> Add( this PlayableGraph graph, ref AnimationMixerPlayable playable, int count) { playable = AnimationMixerPlayable.Create(graph, count); return(PlayableSyntax.Create(graph, playable)); }
void AttachMixerToAnimationPlayableOutput(AnimationMixerPlayable mixer, PlayableGraph g) { var playableOutput = g.GetOutput(0); playableOutput.SetSourcePlayable(mixerPlayable); }
public BlendedAnimationLayer(PlayableGraph PlayableGraph, AnimationLayerMixerPlayable parentAnimationLayerMixerPlayable, int layerId, BlendedAnimationInput BlendedAnimationInput, Func <float> InputWeightProvider) : base(layerId, parentAnimationLayerMixerPlayable) { this.BlendedAnimationInput = BlendedAnimationInput; this.BlendedAnimationClips = BlendedAnimationInput.BlendedAnimationClips.ConvertAll(i => i.ToBlendedAnimationClip()); //create a playable mixer this.AnimationMixerPlayable = AnimationMixerPlayable.Create(PlayableGraph); foreach (var blendedAnimationClip in this.BlendedAnimationClips) { var animationClipPlayable = AnimationClipPlayable.Create(PlayableGraph, blendedAnimationClip.AnimationClip); animationClipPlayable.SetApplyFootIK(false); animationClipPlayable.SetApplyPlayableIK(false); blendedAnimationClip.InputHandler = PlayableExtensions.AddInput(this.AnimationMixerPlayable, animationClipPlayable, 0); PlayableExtensions.Play(animationClipPlayable); blendedAnimationClip.AnimationClipPlayable = animationClipPlayable; } //calculate blendings for (var i = 0; i < this.BlendedAnimationClips.Count; i++) { if (i == 0) { this.BlendedAnimationClips[i].Blending = this.BlendedAnimationClips[i].Blending.SetWeightTimePoints( AnimationWeightStartIncreasingTime: 0f, AnimationWeightEndIncreasingTime: this.BlendedAnimationClips[i].WeightTime, AnimationWeightStartDecreasingTime: this.BlendedAnimationClips[i].WeightTime, AnimationWeightEndDecreasingTime: this.BlendedAnimationClips[i + 1].WeightTime ); } else if (i == this.BlendedAnimationClips.Count - 1) { this.BlendedAnimationClips[i].Blending = this.BlendedAnimationClips[i].Blending.SetWeightTimePoints( AnimationWeightStartIncreasingTime: this.BlendedAnimationClips[i - 1].WeightTime, AnimationWeightEndIncreasingTime: this.BlendedAnimationClips[i].WeightTime, AnimationWeightStartDecreasingTime: this.BlendedAnimationClips[i].WeightTime, AnimationWeightEndDecreasingTime: 1f ); } else { this.BlendedAnimationClips[i].Blending = this.BlendedAnimationClips[i].Blending.SetWeightTimePoints( AnimationWeightStartIncreasingTime: this.BlendedAnimationClips[i - 1].WeightTime, AnimationWeightEndIncreasingTime: this.BlendedAnimationClips[i].WeightTime, AnimationWeightStartDecreasingTime: this.BlendedAnimationClips[i].WeightTime, AnimationWeightEndDecreasingTime: this.BlendedAnimationClips[i + 1].WeightTime ); } } this.Inputhandler = PlayableExtensions.AddInput(parentAnimationLayerMixerPlayable, this.AnimationMixerPlayable, 0); parentAnimationLayerMixerPlayable.SetLayerAdditive((uint)layerId, BlendedAnimationInput.IsAdditive); if (BlendedAnimationInput.AvatarMask != null) { parentAnimationLayerMixerPlayable.SetLayerMaskFromAvatarMask((uint)layerId, BlendedAnimationInput.AvatarMask); } if (InputWeightProvider != null) { this.inputWeightProvider = InputWeightProvider; } }
public AnimationMixerPlayable AddMixerPlayable() => default; // 0x00A06B90-0x00A06DB0 public void SetMixerPlayable_OutputWeight(AnimationMixerPlayable mixerPlayable, float weight) { } // 0x00A06DB0-0x00A06E30
private void UpdateStates(float deltaTime) { mustUpdateWeights.Clear(); totalWeights.Clear(); for (int i = 0; i < m_States.Count; i++) { StateInfo state = m_States[i]; //Skip deleted states if (state == null) { continue; } //Update crossfade weight if (state.fading) { state.SetWeight(Mathf.MoveTowards(state.weight, state.targetWeight, state.fadeSpeed * deltaTime)); if (Mathf.Approximately(state.weight, state.targetWeight)) { state.ForceWeight(state.targetWeight); if (state.weight == 0f) { state.Stop(); } } } if (state.layerDirty >= 0) { AnimationMixerPlayable lastMixer = GetMixer(state.layerDirty); if (!lastMixer.Equals(AnimationMixerPlayable.Null)) { if (lastMixer.GetInput(state.indexAtLayer).Equals(state.playable)) { graph.Disconnect(lastMixer, state.indexAtLayer); } } AnimationMixerPlayable mixer = AddMixerWhenNotExist(state.layer); if (mixer.Equals(AnimationMixerPlayable.Null)) { throw new Exception("Can not get mixer at layer:" + state.layer); } state.indexAtLayer = m_States.GetAvailableIndexAtLayer(state.layer, state); int stateCountByLayer = m_States.GetCountByLayer(state.layer); if (stateCountByLayer > mixer.GetInputCount()) { mixer.SetInputCount(stateCountByLayer); } graph.Connect(state.playable, 0, mixer, state.indexAtLayer); } if (state.enabledDirty) { if (state.enabled) { state.Play(); } else { state.Pause(); } if (!keepStoppedPlayablesConnected) { AnimationMixerPlayable mixer = GetMixer(state.layer); if (mixer.Equals(AnimationMixerPlayable.Null)) { throw new Exception("Can not get mixer at layer:" + state.layer); } Playable input = mixer.GetInput(state.indexAtLayer); //if state is disabled but the corresponding input is connected, disconnect it if (input.IsValid() && !state.enabled) { DisconnectInput(i); } else if (state.enabled && !input.IsValid()) { ConnectInput(state.index); } } } if (state.enabled && state.wrapMode == WrapMode.Once) { bool stateIsDone = state.isDone; float speed = state.speed; float time = state.GetTime(); float duration = state.playableDuration; stateIsDone |= speed < 0f && time < 0f; stateIsDone |= speed >= 0f && time >= duration; if (stateIsDone) { state.Stop(); state.Disable(); if (!keepStoppedPlayablesConnected) { DisconnectInput(state.index); } } } if (!totalWeights.ContainsKey(state.layer)) { totalWeights.Add(state.layer, 0.0f); } if (!mustUpdateWeights.ContainsKey(state.layer)) { mustUpdateWeights.Add(state.layer, false); } totalWeights[state.layer] += state.weight; if (state.weightDirty) { mustUpdateWeights[state.layer] = true; } state.ResetDirtyFlags(); } var e = mustUpdateWeights.GetEnumerator(); while (e.MoveNext()) { if (e.Current.Value) { float totalWeight = totalWeights[e.Current.Key]; bool hasAnyWeight = totalWeight > 0.0f; for (int i = 0; i < m_States.Count; i++) { StateInfo state = m_States[i]; if (state == null || state.layer != e.Current.Key) { continue; } AnimationMixerPlayable mixer = GetMixer(state.layer); if (mixer.Equals(AnimationMixerPlayable.Null)) { throw new Exception("Can not get mixer at layer:" + state.layer); } float weight = hasAnyWeight ? state.weight / totalWeight : 0.0f; mixer.SetInputWeight(state.indexAtLayer, weight); } } } mustUpdateWeights.Clear(); totalWeights.Clear(); }
//Create playable tree void CreateAndPlayTree() { #if UNITY_2017_1_OR_NEWER var clipActions = actions.OfType <PlayAnimatorClip>().ToList(); var inputCount = 1 + clipActions.Count; ports = new Dictionary <PlayAnimatorClip, int>(); graph = PlayableGraph.Create(); mixerPlayable = AnimationMixerPlayable.Create(graph, inputCount, true); mixerPlayable.SetInputWeight(0, 1f); baseClipPlayable = AnimationClipPlayable.Create(graph, baseAnimationClip); baseClipPlayable.SetPlayState(PlayState.Paused); graph.Connect(baseClipPlayable, 0, mixerPlayable, 0); var index = 1; //0 is baseclip foreach (var playAnimClip in clipActions) { var clipPlayable = AnimationClipPlayable.Create(graph, playAnimClip.animationClip); graph.Connect(clipPlayable, 0, mixerPlayable, index); mixerPlayable.SetInputWeight(index, 0f); ports[playAnimClip] = index; clipPlayable.SetPlayState(PlayState.Paused); index++; } animationOutput = AnimationPlayableOutput.Create(graph, "Animation", animator); animationOutput.SetSourcePlayable(mixerPlayable); mixerPlayable.SetPlayState(PlayState.Paused); graph.Play(); #elif UNITY_5_6_OR_NEWER var clipActions = actions.OfType <PlayAnimatorClip>().ToList(); var inputCount = 1 + clipActions.Count; ports = new Dictionary <PlayAnimatorClip, int>(); graph = PlayableGraph.CreateGraph(); mixerPlayableHandle = graph.CreateAnimationMixerPlayable(inputCount, true); mixerPlayableHandle.SetInputWeight(0, 1f); baseClipPlayableHandle = graph.CreateAnimationClipPlayable(baseAnimationClip); baseClipPlayableHandle.playState = PlayState.Paused; graph.Connect(baseClipPlayableHandle, 0, mixerPlayableHandle, 0); var index = 1; //0 is baseclip foreach (var playAnimClip in clipActions) { var clipPlayableHandle = graph.CreateAnimationClipPlayable(playAnimClip.animationClip); graph.Connect(clipPlayableHandle, 0, mixerPlayableHandle, index); mixerPlayableHandle.SetInputWeight(index, 0f); ports[playAnimClip] = index; clipPlayableHandle.playState = PlayState.Paused; index++; } animationOutput = graph.CreateAnimationOutput("Animation", animator); animationOutput.sourcePlayable = mixerPlayableHandle; mixerPlayableHandle.playState = PlayState.Paused; graph.Play(); #else ports = new Dictionary <PlayAnimatorClip, int>(); mixerPlayable = AnimationMixerPlayable.Create(); var basePlayableClip = AnimationClipPlayable.Create(baseAnimationClip); basePlayableClip.state = PlayState.Paused; mixerPlayable.AddInput(basePlayableClip); foreach (var playAnimClip in actions.OfType <PlayAnimatorClip>()) { var playableClip = AnimationClipPlayable.Create(playAnimClip.animationClip); playableClip.state = PlayState.Paused; var index = mixerPlayable.AddInput(playableClip); mixerPlayable.SetInputWeight(index, 0f); ports[playAnimClip] = index; } animator.SetTimeUpdateMode(DirectorUpdateMode.Manual); animator.Play(mixerPlayable); mixerPlayable.state = PlayState.Paused; #endif // GraphVisualizerClient.Show(graph, animator.name); }
public override void OnCreate(SequenceBehaviour sequence, IReadOnlyList <Blackboard> blackboards) { m_Mixer = ((PlayableSequence)sequence).ChildMixer; }
public void InitializeSelf(PlayableGraph graph) { containingGraph = graph; if (states.Count == 0) { stateMixer = AnimationMixerPlayable.Create(graph, 0, false); return; } foreach (var transition in transitions) { transition.FetchStates(states); } runtimePlayables = new Playable[states.Count]; stateMixer = AnimationMixerPlayable.Create(graph, states.Count, false); stateMixer.SetInputWeight(0, 1f); currentPlayedState = 0; // Add the statess to the graph for (int i = 0; i < states.Count; i++) { var state = states[i]; stateNameToIdx[state.Name] = i; var playable = state.GeneratePlayable(graph, varTo1DBlendControllers, varTo2DBlendControllers, blendVars); runtimePlayables[i] = playable; graph.Connect(playable, 0, stateMixer, i); } activeWhenBlendStarted = new List <bool>(); valueWhenBlendStarted = new List <float>(); for (int i = 0; i < states.Count; i++) { activeWhenBlendStarted.Add(false); valueWhenBlendStarted.Add(0f); } transitionLookup = new int[states.Count, states.Count]; for (int i = 0; i < states.Count; i++) { for (int j = 0; j < states.Count; j++) { transitionLookup[i, j] = -1; } } for (var i = 0; i < transitions.Count; i++) { var transition = transitions[i]; var fromState = states.IndexOf(transition.FromState); var toState = states.IndexOf(transition.ToState); if (fromState == -1 || toState == -1) { //TODO: fixme } else { if (transitionLookup[fromState, toState] != -1) { Debug.LogWarning("Found two transitions from " + states[fromState] + " to " + states[toState]); } transitionLookup[fromState, toState] = i; } } }
public Instance(EntityManager entityManager, Entity owner, PlayableGraph graph, AnimGraph_StateSelector settings) { m_settings = settings; m_graph = graph; m_EntityManager = entityManager; m_Owner = owner; animStateMixer = AnimationMixerPlayable.Create(m_graph, 0, true); m_RootPlayable = animStateMixer; // Animation states animStates = new AnimationControllerEntry[(int)CharacterAnimationState.NumStates]; // Instantiate controllers. We only create one of each type even though it might be used in multiple animation states var controllers = new Dictionary <AnimGraphAsset, IAnimGraphInstance>(); var controllerPorts = new Dictionary <IAnimGraphInstance, int>(); var stateTransitionPorts = new List <int>(); var transitionTimes = new Dictionary <IAnimGraphInstance, float[]>(); foreach (var controllderDef in m_settings.controllers) { if (controllderDef.template == null) { continue; } if (controllers.ContainsKey(controllderDef.template)) { continue; } var controller = controllderDef.template.Instatiate(entityManager, owner, m_graph); controllers.Add(controllderDef.template, controller); var outputPlayable = Playable.Null; var outputPort = 0; controller.GetPlayableOutput(0, ref outputPlayable, ref outputPort); var port = animStateMixer.AddInput(outputPlayable, outputPort); controllerPorts.Add(controller, port); stateTransitionPorts.Add(port); var times = new float[(int)CharacterAnimationState.NumStates]; for (var i = 0; i < (int)CharacterAnimationState.NumStates; i++) { times[i] = controllderDef.transitionTime; } for (var i = 0; i < controllderDef.customTransitions.Length; i++) { var sourceStateIndex = (int)controllderDef.customTransitions[i].sourceState; var time = controllderDef.customTransitions[i].transtionTime; times[sourceStateIndex] = time; } transitionTimes.Add(controller, times); } // Setup states specifically defined foreach (var controllderDef in m_settings.controllers) { var animState = controllderDef.animationState; if (animStates[(int)animState].controller != null) { GameDebug.LogWarning("Animation state already registered"); continue; } var controller = controllers[controllderDef.template]; animStates[(int)animState].controller = controller; animStates[(int)animState].animStateUpdater = controller as IGraphState; animStates[(int)animState].port = controllerPorts[controller]; animStates[(int)animState].transitionTimes = transitionTimes[controller]; } m_StateTranstion = new SimpleTranstion <AnimationMixerPlayable>(animStateMixer, stateTransitionPorts.ToArray()); }
/// <summary> /// 初期化Playableに必要な物の作成 /// </summary> public void Initialize(int maxBlendNum = 2) { playableGraph = PlayableGraph.Create(); mixer = AnimationMixerPlayable.Create(playableGraph, maxBlendNum, true); }
protected override void CreateMixerPlayable() { mMixerPlayable = AnimationMixerPlayable.Create(mGraph, 1, true); }