playMaker

Author Topic: Why Mechanim, when Playmaker already runs on States?  (Read 2128 times)

Thore

  • Sr. Member
  • ****
  • Posts: 480
Why Mechanim, when Playmaker already runs on States?
« on: June 04, 2019, 11:23:49 AM »
I am in the process of improving my Mechanim spaghetti, and encountered an ancient talk, from 2016, about Mechanim in Firewatch. The guy makes the astute observation that if you already have a state machine solution (we do), there's really no reason to use Mechanim, which is a state machine, too.


He says there are two general patterns, you'll need, the "blend tree" (states interrupting each other) and the "hub and spokes" (do one thing at a time). I don't like Mechanim, and would prefer if I could do it all (or most) in Playmaker, but I have no experience about the PROs and CONs of this approach.

Has anyone experience with a Playmaker-driven animation FSMs? Do you know a pattern which animation work can be offloaded to Playmaker, and which is best left in Mechanim etc? Pros and Cons?

Thore

  • Sr. Member
  • ****
  • Posts: 480
Re: Why Mechanim, when Playmaker already runs on States?
« Reply #1 on: June 04, 2019, 04:08:40 PM »
Alright. Some success and progress. Here is what I found out so far.

Old Setup
I already had an FSM for all the FX, sound and particles, and which also used to communicate with Mechanim. You can see some part in the lower left of the image below.

Other FSMs send out an event, like when jumping, or when grounding, typically as a game object wide broadcast, e.g. "JUMPING". Those FSMs who care about it, like this FX FSM then go to the respective state and do their thing. In this case, it used to play the particles, sound and also switched a couple of booleans around. For instance, isGrounded = false and suchlike. But this gets cumbersome quickly, and it doubles logic I already have in Playmaker.



New Setup
Now I have just two parameters, one for current running Speed and one Random Int to play random clips (I had this before, too).

I have a character script anyway for the stats, contained in scriptable objects, and I decided to directly update the animator. Here's the bit you need.

Code: [Select]
   

    Animator anim;
    Rigidbody2D rb;

...

 void Awake()
    {
        rb = gameObject.GetComponent<Rigidbody2D>();
        anim = gameObject.GetComponent<Animator>();
    }

    private void FixedUpdate()
    {
        anim.SetFloat("Speed", Mathf.Abs(rb.velocity.x));
    }


You can do this also with Playmaker in a single state FSM, but that's fast and direct, and I had a script there anyway.

Next, I only needed to machete the Mechanim jungle, and use the Animator Cross Fade to go to the Mechanim State I want directly. In Mechanim, I typically use sub-state-machines and blend trees, because I can easily add variations using the random int trick.

The landing > ground > running transitions are done by switching the state to action sequence (right click on action list), a wait action and another Animator Cross Fade. I find this better than using clunky transitions in Mechanim.

Randomizing animations is easy. Make an int parameter. In PM use Random Int and Set Animator Int to set this parameter some random number as specified. Next, when entering the sub-state add your different animation clips with the variations, and random int equal to X into the conditions, e.g. if RandomInt equals 1, play jump_01, if equal 2 play jump_02 and so on. You can super easily expand it that way. You can typically use and reuse just one randomize paramter in Mechanim for everything.

I guess with this setup, I can do most of the remaining animations, too.

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Why Mechanim, when Playmaker already runs on States?
« Reply #2 on: June 05, 2019, 03:11:23 AM »
Hi,

There are reasons still to use Mecanim, because it can run complex animations, which sometime can be easier to do using the Animation window. But...

 I myself started to use Mecanim more for UI and panels animations, and I eventually had to go back to using PlayMaker because of many bugs in Mecanim, it simply would start not working for one panel for no apparent reason... and so I concurr that if you think youc an do it in PLayMaker, do it, because it will give you a massive advantage should you start create slightly more complex features involving logic and controls, which mecanim can't do that well, so you can start animating while sending events and do some very complex logic at the same time.

Bye,

 Jean

Thore

  • Sr. Member
  • ****
  • Posts: 480
Re: Why Mechanim, when Playmaker already runs on States?
« Reply #3 on: June 05, 2019, 12:01:43 PM »
Thanks for your reply! It looks like I settle for a good mix of both. I still use Mechanim to actually play the animations, but cut off almost all logic (since this is done by PM anyway). I also use Blend Trees for a couple of verbs.

What Works For Me
... which may be subjective, my project is 2D

For this to work, you need to have "high level" states in Playmaker, which is listening to the logic, but should NOT interfere or drive the logic. FSMs logic/mechanics > State/FX FSM > Particles, Sound, Animation

I have just one exception: the running clip has an animation event to play footstep sounds in this FX FSM, where information flows in the wrong direction (animation > State/FX FSM). For now, that's fine, but that's an example where I need to keep an eye on it and if more comes up, straighten out the order again, and add FSMs that are controlled via animation clips.

Movement, Idle, Walk and Running:
Use a single Blend Tree with Motion fields. In Playmaker, cross blend to that Mechanim State when the player is grounded. No need to add boolean parameters like "isGrounded" and suchlike. Also no need to manage different Mechanim states, like idle and running state. But you'll need to fetch the movement values (e.g. velocity) and pass it over. See above for a script.

Jumping, Falling:
For a group of related states, make a sub-state-machine in Mechanim. You can still simply call your clip by the string you gave, but it hides the clutter. I now always do this as a matter of principle. As explained above, you can easily add animation variations, too. For this, you crossblend to an empty state (jumpUp in my case, above), and use the conditions in Mechanim to pick out a variant (as determined with the RandomInt, which you roll before each time the state is called).

The jump arc with different phases can also be done with a blend tree. See Unity’s Robbie Demo for how this works.

Skip to 12mins

One Shot State:
I always use a sub-state machine. You can drag and drop your clip over it to "drop it inside". I use it more as a container. The entry functionality is ignored, since I crossblend to my desired Mechanim state directly. Connect the state to the exit node, and it will run the clip once and then return automatically to your overall default node (e.g. the Movement state).

Temporary State:
If you want to go to a particular animation state and have it stay there unless otherwise called: Again, first make a sub-state machine in Mechanim  drop your clip inside it, but not connect it to the exit node. It will then get stuck there and play the clip. When you select an animation clip in the project, you can set it to loop or not loop.

Animation Layers
The standard crossblend action calls any state regardless on which layer it is placed. Which means you can easily also manage the states on other layers. For example, I have a layer for the hands, to switch between armed and unarmed hand stances. Make sure you set the weight of the layer (to 1 for full effect), and make sure that such clips only contain animation information that you want to be overwritten. E.g. if the hand layer also animates the feet you'll see glitches.

If anyone has some ideas, chime in! :)
« Last Edit: January 10, 2020, 04:43:36 PM by Thore »