I am looking to see if it is possible to get all of the instances of playables within a playableDirector component.
I am somewhat of a beginner c# programmer, so I wasent able to see a way via the API documentation, and havent seen any examples yet. I dug through all the examples posted on this thread. (Which have been helpful in writing the other C# snippets/actions).
I want to be able to mute tracks for example, in a running timeline, or add animations at X time, etc.
public PlayableDirector collectedTimeline;
public string playerAnimationTrackName;
void BindPlayerToAnimationTrack(){
//Loop through timeline tracks and find the desired track to bind the player to
foreach (var playableAssetOutput in collectedTimeline.playableAsset.outputs) {
if (playableAssetOutput.streamName == playerAnimationTrackName) {
collectedTimeline.SetGenericBinding (playableAssetOutput.sourceObject, player);
}
}
}
Itās from the project linked in the comments of this video.
During playback, the playable graph is available through the playableGraph property on the playable director. You can grab the outputs from the graph - each track is represented by an output, or you can parse the graph from the root (playableGraph.GetRootPlayable(0)).
Most tracks have a mixer that represents the track. This would be the input to the root. Then the inputs to the mixer are the playables representing the clip.
Animation is more complex, but the leafs nodes are AnimationClipPlayables.
Same thing question here. I do get the whole playableGraph.GetRootPlayable(0), but what next once we have that? Whatās the missing link that could get us to āanimationTrack.muted = trueā ?
Iāve read about many complicated ways. Including some AnimationPlayableOutput thingy, but that arenāt recognized in Unity 2018.2.4f1.
Iāve also tried some AnimationTrack a = playableDirector.GetGenericBinding(animator) as AnimationTrack;
Debug.Log(a);
but nothing happens, the AnimationTrack isnāt recognized
The goal is always the same: how to simply āmuteā a playable track from script ?
Ok, so playableDirector.playableGraph.GetOutputByType(i) is an other way to get the AnimationTrack. But, as I said, thereās a weird behaviour in Unity 2018.2.4.f1, AnimationPlayableOutput isnāt recognized. (everything else is, using Timeline and allā¦). Am I missing something or could that be an issue in this version ?
Oh. Yeah. of course ^^. Thanks.
As Iām still working on the topic:
Iām in the TextSwitcher default playable,and I would like to know if Itās possible to get the current track the clip is on?
So that I can test if the track is mute, and if so disable its functionality.
I suppose I should get access at least to the director or such to do so ? But didnāt found so far.
CreatePlayable() passes a gameObject. For timeline, that is the game object the playable director belongs to.
Or, you can ask a playable for itās PlayableGraph. From there you can call PlayableGraph.GetResolver() ā itās an IExposedPropertyTable, but thatās actually the playable director as well.
Or, the FrameData passed into Prepare/ProcessFrame contains the PlayableOutput currently being processed.
GetReferenceObject() on the playable output should give you the track that created it.
^^ Got a new problem. Weirder this time.
Hereās my example:
On entering new clips with timelineās reading head, Iām checking if theyāre are of type TextSwitcher. If so, in their mixerBehaviour, Iāve added some function that asks to mute an AudioTrack, below in the same timeline.
Editor mode, everything works, Playmode: everything slowly falls apart. iāve got hard time to understand how it slowly degradates.
For example, if the director does one entire play till the end, (in which the audio gets mute/unmute regularly depending on the TextSwitcher track above), once the head goes back to the start of the timeline, audio track, even unmute, displays correctly the change on the timeline, but does not give any soundanymore. Itās super weird (or same thing If I manually move the reading head a few times accross the timeline)
I felt like maybe I should do some āRebuildGraphā after muting/unmuting a track. But when I do so, I get warnings telling me that I canāt do it while the graph is being evaluated. And it seems to be evaluated all the time.
So yeah⦠bit lost again, can you help?
(using 2018.2.5f1)
Flag the graph to be rebuilt, and rebuild it from a monobehaviour (e.g. in an update method). Rebuilding the graph from Prepare or Process frame doesnāt work because itās in the middle of execution.
Actually, I was already doing that part of doing the rebuild within a monobehaviour, in an update method ^^ā
But maybe Iām missing the flagging part. Not sure what you meant by āflag the graph to be rebuildāā¦
Have a static boolean act as āflagā. Set it to true when you want the graph to be rebuilt, then when your monobehaviour (which is checking that same bool) fires, set the boolean back to false.
Thanks for this code, it works fine but after some testing I found two limitations:
Only AnimationPlayableOutput has the SetTarget method, this means that I cannot mute tracks of other types right? Is there a generic method for IPlayableOutput?
I have a timeline with some Override Tracks on my Animation Track. When I mute the parent track in editor the children are still played, unless I also mute them. Using the runtime method provided however the children are muted too and thatās not what I want. Is there another way to achieve the same result?
Sorry for bumping this thread but itās very hard to find how to mute an Override track, say I have the AnimationPlayable X has an override track Y, how do I access it and mute it?
at the moment Iām using the TimelineAsset to mute it indirectly and rebuild the graph
So Iāll answer my own question, found how to remove tracks sadly weighting doesnāt work as itās get reset the next frame for whatever reason
for (int i = 0; i < director.playableGraph.GetRootPlayableCount(); i++)
Process(director.playableGraph.GetRootPlayable(i));
void Process(Playable playable, int depth = 0)
{
if (playable.GetPlayableType() == typeof(AnimationLayerMixerPlayable))
{
AnimationLayerMixerPlayable mixer = (AnimationLayerMixerPlayable)playable;
Debug.Log("Found Mixer!" + mixer.GetInputCount());
Debug.Log(mixer.CanSetWeights());
!!! //mixer.SetInputWeight(1, 0f); <<<----- this doesn't work, it works only if you pause the graph, but if you resume it gets reset
mixer.DisconnectInput(1);
return;
}
Debug.Log(new string('>', depth + 1) + playable.GetPlayableType().ToString());
for (int i = 0; i < playable.GetInputCount(); i++)
{
Process(playable.GetInput(i), depth + 1);
}
}
So seems like I found how to weight down the layer mixer, but wish an official will state why exactly this is the behavior and if itās the intended one.
So to disable a branch of a mixer, you need to disable the inputs of the children sub mixers
this is the minimal actions that needs to be done to set all branch to 0 and to make Animation Layer Mixer not get back to 1.0.
//mixer.SetInputWeight(1, 0f); <--- 2nd AnimationLayerMixer branch, gets reset next frame
//mixer.GetInput(1).SetInputWeight(0, 0f); <---- Animation Offset, doesn't do anything
mixer.GetInput(1).GetInput(0).SetInputWeight(0, 0f); <----- Animation Mixer, this one does it!
//mixer.GetInput(1).GetInput(0).GetInput(0).SetInputWeight(0, 0f); <---- Animation Clip, doesn't change anything
//mixer.DisconnectInput(1); <--- If you don't want to play with weights, do a hard cut instead