Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Animation "Sets", 2D game, swapping controllers

Discussion in 'Animation' started by Nikovich, Nov 17, 2015.

  1. Nikovich

    Nikovich

    Joined:
    Jul 10, 2010
    Posts:
    69
    So say I'm making a game with a 2d character and this character has a number of weapons available. Each weapon has its own set of animations, combo1, combo2, jump, guard, etc.

    I've only dealt with characters that have limited animations so far, but I think I've got a decent handle on how the animator controller works. My question is, what would be the best way of sorting consistent animations with different weapons for a character? I know how I would do this in flash. I would just nest sets of animations by movieclip, so it would look like:

    Weapon 1 (Clip)
    - Idle (Nested Clips)
    - Run (Nested Clips)
    - Attack (Nested Clips)

    Weapon 2 (Clip)
    - Idle (Nested Clips)
    - Run (Nested Clips)
    - Attack (Nested Clips)

    And so on.

    I've done some searching on the forums, so I know swapping animator controllers at runtime is possible. Would the best action be to create a separate animator controller per weapon, each with its own set of animations that I know would be consistent (combo1, combo2, jump, guard)? Or are there any problems or reasons why I shouldn't do this, and just stick with throwing all the animations into one controller and naming them "weapon-animation." Or should I do something wacky and have different animator controllers, put one on their own individual gameObject within the character sprite, and hide the ones without the currently equipped weapon?
     
  2. Guessmyname

    Guessmyname

    Joined:
    Feb 12, 2011
    Posts:
    24
    This is really one of those problems the upcoming Playables API is meant to solve, but unfortunately it's still in the development stages at the moment (you can try using it - documentation is in the Manual - and it mostly works, it's just very crash prone right now); with Playables you can blend AnimationControllers, so you'd naturally swap from one to other.

    In your case, given your character is 2D (and hence I assume sprite based), you're actually in luck; you may as well just swap controllers directly (Animator.runtimeAnimatorController) on a per-weapon basis. The big thing about swapping controllers at runtime is that they have to reinitialise when changed, which breaks smooth transitions for 3D characters but can be mitigated for 2D characters (since you're animating in discreet frames anyway).

    In terms of actual methodology, you generally only want one AnimationController to serve as a template, and then use AnimationOverrideControllers to redefine what clips should be playing in what state; so you have your AnimationController setting up all the states and transitions for, say, running and jumping around, and the Override to define the animation clips for running and jumping around with a sword or rifle or whathaveyou.

    The fun part will be the attack animations. Again, best advice I can give to template them; if you have a bunch of different weapon types that behave differently from each other (ie ranged weapons and melee weapons) and so need their own systems of animation states and transitions to operate, build them into the Controller itself with an int property to define what 'type' of weapon the character is wielding (ie weaponType = 0 for melee, weaponType = 1 for ranged, and they go to different substate machines). Again, the Controller should define states and transitions and the specific Override the actual animations.

    One last thing to be careful of is StateMachineBehaviours. Since they're defined per state, you can't change them with Override Controllers, but if you add your events into the animation clips themselves (as an import option / in the Animation view), they can be defined on a per-animation basis and swapped out as needed; when to spawn projectiles or activate/deactivate hit detection for example should be per-animation rather than handled by a StateMachineBehaviour. SMBs are also destroyed and recreated when an AnimationController is swapped out at runtime, so be careful about referencing them from scripts on gameobjects; you'll need to reacquire them every time the Animator reinitialises.
     
    theANMATOR2b likes this.
  3. Nikovich

    Nikovich

    Joined:
    Jul 10, 2010
    Posts:
    69
    Yeah, everything is frame based. I'll keep override controllers in mind when I need a 3d character to smooth transition though. I've never looked at that component before, it seems very similar to my original idea of swapping animator controllers, but actually the way it should be done. As I'm familiar with the base controller and not familiar with overrides, I'll just try swapping with runtimeAnimatorController unless there are issues.


    Aren't SMBs added to each animation state though? Maybe I don't understand how override controllers work, but I thought in either case, both would use separate animation clips, in which case the SMBs would be swapped with them. Or, since it's supposed to be replacing the same structure as the original controller, do the SMBs only apply to those original clip slots, and the new animations in those areas of the tree receive those same SMBs?
     
  4. Guessmyname

    Guessmyname

    Joined:
    Feb 12, 2011
    Posts:
    24
    Using an Override controller is literally the same as swapping out runtime controllers, you just set Animator.runtimeAnimatorController to point to the Override rather than a different controller. It just redefines what clips are tied to what states in its parent AnimatorController.
    (The main advantage is mostly in debugging and parameters; you'll only need to maintain the one AnimatorController rather than propagating fixes / changes to a whole swathe)

    SMBs are defined on a per-state basis yes, but they're instantiated as a part of the runtime controller. So when you swap runtime controllers, the SMB instances in the old one go with it and new instances are created for the new one. This really only matters if you're using a script with Animator.GetBehaviour/s somewhere; it returns SMB instances which you'll need to reacquire whenever runtimeAnimatorController is changed.

    Generally speaking best practise if you're doing a lot of controller swapping is not to access SMBs externally; instead let them find whatever they need to work with off the Animator via GetComponent et al from the State/StateMachine Enter functions.
     
    Ccrawler likes this.