Search Unity

Replicating a mecanim state machine using Playables

Discussion in 'Animation' started by TantzyGames, Oct 6, 2017.

  1. TantzyGames

    TantzyGames

    Joined:
    Jul 27, 2016
    Posts:
    51
    I’m having some difficulty conceptualizing how achieve what I need using Playables. I’m hoping someone with some experience can offer some guidance.

    I need a sub-state machine where the transitions and the length of those transitions are set at runtime. I need a number of these state machines that are used at different times, each with similar structure but different clips and different transitions.

    Just to double check, I tried just using mecanim first. Override controllers allow me to change clips, and Animator.CrossFade allows me to create the transitions, but CrossFade doesn’t cope with interruptions. I thought there may be a way to deal with interruptions, but at that point I figured playables would be a better investment.

    I’ve started to work on a playable for this system, but I’m not sure of the best way to proceed. None of the examples really deal with how to replicate a mecanim state machine, and the looking at my animator controller in the PlayableGraph Visualizer, the structure is obscured by Playable nodes which I can’t see into (but I think suggest an answer to my first question).

    What I have put together with help from the examples is the ability to transition from my animator to a playable, and to transition from one clip to another clip within the playable. Beyond that I’m not sure of the best way to structure the playable graph for best results.

    1. Should I just have all the clips connected to a mixer in one playable, or is it better to have a different playable for each state?

    From what I can tell, having all the clips in one playable is more like a blend tree than a state machine so I’m tending towards a playable for each state. What confuses me is that looking at the PlayableGraph Visualizer for my animator controller shows each mixer with 2 inputs - an animation clip and a playable - and I'm not sure what each represents.

    2. Is there a functional difference between pausing a clip and stopping a playable?

    3. To replicate mecanim transitions should I
    a) start playing the second clip/playable
    b) blend between the current/first clip/playable and the second one
    c) stop playing the first clip/playable?

    4. Is PlayableDirector useful for this case? It looks like it might be useful as part of my Playable Controller but I’m not sure if it needs a timeline.

    Edit: Another question.

    5. For my sub-state machines, what are the benefits of creating separate PlayableGraphs for each as opposed to housing all of them in a single PlayableGraph, and vice versa? They'll be disposed of as a group rather than individually, but are there performance implications?
     
    Last edited: Oct 6, 2017
  2. mangax

    mangax

    Joined:
    Jul 17, 2013
    Posts:
    336
    i've been in the past two days playing with playablebehaviors ... you are right regarding not many resources..
    i guess if you look at scripts from one year ago or older.. there have been many changes.. anyway this is what i figured so far.. i could be wrong..

    1. from what i understand.. mixer is able to play two inputs together and mix them.. Playable can implement scripts that can be run when they start playing or on exit or even paused!.. https://drive.google.com/file/d/0BxXa-EKSOUL9ZlNMTGxVN1VDVzA/view
    so if you are thinking to blend between just two or more AnimationClips.. a mixer is good enough i guess..


    2. didn't tested it yet.. but i would guess that pause maintains the state time (Where it stopped)
    + can call the functions inside playable states like: onpause-

    3. this is what i do now, and what some tutorials examples online contains..
    actually you don't need to stop the clips you transitioned from ..

    regarding which is the best way to use playables.. i found that in my project character animator which contains 3 different layers and multiple blends and sub-state machines etc...
    inside graph visualizer is saw all clips inside a single layer are connected to a mixer.. and all 3 main layers mixers are connected to a single mixer at the end.. so i figured out that the animator actually manages the relations between clips/states/blends/submachines ..all as mixers at the end..

    i personally like the concept of mixers ... very simple ... and can do unlimited possibilities..
    so making an animation manager to handle these tasks should be straightforward if you can keep track of inputs/outputs..

    4. no idea

    5. is it possible to blend one graph into another graph ? if not then it would look odd if your character suddenly flicks...

    in my case i would use one playablegraph, for example a character might have common animations... like walking/running/ jumping.. or when taking a damage.. with all the audio and such along with them..there is a small number of clips i need to be played for weapon holding and attacking with weapon. it would be odd if i create new graph for just few clips and then just replicate same other states..


    i have a question as well regarding the playable api..
    is it possible to change an existing clip in the PlayableGraph?? or the AnimationClipPlayable?
     
    Last edited: Oct 8, 2017
  3. TantzyGames

    TantzyGames

    Joined:
    Jul 27, 2016
    Posts:
    51
    Hey mangax, thanks for your reply.

    1. Thanks for that link. It's really useful to see those examples.
    With only 2 clips it's pretty straight forward, and there are examples to use. I have 4-8 clips, and possibly more. My question is in terms of best practice in terms of managing those multiple states/clips. For example in mecanim I could create an animator controller with all the clips transitioning between each other, or I can create blend trees and sub-states to segment and give them some hierarchy. What's the best way to do that in animation playables?

    I can do some of that with mixers, but is that enough? In replicating mecanim I really want to nest Playable Graphs, and if I have my own hierarchical state machine I can do that, but I feel like that's not the best way to accomplish it.

    2. Pausing a clip takes it out of consideration for it's mixer, but doesn't affect the playable graph time. Stopping a playable graph affects all it's clips. Does an AnimationClipPlayable have an accessible onPause function?

    3. That's really interesting. My character setup is very similar, but when I look at the mecanim graph instead of lots of clips attached to a mixer I see one clip and one "playable" connected to each mixer. I don't understand what the one clip is (when there should be many) and it's not clear what the playable contains.

    For simple playables it's easy enough to manage the weights between multiple clips, but I can also see it getting quite unwieldy with only a little more complexity. I'm hoping that the developers have already considered that, or else perhaps I'm expecting more from this than they intended. It's not really clear from the documentation.

    5. I doesn't seem possible to blend graphs, or nest them in other graphs. But I'd quite like to create similar functionality, and I'm guessing that's what the "playable" nodes in mecanim are doing. Otherwise I have a huge mess of clips and mixers all in one entity that are much more difficult to keep track of and manage.

    What I'm doing is a bit like The Sims where animation and functionality is contained within the objects being used. So I need quite a few of these playable state machines, and I'm looking for the best way to manage them all. At the extreme I could just have one big playable graph with every possible clip connected to a few mixers, and manage them from my own state machine, but I hope that the developers can suggest much more efficient ways of using the system.

    To answer your question. It doesn't seem possible to change the clip an AnimationClipPlayable (you can only get a reference to the clip), but you can certainly remove one from the graph and add another, effectively replacing it.
     
  4. mangax

    mangax

    Joined:
    Jul 17, 2013
    Posts:
    336
    1 & 2 Try looking up playable api and their example there is queue class example at the end where it can plays multiple clips one after another.. i tried copying same class and run it...but didn't work!
    it created a a new class inheriting from playablebehavior, and overrides onpause etc.. then it checks if first clip ended then it animate the next clip.. i dunno why it didn't work...am not sure about what you try to do with pausing the graph?

    mecanim is becoming more like a place for state management with the addition of behaviors to them..
    so i think the new playable api is pretty much should be approached in the in same way you handle your game AI states etc.. and states management can be programmed and structured differently..it's hard to say which is the best way! it depends on your needs..


    3-5. i have also playables states in the graph from the animator, not sure what they represent.. maybe some default states from animator?

    yesterday i created 2 mixers.. attack and movement.. i wanted to add jump animations.. which contains jump/falling/land.. so i thought maybe jump mixer and movement mixer should be under another mixer.. so i can set the weight for each mixer!.. then i realized it's a bit annoying handling each mixer inputs and the clips weight at each mixer.. so i ended up having all the movement clips under one mixer.. and am thinking now to construct a mixer manager class! which handles transition from one clip index to another .. it's better keeping these indexes handled by a manager so you can have a higher level of abstraction..
     
  5. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    I'll try to clear up some things:

    Everything in the Playable system is a Playable. A single animation clip is wrapped in a Playable. A mixer is a Playable. A layer mixer is also a playable.

    Mixers mix playables, not clips. So you can have mixers that mix mixers. In the AnimatorController, that would happen if you're playing several layers, and the layers contain blend trees. The blend tree is a mixer, and controller itself is a layer mixer (which is essentially a more complex mixer that handles avatar masks and additive blending).

    A graph just contains all of the above. They don't mix with each other - that's the mixers job.


    For pausing, note that the default time mode of a newly created graph is the DPS clock, which is a clock used to control sound and is a really bad fit for animation! That's probably an oversight. Be sure to switch to game time.

    I've been replicating most of the useful behavior in the AnimatorController in Playables. That does not, in my opinion, include sub state machines, so I don't have any experience to help you there. What I can say is that sub state machines really only changes the behavior of what's inside them when blending. They won't really need to show up in the graph, since what you're playing is a single state inside the sub state machine.
     
    CodeRonnie, CrazyD0G, Deeeds and 2 others like this.
  6. mangax

    mangax

    Joined:
    Jul 17, 2013
    Posts:
    336
    Thanks fir the information!
    I really like the new api ... I was able to do some interesting animations with layer mixer (attacking while running)

    Btw do you know where i can find a resource of how to display playables created from script in the graphvisualizer??

    I tried using the classes of graphicvisualizer in my scripts but with no success..
     
  7. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    You need to register the graph with the visualizer. So:

    Code (csharp):
    1. GraphVisualizerClient.Show(myPlayableGraph, "Some name");
    That'll allow you to select "Some name" in the dropdown in the visualizer window..
     
  8. mangax

    mangax

    Joined:
    Jul 17, 2013
    Posts:
    336
    amazing! thanks for help!
     
  9. TantzyGames

    TantzyGames

    Joined:
    Jul 27, 2016
    Posts:
    51
    Thanks Baste and mangax. I think I'm starting to wrap my head around this.

    I don't really need sub-state machines, that's just how I created my first example in mecanim, and the idea that I want to replicate. I have a mecanim animation controller for my basic animations that I mix to a playable graph (and then back) instead of transitioning to a sub-state machine (and back).

    Thanks to mangax I've had a look at playable behaviours again. I think this is what I was missing initially. Those playable nodes in the mecanim graph are playable behaviours controlling the sub-states. The playable behaviour interface has the functions needed to control the graph, which are the same functions you have in a state for a state machine. So better to use that than roll my own because playable behaviours can be mixed too.

    And in thinking about replacing clips I've realized that playables are structs which is why the clip can't be replaced. But what that also means is that I can create and delete a bunch of them without worrying about garbage.

    Playable Graphs can't be mixed, they're the top level. So if I need to transition from one set of moves to another, they'll need to be in the same playable graph. But if a set of moves only needs to transition from mecanim and back then it can be in it's own playable graph, but doesn't have to be.

    Also there seems to be a slight overhead in creating a playable graph so perhaps as well as transitions being a consideration, I can put predictable move sets into a single playable graph (each with it's own playable behaviour controlling the mixing), and create other playable graphs on the fly for move sets that are less predictable.

    I'm still a little unsure about timing of all the elements, but I'm sure that'll become clear with a bit more experimenting. Instead of thinking about it like clips start playing when the graph starts I think it's more correct that a clip matches it's parent time. So a clip would match it's controlling playable behaviour time which matches the playable graph's time. But the position in time for all of those elements can be individually adjusted. So creating a transition would require setting the new clip to 0 time at the beginning of the mix, and creating a blend would require matching the clip's times. Does this sound right?

    One thing I love about the animation system is that it's multi-threaded. I use a combination of coroutines and animations to move stuff, but animations are great because they play smoothly even when the frame rate drops or is erratic (loading anims for example).

    For some of my motions, I'm using mixing for creating animation between poses, so while controlling the mix offers significant flexibility and power, it means that the mixing in this system is all on the main thread so I lose a big benefit of the animation system. It would be great if there was a way to create a transition (a predictable mix over time) that wasn't dependent on the main thread. Maybe as another extension: SetTransition(float startWeight, float endWeight, float startTime, float transitionTime)?

    The other question I still have is my mecanim layers. When I've mixed from an animation controller to a playable graph, then I can't layer animation unless that layer is replicated in the playable graph. It would be really useful if I could just mix specific layers instead of the entire controller. Maybe to achieve this I need to move the entire system to playables...
     
  10. mangax

    mangax

    Joined:
    Jul 17, 2013
    Posts:
    336
    sorry i didn't get the last part about animation mixing part? do you mean something similar like audio snapshots?

    i was just thinking it would be cool if it is possible to take a snapshot of all graph input weights..
    then i can apply transition between these shots or at any time... similar to audio mixer.. it makes controlling the graph, a more manageable process..

    am sure unity devs can figure out interesting ways to store/apply these shots..
     
  11. TantzyGames

    TantzyGames

    Joined:
    Jul 27, 2016
    Posts:
    51
    I think it's just my lack of understanding of how playables work. I think I'm still thinking too literally about all of this. But what I was saying is, for example, I need to create (recreate) simple transitions from one animation clip to another.

    My understanding is that the animation system is multi-threaded which is why animations run much more smoothly than coroutines, even when they have the same timing settings. Even though an animation can only display an update every frame, it can evaluate more frequently/regularly whereas a coroutine can only evaluate every frame - or at least that's how I think it works based on my observations.

    If that is the case, it seems that playables can only evaluate every frame which have the same limitation as coroutines instead of the power of the multi-threaded animation system. If that's the case, then I can't create a transition playable behaviour that replicates mecanim transitions. I can only create a transition playable that behaves the same way, but doesn't evaluate in the same way.

    When I say I'm thinking too literally, take my question about layers. I realized that when I connect my animation controller to my playable graph I have complete access to it. I think I could hook up it's layer mixers to my main mixer, but to do that I need to figure out how to interpret, and then control, an animation controller graph - which doesn't seem like a trivial process.

    It's a little frustrating because all the talks say that that mecanim is built using playables, but instead of concrete examples that reflect what I've learned over years of using mecanim, there are only a few trivial examples that demonstrate abstract concepts, so I don't really know yet if my assumptions are even remotely accurate. Playables have been in development for so long it's strange there is so little documentation or examples.

    Anyway, my task today is to start putting all this into practice and to re-create my animation controller. I'm sure some of my questions will be answered along the way.

    @Baste you mentioned you've replicated most of the useful AnimationController behaviour. Can you tell me if I'm on the right track, or give me any pointers?

    @mangax you can create snapshots with float arrays:
    Code (CSharp):
    1.  
    2.         int inputs = mixerPlayable.GetInputCount();
    3.         float[] snapshot = new float[inputs];
    4.         for (int i = 0; i < inputs; i++)
    5.         {
    6.             snapshot[i] = mixerPlayable.GetInputWeight(i);
    7.         }
    and then apply those values or blend to them when you want them.
     
    Last edited: Oct 11, 2017
  12. mangax

    mangax

    Joined:
    Jul 17, 2013
    Posts:
    336
    Thanks for the script!

    The way i look at playables in the graph (regardless of their playable type) are like stream of animations... and inputs values controls how much of source go through each playable node.. all clips start playing when you call graph.play()... the looping clips keeps looping while non-looping clips reach their last frame.. note that even when animationclip reach their last frame...it still effects results.. so i had to set their input weight to zero!

    so when you speak about transition from one clip to another,i learned that it's essentially controlling the weights only of all these sources and make sure there is no weight leaking somewhere that might effect the animation you want to see! Also you will need to setTime(0.0) For non looping clips every time you want them to start from their first frame ..

    Mecanim manages that for you with all user friendly UI.. but you can ditch mecanim and make your own playable and handle everything manually!

    playgraph is more like audio mixer than mecanim with states etc... In audio mixer the effects all applied at same time..and you adjust their amount.. thats why there is also playable audio support nodes the graph..they all act in same way i guess..


    I haven't looked into the multi-threading smoothness of animations etc.. but i noticed when scene loaded..the playgraph animations starts up very slowly! then it picks up speed until its reach the standard speed..this behavior happens at the first 2 seconds regardless of game fps.. so maybe this is a poof that playableclips update run in different thread ??
     
    Last edited: Oct 11, 2017
  13. TantzyGames

    TantzyGames

    Joined:
    Jul 27, 2016
    Posts:
    51
    Yes, which basically brings me back to my original question - whether I just add all my clips to a single mixer and control their logic with my own state machine, or whether there is something built in to make that a bit simpler.

    Today I got transitions happening very quickly using coroutines, but I wanted to create a playable transition. Following the Playable Behaviour example, I could change connections, and replace the pingpong behaviour with a different one. Then I created a PlayableTransition behaviour which kinda worked, but with an AnimatorControllerPlayable added to the graph it produced this error:
    Code (CSharp):
    1. InvalidOperationException: Connecting a single-threaded Playable to a running multi-threaded PlayableGraph is not supported
    So I'm thinking at this stage that none of the playable system is multi-threaded, which is unfortunate. But if that's the case, there's no reason to make my transitions as playables, which is actually a relief because trying to do that seems to be super complicated. In fact it seems to me that making the playable system flexible enough to be everything for everyone, has made it too complicated and obtuse to be very useful at all for anything remotely complex, at least for my limited skills. It doesn't help that Unity crashes if I even glance at a playable graph sideways.

    It's frustrating because all I really need is to be able to change animation clips and create custom/runtime transitions. Even if I could just change the duration of a transition I could probably get most of what I need using mecanim.

    But to replace mecanim I need to figure out a way replicate synced layers (which I have running different objects in different animators), transitions, and to manage additional layers and all their clips. I was hoping to avoid writing my own version of mecanim, but it seems at this point it's the only way to achieve what I need. I'm still hoping to be proven wrong by someone. @Baste has had some success, and hopefully @Mecanim-Dev can offer some help too?

    Maybe I'm expecting too much from it. When playables are eventually running in the C# jobs system, and it has useful examples and real documentation I'm sure it'll be much better. Or maybe I'm just grumpy from so many crashes today...
     
    Last edited: Oct 11, 2017
  14. mangax

    mangax

    Joined:
    Jul 17, 2013
    Posts:
    336
    oh, i didn't see that behavior scripting page before.. maybe i was in the manual section in unity website!

    yeah i guess mimicking mecanim is kind of seems like overwork.. playables is made for custom made animation effects while mecanim is more friendly approach...
    it doesn't make sense that playable is easier to work with than mecanim when you have multiple states and transitions in mind.. custom playables will always needs a custom solution to manage it.

    There are things i find it possible and easier to do in playables which is hard in mecanim!

    for example, an issue i had with mecanim is with Avatar Masks , i have a character with attack animations, but i want mecanim to force player lower body walk/run is applied even when the player is attacking.. so player can attacks while running.. it does that effect..
    the issue is when after the attack ends, the timing when it enters to the next state (idle or runnning) is not synced well with lower body, causing player to run weirdly.. the only fix for this is to update one of each state timing to 0 or something.. maybe there is another better way.. but still more annoying to achieve than playables..

    with playable this is easy to achieve , plus more!

    i was able to control upper body while maintaining movements animations!
    Attacks have some leg animations... so i was able to apply attack animations with lower body when player is not moving or idle.. the lower body will apply attack animations... but if running, his legs will keep running..
    whats more interesting is when the player between running/idle .. on slow/walk movement.. the character will do a mix of attack and walking ,it's like the character legs apply the attack animation while doing little walk steps..
     
    Last edited: Oct 11, 2017
  15. TantzyGames

    TantzyGames

    Joined:
    Jul 27, 2016
    Posts:
    51
    Hey that's really cool. When I was reading your post I was thinking of how it shouldn't be too difficult to setup in mecanim, but then watching the video and thinking about it I can see how much easier, and more flexible, it is with your own blending logic. Great stuff!

    It turns out that playable behaviours weren't the answer after all.

    I finally got a transition playable behaviour working - in the graph visualizer. I can change the transition duration and the target and the mixer inputs change color correctly. Unfortunately the playable isn't passing the clip data from it's input mixer to it's output mixer so the clips don't play.

    Now a playable "behaviour" I would think connects to a playable, effects how it works, but doesn't change it's inputs or outputs. But in this "everything's a playable" system, a playable behaviour node has to sit between a playable and it's output node, which is fine I guess, so long as it passes the playable's data through. But it doesn't!
    If everything can be a playable, surely every playable should indiscriminately pass whatever data enters it's inputs through to it's outputs?

    Which reminds me of a question. Why is there no animationTransitionPlayable? Transitions are fundamental building blocks of an animation state machine, just like clips, mixers and layers - but they all have playables and transitions don't. I get that a transition is a just a fancy mixer, and if playable behaviours passed animation data then fine, but they don't.

    Anyway my solution is to use AnimationPlayableUtilities to play my mixer (this is also what I had to use with the blender playable behaviour example), which duplicates my graph, creating a new AnimationOutput. The upside is that my transitions actually play in the scene. The downside is that I have no idea how to get back to my original graph/output. When I mix back to my animation controller, I can see it happening in the graph, but now that output is dead. But I can't user AnimationPlayableUtilities to play from my original graph because "crash". I can't change outputs because "crash". I can't delete outputs because "crash".

    So I think I need to change strategy, at least until I get some help (and this is probably a bad time to be asking for help because of Unite Austin). I am able to create a graph and control it's mixers with my own classes, so that's what I'll do for now. The only reason I didn't do that to start with was that I was hoping that playables were multi-threaded, but since they're not, then there's no benefit to trying to force my controllers to fit the playable system.

    So currently my best answers my original questions are:
    1. As long as you keep a reference to the playableClips it doesn't make a big difference. The more complicated your graph or the more clips you have, the easier it will be to manage them with a network of mixers rather than just one. It will run faster that way too, because you won't be manipulating as many weights each frame.
    2. No
    3. Yes
    4. No
    5. Use a single playable graph and keep references to the mixers and clips you need. Don't touch AnimationOutputs or "crash".
     
  16. TantzyGames

    TantzyGames

    Joined:
    Jul 27, 2016
    Posts:
    51
    To answer another question:

    I can still control my animator controller through mecanim even when it's in a playable graph, so I don't need to replicate my layers. I just need to mix from the specific layer mixer I need, instead of mixing from the entire controller. That way I can override the base layer with my custom motions, and still have my other layers working through mecanim.

    However my synced layers aren't so easy. My prototype has a synced layer to animate IK goals, which have their own clips and their own animator (a surprisingly simple solution). Now I think I have to have 2 separate graphs to deal with those, but either way I'll need to manage the syncing on my own.

    Edit: Oops, I spoke too soon. I can't mix from a specific layer in the controller because it's read-only, so all or nothing...
     
    Last edited: Oct 12, 2017
  17. mangax

    mangax

    Joined:
    Jul 17, 2013
    Posts:
    336
    I get that a transition is a just a fancy mixer, and if playable behaviors passed animation data then fine, but they don't.

    yeah there is a bug or something.. all the examples in unity website about playables queue examples are not working on the character, i can see the transitions fully working in the graph... but the character is stuck on T-Pose!..
    sadly even in latest release 2017.2 still not working...


    about the sync thing, i usually don't have sync layers + IK, i haven't tested playables + animator controller yet ( i can't help much in this regard in meantime )...currently i am only testing pure playables solution!
     
    Last edited: Oct 13, 2017
  18. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    I mentioned this upthread, but it probably got swallowed. The default time mode of a playable graph is the DPS clock, which makes it behave in all kinds of strange ways when you pause the player - in particular things run very slowly for a while, the longer the pause, the longer the slowness. I'm guessin the same thing is happening here.

    There's some part of the API where you can put it in game time, which makes it run like you'd expect. It's probably a bug that it defaults to DPS, I just haven't bothered to report it yet.

    For transitioning I just modify the weights in a mixer. I keep track of the state of weights when I started transitioning to a new state, and then I do an interpolation towards how I want the weights to be in the end. There's an array of floats somewhere in there. Sounds like what @mangax is doing.

    I'm experimenting with seeing if it's usefull to have curved transitions - the AnimatorController uses linear interpolation between the last state and the current state, but it might be that things like movestops or accelerations could be improved with different kind of blend curves.

    The long term plan was to open source my solution, but right now it has all those little issues that are annoying (Undo fails to Undo things) and the UI is a mess and I haven't quite nailed down 2D blending. I know how Unity's doing it; Rune
 Skovbo
 Johansen works at Unity, and posted in Unity Answers somewhere that their 2D blending was based on his thesis (great read), so I just need to put in th work. If you're interested, I guess I could put out my current stuff so you can see what I've done.
     
  19. TantzyGames

    TantzyGames

    Joined:
    Jul 27, 2016
    Posts:
    51
    How are you getting your character to move? Using AnimationPlayableUtilities?
    I don't understand the relationship between the Animator and the AnimationPlayableOutput. When we create an AnimationPlayableOutput we need to specify the animator so I would assume that creates the necessary connection, but it doesn't actually do anything.
    Using AnimationPlayableUtilities to "play" the graph or playable creates that connection, but it also duplicates the playable which has a tenuous connection to the original that doesn't survive editing.
    When I create an AnimationControllerPlayable in my graph the connection works, so the output seems to inherit the serialized connection between the animation controller and the animator.
    When I've used AnimationPlayableUtilities to force a connection, then I guess the only way to go back is to use AnimationPlayableUtilities to force a new connection back to the original. But when I've tried that, it either creates a new graph that doesn't affect the animator, or crashes Unity.

    I read that, but didn't understand the implications of it. So if syncing to audio, then maybe stick with the DSP clock, but an animation graph should use one of the other modes, eg:
    m_Graph.SetTimeUpdateMode(DirectorUpdateMode.GameTime);

    That's interesting, because the very first example in the manual shows an animation graph and an audio graph in the same PlayableGraph, which I've been excited about, thinking I could more easily link animation and audio by playing a single graph with both in there. But time mode can only be set on a PlayableGraph, not any playable. Although in that situation the audio is probably fine using game time as well, and if you're syncing animation with audio then you probably want the animation to use the DSP clock too.

    Yes, I've implemented a variable transition both as a coroutine and as a custom playable doing just that. I'd love a glimpse at what you've been able to achieve. What I'm most interested in is if your transitions are playables or your own class? How are you structuring your graphs, and then how are you manipulating them?

    The best way I can think of using playables is to create a single graph, and then manage it with my own state machine. But from how it's promoted I don't think that's the way it's intended to be used so I am really curious to find out how others are using the system. Are you making the most of it being all structs by creating new connections whenever you need them or a more conservative approach like mine?

    Also by picking through more threads here, it does sound like it much of what I was originally expecting from playables based on the blogs and talks can't actually be achieved until the C# jobs system arrives.
     
  20. mangax

    mangax

    Joined:
    Jul 17, 2013
    Posts:
    336
    Thanks @Baste for the clarification...
    It happens as just you described it.. sometimes it remains frozen for like 5 seconds before start moving slowly!

    @TantzyGames No i don't use the utilities, i simply use same samples (other than the queue examples) , and they work, you don't need to attach animatorcontroller asset inside the animator, playables only needs animator component attached to gameobject to work. am still as well looking for best way>>>


    Recently, i came to think that all these inputs/indexes/weights are more like handling steering and vectors! So i might figured part of the solution here:

    Code (CSharp):
    1. //adding public "blend" variable for all inputs.
    2. mixerPlayable.SetInputWeight (idleIndex, blend * moveBlend * ( 1f-move)); //looping idle
    3. mixerPlayable.SetInputWeight (runIndex, blend * moveBlend * move ); //looping running
    4. mixerPlayable.SetInputWeight (jumpIndex, blend * jumpBlend); // non-looping jump
    5. mixerPlayable.SetInputWeight (fallIndex, blend * fallBlend);   // looping fall
    6. mixerPlayable.SetInputWeight (landIndex, blend * landBlend);   // non-looping landing
    7.  
    an idea to control all the behavior is to have blend variable added to all inputs per behavior.. this blend value can be controlled by other behaviors if needed, without interrupting each behavior job, making things far more less complex to manage!
    structure example:
    State1: Blend = (State2Blend * State3Blend )
    State2: Blend = (State1Blend * State3Blend )
    State3: Blend = (State1Blend * State2Blend )



    This solves Many things + advanteges:

    the blend variable will controls the speed between each state.. regardless of each state behaviors or mixers location in graph etc.

    less tracking for inputs, inputs index is handled per it's own state behavior. also it is possible for two behaviors sharing same mixer, each control it's inputs.

    follows animation flow better..if the move behavior will started to play the non-looping jump animation..if any state activated (like damage animation state), once other state is done.. it will blends back to where move behavior logically should be at in the jump process...in this case you won't face the issues to determine how to start move state again..

    More easier to manage interruptions and reverting back!

    AvatarMask friendly.. the other states that might controls some parts of the body will continue to work (like the video i posted). depending on how you connect your graph and what states will control over other states.. you have full control through scripts.

    Less Loops iterations per state less complex scripts to manage, also it should run faster from scripts side.

    downside:
    Some States should be running non-stop..even when other state is active.


    This sounds like each state can have it's own mixer and each mixer can be grouped under a single mixer which controls the blend between each state mixer..
    but with this approach i liberate my class manager from keeping track of mixers and their relations which makes it possible to create different types of mixers structure in graph.
    it is less reliant on mixers, mixers are very handy but i would only now use it now for avatar mask purposes...


    Lastly, i started to believe that a full state machine solution may not work well with playables..
    if it works, you will have to make very complex statemachine solution..you have to consider the all play graph structure possibilities and how things should behave with each other..
    it would be so complex that mecanim graph is just a better solution to have :)

    Edit: updated the approach
     
    Last edited: Oct 15, 2017
  21. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    A transition is just a POJO containing information about how the transition should look. Here's a strip-down version containing the essentials (ie. none of the serialization code or boilerplate Equals, HashCode stuff):
    Code (csharp):
    1. [Serializable]
    2. public class StateTransition
    3. {
    4.     public TransitionData transitionData;
    5.     private AnimationState fromState, toState;
    6. }
    7.  
    8. [Serializable]
    9. public struct TransitionData
    10. {
    11.     public float duration;
    12.     public TransitionType type;
    13.     public AnimationCurve curve;
    14. }
    15.  
    16. public enum TransitionType
    17. {
    18.     Linear,
    19.     Curve
    20. }
    So it's just data. The AnimationPlayer takes care of figuring out which one to use when switching states and then applies that.
    Here's my AnimationLayer.Update, called by AnimationPlayer on all of it's layers:

    Code (csharp):
    1. //called by AnimationPlayer.Update (a MonoBehaviour)
    2. public void Update()
    3. {
    4.     if (!transitioning)
    5.         return;
    6.  
    7.     var lerpVal = (Time.time - transitionStartTime) / currentTransitionData.duration;
    8.     if (currentTransitionData.type == TransitionType.Curve)
    9.     {
    10.         lerpVal = currentTransitionData.curve.Evaluate(lerpVal);
    11.     }
    12.  
    13.     for (int i = 0; i < states.Count; i++)
    14.     {
    15.         var isTargetClip = i == currentPlayedState;
    16.         if (isTargetClip || activeWhenBlendStarted[i])
    17.         {
    18.             var target = isTargetClip ? 1f : 0f;
    19.             stateMixer.SetInputWeight(i, Mathf.Lerp(valueWhenBlendStarted[i], target, lerpVal));
    20.         }
    21.     }
    22.  
    23.     if (lerpVal >= 1)
    24.         transitioning = false;
    25. }
    My graphs end up looking like this:

    asdf.png
     
    davidseth8 and npatch like this.
  22. TantzyGames

    TantzyGames

    Joined:
    Jul 27, 2016
    Posts:
    51
    That's really interesting, thanks so much for sharing. I was actually just working on a similar concept to avoid limiting my system to a single transition at a time, but being able to run multiple transitions and have them blend together nicely. Your post has given me some great ideas.

    I'm struggling with this at the moment. I'm still deciding how much of mecanim to use, if any. I really want to make use of it's multi-threading as much as I can, but it depends how well I can merge it with my playable system.

    Thanks so much :) That's super useful! and really nice to see that your approach supports my conclusions.
     
  23. mangax

    mangax

    Joined:
    Jul 17, 2013
    Posts:
    336
    The more i stumble upon new animation requirements the more i see this approach works better!

    Today i was thinking to make a damage behavior,which supports flick dmg... when the character gets light damage, the animation can trigger little blends values only.. when it reaches like 0.3f blend, then it fades out right away.. now the character body will do flick dmg animation while doing other animations .
     
    Last edited: Oct 16, 2017
  24. mangax

    mangax

    Joined:
    Jul 17, 2013
    Posts:
    336
    Just wanted to share some of my experience with the new api..

    Updating clips is still annoying!!!

    I made a function which replace/add new inputs , then update it the behavior classes with the new indexes.. still it causes too much hassles to update animation clips and reconnecting outputs/inputs!!
    i think the api in big need for something to swap animation clip while maintaining all inputs/outputs in the graph!

    i wish playable api have a new feature, which is smoothly replacing animation clip with another one.. for example:

    Code (CSharp):
    1. PlayableGraph.SmoothReplace(oldPlayable,newPlayable,1f);
    the feature idea is to replace old playable with new playable within 1f second , less or more..

    unity internally will create a temporary "mini mixer" , it will add and play the new playable, then it will blends between old playable to the new one within the specified time..
    once it ends, it discard old playable and the mini mixer!

    this will make it possible.. to replace all animation clips and maintain all connections! also the character will not shake suddenly because of animation clip switch!

    i've added the idea here , please vote! >> https://feedback.unity3d.com/suggestions/feature-request-playable-smooth-replace
     
    Last edited: Oct 29, 2017
  25. TantzyGames

    TantzyGames

    Joined:
    Jul 27, 2016
    Posts:
    51
    Yes, disconnecting and connecting is annoying. I have a situation where I have a number of animation sequences, but only one is active at a time. I considered using a single mixer with a single input, and disconnecting and connected each one as I needed them, but it ended up simpler to connect all of them and to set the mixer input weight to the active one.

    I don't know if I'd want a smooth replace as you describe, but it would be very useful to have a simpler way to replace a playable for a particular input. What you're asking for seems to me to be a transition with an option to discard the clip being transitioned from. That could certainly be useful, but then you might as well add the other options useful to transitions.

    After creating my own transitions and getting this system working I would still love to have an AnimationTransitionPlayable class provided. It seems that even though animation clips played through playables are multi-threaded, but my transitions aren't.

    In terms of structure, I started to create a similar structure to a mecanim state machine, but transitions ended up being a nightmare to manage between multiple mixers and clips. Instead I have a much flatter structure:



    So in most cases I'm either mixing between clips, or mixing between mixers, but when I'm doing both then I just have two (or more) transitions happen together. So instead of a super complex transition class, I have a transition replicating mecanim transitions, that can handle clips or mixers, and a simple transition that just blends inputs over time without any other options that I use for blending mixers.

    I'm currently working on how to use all this with multiple characters. A playable graph can only have a single animation output that's tied to a runtime animation controller (I tried adding another output to a different runtime animation controller, but got the dreaded "don't mess with outputs" crash). It looks like I might have some luckwith AnimationPlayableUtilities. It means I'll need to keep references to my mixers by index, which I was trying to avoid, but if it gets the job done... Trying it out today.

    PS. Unity, where's the documentation for the playable extensions specific to Animation playables? That would be super useful...
     
    Deeeds likes this.
  26. mangax

    mangax

    Joined:
    Jul 17, 2013
    Posts:
    336
    yes as you said, to be able to swap playables easily , plus.. to have some smooth transition effect while doing so!

    if playables in essence is created to have more "control" over Animations, there should be at least one function that helps in replacing playables easily! it's ironic a bit when you compare it to how simple is replacing a clip in mecanim is despite it's shortcomings...

    if you want to use playables for multiple characters>> you have to create a new class manager for each character & you have to create a new graph for each character!
    you can't have two outputs from a single graph! unless it's different type like audio output..


    regarding AnimationPlayableUtilities , i remember one unity dev in one presentation on youtube said that they are aware that many people still use mecanim in their projects, and they created some utilities to be able to integrate some of playables new features into your existing mecanim characters.. i think it is made for this purpose mainly.
     
    theANMATOR2b likes this.
  27. TantzyGames

    TantzyGames

    Joined:
    Jul 27, 2016
    Posts:
    51
    I think more control doesn't mean making it easier, in fact the opposite. The more control, the more complex the system is. There's a balancing act between flexibility and usability that still needs a lot of work for playables IMHO.

    There's a lot that seems easier in mecanim until you realize that none of that ease of use is at runtime. The two systems have the same limitations which explains why you can't replace a clip or adjust a transitions at runtime.

    It does seem that each character needs it's own graph, and that graphs aren't easily copied. So if I want to control more than one character with the same graph, I need to create a separate graph for each character, and create all the elements for all the graphs individually. I hoped AnimationPlayableUtilities.Play might do it, but it was crashing Unity (maybe because the graph has an AnimationControllerPlayable which uses a unique runtimeAnimatorController). And the fact that we're still guessing at how they work and what they're for for demonstrates how useful the documentation is...

    The more I make use of playables, the more difficult it seems to be to use mecanim with them. I'm very close to discarding mecanim altogether and doing everything in playables which seems counter intuitive when all I really wanted in the first place was to slightly extend mecanim.
     
    theANMATOR2b likes this.
  28. mangax

    mangax

    Joined:
    Jul 17, 2013
    Posts:
    336
    they didn't show enough examples of best uses of playables with mecanim , how mecanim can benefit from playables?
    the sample scripts are very basic.. they don't enlighten much of how to deal with complex character animations.

    i think unity devs need to release a full sample project of multiple usages of playables!
    putting a demo scenes with full character animations (attack/damage/etc) and included it in asset store (what they do whenever they introduce new features in unity!)

    most importantly is the sample project should show off some capabilities of the new playables , including usage of sound and other effects! it should be like best practices for beginners!
     
  29. TantzyGames

    TantzyGames

    Joined:
    Jul 27, 2016
    Posts:
    51
    I agree. The blog posts show some interesting uses and demonstrations as gif's. It's disappointing those haven't been made available as example scenes.
     
    Deeeds likes this.
  30. TantzyGames

    TantzyGames

    Joined:
    Jul 27, 2016
    Posts:
    51
    My original idea was to have humanoid animation in the base layer controlling a character, additional animation in a synced layer controlling a separate fbx with IK goal objects and other non-humanoid transforms, with another layer for facial animation, and another layer for some other expressive animations. My testing with mecanim had this working nicely, but I need to be able to adjust transitions at runtime, and to either change or add animation clips at runtime. Playables to the rescue.

    Once I had playables working for the humanoid animation, I started experimenting with the best way to add the IK and other animation. Creating another playable graph to control the second set of objects halved my framerate (and that was just with the runtimeAnimationController in there, not any additional mixers or clips), so that didn't seem worth pursuing. Instead I bundled all the objects together and combined the animation clips. I was avoiding this initially because I wanted to keep more flexibility, but ultimately it doesn't really matter. It means that I only need a single playable graph and a single set of animation clips which keeps the code much simpler, and is much friendlier to my frame rate.

    I'll be interested to see how it all goes without any reference to mecanim. I'm still debating whether to retain mecanim for the facial and expressive animation layers, or to do everything in playables. When I get to that I'll have to do some more testing...
     
    theANMATOR2b likes this.
  31. mangax

    mangax

    Joined:
    Jul 17, 2013
    Posts:
    336
  32. TantzyGames

    TantzyGames

    Joined:
    Jul 27, 2016
    Posts:
    51
    Sorry I missed your reply. That does look interesting. I'll definitely spend some time digging through that. Have you learned anything from it so far?
     
  33. mangax

    mangax

    Joined:
    Jul 17, 2013
    Posts:
    336
    i haven't looked into it much, it looks similar to @Baste solution , transitions and such.. so i skipped the approach.

    am more comfortable with controlling animations in non transitional fashion... i feel it's more simple and straight forward than transition manager..

    Right now my classes handles difference in state blends and profile blends in this way (check image)..
    Drawing.jpeg
    each state is looping through each profile entry.. movement have idle/move/jump transitions of two profiles (healthy and injured movement).. to change animation style i only need to change profile blend.. and state blend would handle between two different states.. all values of the mixer will be equal to adjusted from all these states to 1f !!

    it works perfectly, i can play two different animations from two different profiles.. for example profile one sheath the sword, and profile 2 would draw different weapon with different animation.
     
    Last edited: Nov 21, 2017
  34. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,982
    anyone able to give input on how to go about this in current unity 2018.1 or 2018.2 beta?

    Struggling to understand how to use playables to set up a full set of animations with transitions for a character.

    Dont really get where the playableasset, playablebehaviour, mixer, graph etc all fit together, what they represent in terms of for a system like this, and any light you can shed would be great!
     
    Deeeds likes this.
  35. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    +1
     
  36. mangax

    mangax

    Joined:
    Jul 17, 2013
    Posts:
    336
    i handle playables by creating behaviors that work together override each other behaviors once needed..
    i don't mimic "transitions" as same as mecanim, over time it felt pointless (why replicating mecanim if mecaim exists?)
    also i get better results than mecanim.. so my approach is transition-less, more like an audio mixer!

    currently i use custom scripts that control mixers.. (i don't use the custom script of playable behavior at all.. )

    for example i have a movement behavior which takes rigidbody velocity speed then control the weights of mixer on how much idle vs run animation should appear by controlling mixer weights..
    this behavior acts as the "default" behavior! it always plays when nothing else happens on other behaviors..

    other behaviors like attack/damage/etc, once any of these behavior plays, it override other default mixer inputs ( the movement), so the attack blends in over the movement behavior, then it blends out..
    i can even interrupt other behaviors in favor of behaviors like damage or death...

    as a result of this approach.. i can have a running character, then it plays attack animation.. at middle of attack animation .. i play damage behavior.. and so on.. i don't need to transition to attack then again to damage... it all works together i only control weights and when to play clips..

    the thing is , you have to construct a manager class to handle all these things, and make sure total weights on mixer don't exceed 1.0f otherwise you will get wacky results..
     
  37. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    This is pretty cool. Sort of sounds like you have it working how I imagined Mecanim should work ;)

    Can you show some screenshots of how you hook this up, with a little code to highlight the magic of the mixer controller/weights?
     
  38. mangax

    mangax

    Joined:
    Jul 17, 2013
    Posts:
    336
    Okay it seems the approach i use makes people a bit puzzled, i have opened a topic and included a simple script as proof of concept..

    https://forum.unity.com/threads/simpleplayablemanager-script.534401/
     
    Deeeds and MadeFromPolygons like this.
  39. winxalex

    winxalex

    Joined:
    Jun 29, 2014
    Posts:
    166
    Use Blend Trees with Playables. No Mecanim. I'm using in example 3 Blend Trees: Locomotion, Crouch, Jump
     
    newMember likes this.