Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Poor man's motion matching

Discussion in 'Animation' started by snacktime, Jul 27, 2019.

  1. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    Wanted to throw this out for some feedback.

    So first off our use case is fairly simple, and I'm looking at this more as a general strategy, how you might implement it with IK or advanced blending isn't really that important,it's more about where does the larger strategy work, or where it fails.

    The part that stood out to me the most wasn't so much how they select animations. Ie the brute force loop through and score each one. What stood out to me was the idea of evaluating a number of data points to arrive at a general target.

    With a state machine approach you generally have separate parts of your code making partial decisions. Like your combat system does an attack, it tells your animation in system I want to play an attack animation. But that code doesn't know about your movement speed, it probably doesn't have information about was the attack blocked, did the character die halfway through, etc.. So a lot of animation systems have multiple points in the code making these requests without full information, and then somewhere you have to sort it all out. And where you sort it out doesn't really have perfect information either. It knows an attack animation was requested, but it doesn't have any context for why that decision was made.

    So why not just start with a system that works by collecting all the data points needed to make a complete decision as the starting point. Then you can make a decision once based on complete information, and it's neatly encapsulated.

    So a poor man's version of the actual motion matching might just be arbitrary lookup tables. The higher level flow is what enables motion matching to even work, and seems like a superior approach just on it's own. How far you take the actual motion matching itself remains very flexible and could change over time, I don't think it's something that needs to be all or nothing.

    Thoughts?
     
  2. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    FYI another reason I liked this approach was it would be easy to jobify and keep main thread time to a bare minimum. With jobs producing output that you just feed directly to the animation api with little to no evaluation of anything necessary. Maybe some simple switch statements for different api commands.
     
  3. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,554
    It sounds like you're overcomplicating things.

    When you play an attack animation, that code doesn't know your movement speed because it has no reason to know. You could easily give it access to that information, but you would gain nothing by doing so.

    If you need to know upfront whether an attack is blocked, then that's something you can build into your system to choose which animation to play based on that condition.

    When my code tells it to play an attack animation, that means I want it to play an attack animation. The cause and effect is always clear. Player presses button -> attack. Enemy hits player -> flinch. Player runs out of health -> die. Having it decide on its own to play a different animation seems like a great recipe for creating bugs that are hard to track down.
     
  4. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356


    It's not a case of the animation system can decide that an attack should be something else. It's just moving that decision to a different place. Your combat system has no business deciding what animation to play really. Features should be firing events or providing data in some form that your animation system can consume, and use that to decide what animations to play.

    In anything this reduces complexity in all but the simplest of animation flows. And more complex scenarios become much easier because I'm just working with data directly. I'm not working with a request that's actually an interpretation/second hand data. Making good decisions on that is nearly impossible.
     
  5. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,554
    I disagree. Whatever system says "this creature is attacking" should also be saying "play the attack animation" and whatever system says "this attack will be blocked" should also be saying "play the attack-blocked animation". The animation system should be playing animations, not making decisions. The decision has already been made by the combat system, so your suggestion would just mean the decision has to be implemented twice in different systems, which means more complexity and more opportunities for bugs.
     
  6. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    If you separate concerns it's not making the same decision twice, it's different things. And by the animation system I was more referring to it in a general sense, you would have separate abstractions there for the scoring and actually calling into the Unity animation system.

    Also this is really the basis for solving much more complex scenarios using scoring systems. Scripted systems whether it's state machines or something simpler don't scale well with complexity.
     
  7. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,554
    If you separate concerns correctly it's not making the same decision twice. But what you're suggesting means that the combat system needs to make decisions based on whether the attack was blocked or not and then the animation system also needs to make decisions based on the same condition.

    For the vast majority of situations, there is no need for any sort of scoring system because you want simple cause and effect as I said before. And you can't really expect anyone to form a real opinion about "complex scenarios" which haven't been explained at all.
     
  8. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    Why would you assume it would not be abstracted correctly?

    For the combat example, in our game and most multiplayer games the logic for initiating an attack and the result of said attack, would be completely separate. In fact most animations would be the result of data from completely separate systems, sometimes 3-4 actually. Plus the logic that initiates an action is almost always a step or two removed from where it's fired.

    I didn't explain complex scenarios because that's actually kind of a key selling point of MM, anyone who has read about it would understand what some of those are.

    Simple cause and effect doesn't really describe the challenge of animation very well. Being simple is an arbitrary constraint. We simplify things all the time due to cost. MM is simply an approach that can remove some of those constraints because for a certain set of problems it can solve them at a significant reduction in cost.

    As an indie you can't afford to compete head to head with larger studios in areas that are capital intensive. You also can't afford to ignore approaches that scale well in terms of cost. Especially not when the competition is starting to use those, which in this area they very much are.
     
  9. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,554
    Because you described it like that.

    You talked about a combat system triggering an attack animation and not knowing whether the attack was blocked or if the target dies during the animation. Those are simple events that the combat system needs to know about and react to in various ways including triggering animations. You are suggesting that the decision to trigger those animations should be handled by another system because you think of it as a "separate concern". You're taking a single Play(attackBlocked) or Play(attackNoTarget) or Play(idle) method call and replacing it with a separate system that needs access to the same data in order to make the same decision. That seems like a textbook example of unnecessary abstraction.

    I gave you my thoughts about what you actually described, not an unspecified "certain set of problems". And for what you described, simple cause and effect absolutely does describe the situation.
     
  10. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    I said the abstractions exist already outside the animation system. You have no basis to second guess them you have no clue what our game looks like and what good abstractions for it would be.

    I'm not even interested in simple approaches like you describe, those don't solve interesting problems. I'm thinking along the lines of what is a solid base flow that can work well with approaches like MM. Your simple paradigm is a non starter there. The set of problems to solve are inherently way too complex.
     
  11. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,554
    Simple approaches like I describe solve the problems that you actually described.

    I have no basis to give the feedback you requested about your vaguely described idea in relation to a use case which you have not described. Maybe what you want can be done with simple methods, maybe your idea won't work and you'll need proper motion matching, I have no idea because you refuse to explain it beyond those simple examples you gave.