Animator Override Controller on Animator Override Controller

Since we don’t have the ability to use the characters and animations for commercial use, I went and got a bunch of paid assets. The problem is they all have their own idle or locomotion motions. Image humans, ogres, dragons, etc.

One answer seems to be to use an Animator Override Controller to override what idle means per “character class”. But now we will have animator override controllers on top of animator override controllers when we add in weapons. (we also need to check for compatibility of weapon with character class but that seems like a good thing to do anyway).

But Animator Controller Override on top of Animator Controller override looks like its asking for trouble.

What’s the alternative? I’ve been poking around with Animation layers but that seems to be for things like changing the idle or walk animation if character is healthy vs injured.

It feels like another answer would be to use animation layers to change what happens when a different weapon is equipped and use animator override controllers to support different character classes. I would be happy to just have high level direction on an architecture here.

I don’t have an answer, but I believe ‘controller override inception’ is pretty standard. If you had a shield that has specific ‘block’ animations and a sword with specific ‘swing’ animations you would probably be layering animation controllers because you wont have an override for each possible shield/weapon combination that could exist. Then you bring in layers for how injured the character is, so that option is somewhat off the table.
It’s just my 2c. I would be interested in any answers, too.

Ok so let’s say I I have a human character as default. Then my fighter script initializes and I put on a default weapon, then my characterclass (or mover or whatever) script initializes and that also sets an override because it’s really an ogre and they walk differenty. But now I have to undo the weapon and override with a different weapon. But the weapon animation override is not at the top of the stack so what will happen when I restore the default?

I’m visualizing one would need code that looks like removal of a middle element from a linked list. Do I have this wrong?

Below is the course code from the WeaponConfig Scriptable Object

 private void AttemptRestoreToDefaultAnimator(Animator animator)
        {
            if (animator.runtimeAnimatorController is AnimatorOverrideController overrideController)
            {
                animator.runtimeAnimatorController = overrideController.runtimeAnimatorController;
            }
        }

I’ve tried a lot of solutions to this particular quagmire.

With humanoid characters (imported into the game as Humanoids in the Rig tab, things are mostly taken care of… For example, if your Ogre and your Knight are both Humanoids, then they can share animations and animator controllers.

Obviously that doesn’t work for dragons. When characters are generic, that’s when complications ensue.

I tend to keep my Animator Controllers unique to each character type… For example: In my current game, you could at any point be fighting against a human, a giant worm, a scorpion, a spider, or a skeleton (and I’m not done).

Now I could try to make a UniController and just throw overrides at every character. To be honest, I actually did that at first. Doesn’t take long to get confused, plus in my game I have multiple attacks, and I might have 8 axe animations, 7 sword animations, 10 unarmed animations, 3 spider animations, 4 scorpion animations, etc…

So ultimately, what I ended up doing was ditching the overrides altogether. This means a couple of things… All Animators for humans MUST have the same triggers/states outside of the Attack states… For the attack states, my WeaponConfig provides an string for the Trigger, and a percentage of regular damage. (I’m oversimplifying in explanation here). Since each WeaponConfig is paired with an animator, it’s fairly straightforward.

1 Like

So that doesn’t sound far off from one idea I had and it would actually be the easiest to get started with and delay needing to undo the AOC. So it would look something like this?

Humanoid Animation Controller

State: Locomotion
State: Death, Trigger die
State: Bow Attack, Trigger: bowAttack
State: Punch Attack, Trigger: punchAttack
State: 2H Sword Attack, Trigger: 2HSwordAttack
State: 1H Sword Attack, Trigger: 1HSswordAttack
… + other unique states and trigger

Zombie Animation Controller

State: Locomotion
State: Death, Trigger die
State: Lunge Attack, Trigger: lungeAttack
… + other unique states and trigger

Dragon Animation Controller

State: Locomotion*
State: Death*, Trigger die*
State: Fire Attack, Trigger: fireAttack
State: Claw Attack, Trigger: clawAttack
… + other unique states and trigger

Common Across All Animation Controllers:

common parameter spelling: forwardSpeed, die, stopAttack
common state spelling: Locomotion, Death

Other Notes

Motions associated with idle, walk, run, death, etc would be unique per Animation Controller but they MUST share same exact state and param spellings as above. This would allow a common interface for the health and mover script while allowing for zombies to walk differently from humans even though they might both have same Avatar.

This should still allow for Layers if one wants to add fatigued or wounded animations at some point in the future.

It sounds like Fighter would have a common interface too if you’re passing down the string from WeaponConfig (and probably converting to hash while you’re at it)

e.g.

        public void EquipWeapon(WeaponConfig weapon)
        {
            currentWeaponConfig = weapon;
            attackID = weapon.attackID;
            currentWeapon.value = AttachWeapon(weapon);
        }

        private void TriggerAttack()
        {
            GetComponent<Animator>().ResetTrigger("stopAttack");
            GetComponent<Animator>().SetTrigger(attackID);
        }

I’m using a mixture of the 3rd person course and the RPG course for Spellbound Hunter… So my rules are:
Die trigger, Death AnimationState
Locomotion for all locomotion states, the blend trees handle the specifics
Speed for locomotion speed.
LookAround Animation State required for PatrolPathStates to operate correctly.
Animations and Triggers must match, be callable from Any State, and return automatically to Locomotion.
Jump, Fall, and Land States required for all Humanoid controllers.
Here’s the Animator for my Scorpion (which is set up for InfinityPBR’s Scorpion:

For Humanoids, here’s a 2H Sword animator:


And thanks to a little [Attribute] magic, here’s how my WeaponConfig looks with each AttackVariant

I put an attribute tag in my AttackVariant struct which, if the AttackVariant is in a WeaponConfig class, gets all of the Animation States from the AnimatorController in the WeaponConfig and builds a popup, ensuring that no attacks will have invalid state indexes.

With the Trigger Names must match StateNames rule in effect, even though my EnemyStateMachine cedes control to the Fighter component, the Fighter Component can still call the Trigger and reach the same Animation State as the PlayerAttackState which directly calls the state. That being said, even as I type this, I’m asking myself why Fighter doesn’t just call CrossFadeInFixedTime instead of SetTrigger. I could dispense with the triggers altogether.

One other little trick I added you might notice with the Death state in the Sword controller is a Death state along with Death1 through 5… On the Death state for the Humanoid animators, I add a StateMachineBehaviour that in it’s OnStateEnter method switches to one of the random death states.

The various GetHit states I use in a Player State that triggers if the player gets hit and Random.Range(1,hitAmount) < remainingHealth. It then triggers the appropriate GetHit based on the angle the player was hit from.

Wow. Thanks.

Are you saying you have a different Animator for each (weapon type, avatar) 2-tuple? i.e. one for 2H sword human, one for bow human, one for fire ball human? Does that mean you swap the full character controller (no override) as soon as you swap the weapon?

One thing I don’t understand with this. How does the designer creating a new weapon know if they should select Attack1 vs Attack2 vs Attack3 for each attack variant they specify? Answer might depend on the above.

Yes, each weapon config has it’s own unique animator.
For Humanoids, I let the Humanoid Animation system deal with the avatar issues… in other words, an Orc, an Elf, and a Human walk into a bar wielding BroadAxes. They all use the same controller even though they have different avatars. But if one is using a Sword, he’ll have a Sword animator.

For monsters, those all have generic skeletons and their own sets of animations tailored for them. Therefore, each one gets it’s own WeaponConfig (to define the attacks) and Animator. The Spider animator looks different from the Scorpion animator (looks REALLY different from the Giant Worm animator).

Familiarity with the animations helps… I go through each Animation in the Animator and make sure that it has the Attack tag on it (that’s how the StateMachine knows you’ve finished the animation), that they have their Hit Events on them, etc. And I make a note of each animation and how much damage one would expect from it relative to other animations.
For example: The Unarmed animations include both punches and kicks. A kick to the shins is annoying, but doesn’t do much damage, not as much as a kick to the gut. Similarly, some punches are generally harder than others.

This gets a bit more subjective when it comes to monster animations… On that Scorpion, Attack1 and Attack1B are left and right swipes with the claws, so those are 100% power slashing attacks. Attack 2 is a puncture with the tail. That’s 150% piercing attack. It’s going to hit stronger than the slashes. Attack 3 (which I’m still working on the side effects) is intended to grab the target, hold him in place while the Scorpion bites the character twice, then releases the target. Each bite does 75% slashing damage, then releases the character. (I have the two bites, I’m working on making the grab look realistic.))

The Great Worm was quite a challenge… he has three attacks. One is a bite, straightforward enough, and does pretty heavy slashing damage. The next attack, the worm makes a sweep around the room with it’s body. I changed that to a collider based attack, which means that if you time it right, you can jump over the worm as the body passes. It does VERY heavy damage, but it’s Blunt. The third is an acid spray with a damage type of Acid.

Again, for each of these, it’s observing each attack within the Import dialogue, and then imagining what the effect of that attack may be. I make very liberal use of Animation Events to help with the effects. (The Spider, for example, has an attack where he leaps on you, and literally pushes you back with the force of his blow).

1 Like

Very impressive Brian. I won’t be doing anything this advanced any time soon, but I really do like seeing the end picture. I can plan my individual “sprint tasks” (so to speak) such that they incrementally build up to an end state. Or just stop if it’s good enough.

I would actually love it if the courses did more of this high level design. Rick if you’re reading this… you could imagine making advanced/premium course material where there is more high level architecture even if the course itself only fills in 20% of the architectural scope.

That’s pretty much how I go about it. One task at a time, revisit as needed. These aren’t all things I came up with overnight. I started Spellborn Hunter before the 4th course was even finished. I’m just bringing it to public beta, after several changes along the way (such as incorporating the Third Person Controller).

1 Like

Nice. Looking forward to release. What’s new in the Third Person Controller? Rotate view (like in TBS Course?)

For folks who wanted to hear more perspectives I posted this on the Unity Forums too but no one responded. The link is below so folks can follow if anyone decides to respond.

https://forum.unity.com/threads/alternative-to-stacked-animator-override-controller.1486989/

State machines, for one, and one of the best implementations of the new Input System you’re likely to find anywhere. While Nathan walks us through a Freelook and Targeting camera setup, I went a different route there and rolled my own script to manipulate the camera (with turning and zooming).

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms