Many games involve combat with various different types of weapons where each type has its own animations for attacking, blocking, and other common actions.
Mecanim
Setting up such a system in Mecanim is generally done by creating a base Animator Controller to define states, parameters, and transitions then creating an Animator Override Controller to replace specific Animation Clips inside it.
- Create an
AnimatorController
asset somewhere in your project and open it. - Assign the asset to the
Controller
field of theAnimator
component on your model. - Create the maximum number of states you might need in each category: light attack combos, heavy attacks, special attacks, taunts, etc.
- Create dummy
AnimationClip
s and assign them to each of those states to be overridden by a weapon at runtime. If your game includes unarmed combat, those animations may be appropriate for use as the defaults as long as every state has a clip assigned and those clips have unique names. - Give each weapon references to its associated
AnimationClip
s along with the names of the dummy clips they are to override. This is why the states all need dummy clips with unique names; you override clip names rather than state names. - Give your script a
public Animator animator
field and assign it in the Inspector. - Give your script a
private AnimatorOverrideController _AnimationOverride
field. - Initialize the override controller on startup (
Awake
,Start
, orOnEnable
):
_AnimationOverride = new AnimatorOverrideController(animator.runtimeAnimatorController);
animator.runtimeAnimatorController = _Override;
- When you equip a weapon, assign its clip overrides:
_AnimationOverride["DummyLightAttackClipName"] = weapon.lightAttack;
- Repeat for each clip to override.
Animancer
A similar result can be achieved much more easily in Animancer because you can simply play the animations of any weapon on demand without worrying about keeping an Animator Controller and Animator Override Controller in sync with your code whenever you need to change anything or track down a bug.
- Add an
AnimancerComponent
to your model. - Give your script a
public AnimancerComponent animancer
field and assign it in the Inspector. - Give each weapon references to its associated
AnimationClip
s. - When you want to play a particular animation, simply pass that clip into the
Play
method:
animancer.Play(weapon.lightAttack);
- If you have lots of different weapons and do not want to keep old states from previously equipped weapons in memory, you can destroy them when you change weapons by calling
animancer.States.Dispose(weapon.lightAttack);
.
The Weapons example demonstrates this concept in more detail.
Similar approaches to either of these could be used to allow game elements to specify their own interaction animations such as a special lever with a Pull
animation that isn’t used anywhere else.