So I’m using an avatar mask to isolate the upper body from the lower body on my character. It’s setup like so:
I want the idle animation to play on the hips and legs, and an attack animation on the chest and arms. This is the idle animation:
This is the attack animation windup with no mask applied, the entire animation is playing on all bones:
This is the attack animation windup with the upper body mask from above applied. I have the layer set to override for this animation. The legs stay in place like on the idle animation, which is great.
However, you see how the upper body is rotated? That’s not what I expected. I can only assume the upper body is being rotated according to the hips, with the hips taking it’s information from the idle animation.
I think I want to override the hips when the attack animation is playing, but I’m not sure how I’d go about that. You can’t pick and choose which transforms to mask because it’s a humanoid animation.
I’m bumping this because I as well am having this issue. It seems that Unity’s Humanoid system in regards to fine tuning it are non-existent. The humanoid avatar system doesn’t split the upper torso and hips into two different regions, rather it clumps it all into one or the other.
But they’re fairly vague and I’m new to animation, so I haven’t been able to figure out exactly how they are using a proxy joint that allows them to get the chest rotation that matches the animated values and ignore the influence of the hips.
That article succinctly explains all the issues I’ve ran in to. However, they appear to be using animations specific to their model, which they can import as Generic instead of Humanoid and obtain the benefits of specific bone masking. That throws their proxy joint fix out the window for me.
Over the last week I’ve been experimenting with different methods to try and isolate the chest from the hips. One method is described in a post I made over on the scripting forums here . What that entails is having a dummy play the whole upper body animation with no masking, and copying the rotation from they spine over to your actual character in LateUpdate(). This method leads to the spine twisting unrealistically at times, but it works.
So I decided to experiment with Animation Rigging to rotate the hips and keep the legs in place. I failed miserably in trying to come up with a solution, although I’m certain one exists with Animation Rigging.
I had FinalIK laying around doing nothing so I threw it in the game. With it’s FullBodyBipedIK rig, you can set up all kinds of targets for bones. So what I wound up doing was using the dummy method, but instead of copying over bone rotations, I set up the FullBodyBipedIK effectors to the dummy bones. After fiddling with some of the weights and adjusting knee and elbow hints, I’ve come up with something that works pretty darn well. FinalIK takes care of rotating the hips and legs according to the upper body animations while leaving the feet in place where the lower body animations have them.
That’s great news. I’m making a full body awareness FPS based off of NeoFPS and his setup didn’t play nicely with Final IK. However the Animation Rigging tools via that article did point out a solution with using several constraints that helped keeping the torso forward while respecting animations and hip rotations. It’s frustrating that over the years they haven’t increased the robustness of the humanoid system or even the generic on.
I have been looking for easy solution to the problem… for almost a year now and still haven’t found any reasonable workflow which allowed to solve the problem.
Anyone has any ideas on how to solve it? Re-rigging your character with extra bones and adding IK constraints sounds like hell of the effort here, especially if you have many animations / characters.
There’s no easy solution for this - hips rotation diff between poses is too big, so whatever system on top of that you’re going to use: masking, animation rigging additive pose corrections, finalik, etc. it will always look bad (either wrong rotations or excessive stretching of the mesh), unless you modify animations in DCC (Blender for example) so that poses you want to blend, will have key bones as close as possible, in terms of position / rotation.
I am a relative newbie in animation.
But respectively, i think that the issue is not how animations are blending and whether the look is natural.
It seems that right now when a new layer overrides rotations of base layer in animator, it overrides values of rotations relative to the parent bone (FK rotations). Since the parent bone is not overriden and belongs to different animation, it leads to weird result.
All we need to correct for this is an option to use IK rotation of current animation for a bone in cases when its parent belongs to a different layer.
Yeah, we can discuss this in lengths, anyway, if effect you’re aim for is legs from idle, upper body from the attack, I see following options to try out:
fix animations
apply IK (custom code in IK callbacks) to upper body bones to look at the vector of the attack, thus fixing head, arms, chest bones rotation
I’d strongly suggest also to check out Animation Rigging package from Unity - it’s comes pretty handy in such situations. In my project, I use single animation Idle for upper body on enemies to aim at the player, track him, change mags and what’s not - all procedural, with the Animation Rigging.
Fixing animations sounds like… a harder approach. And, technically there’s nothing wrong with the animation: it is the issue of merging base animation with the animation for the upper body one. However, what you want there to do is to, essentially: for override layer, for the highest active bone in the avatar mask, bake rotations of the parents into it - which sounds to me like non-trivial problem.
As for the second approach, it is also not so fool-proof, as it it is implemented by plain direction vector, the upper body animation will change (imagine a character which does a full swing and rotates his spine - fixing the spine to the direction of attack would not work). What you need here is to: a) apply rotation of the hips in the animation in the override layer; b) compensate for hips rotation driven by base layer at every single frame. In this way, IK position of spine will stay the same.
The v-rising article suggested to do the following:
creating an extra bone, which mirrors IK rotation of the spine, but way above in hierarchy - so it is unaffected by any parental rotations; and it still captures the combined rotations of hips and spine in the animation on this layer.
in the resulting animation, chaining IK rotation of spine to this new bone. In this way, no matter what parent (hips) are doing, the spine is always in same relative rotation to the root.
I know how to make every single step here, but it means creating extra bone for every character, copying bones in blender… arrgh. I was wondering if there’s simpler, code-wise solution to this problem, as I’ve seen at least several posts (and now an article) dedicated to solving this; yet none arrived at a reasonable answer/workflow there.
I’d advise against modding rigs / bones hierarchy, esp. as a bandage for a very specific problem - you will have a hard time later on keeping track of all such changes.
Your original rig, and a dummy rig that is a copy of the original
The dummy rig is placed as a sibling of the original one in the hierarchy, and have its own animator component
You then make a copy of you animation controller and remove the mask on the combat layer, and attach it via an animator component to the dummy rig so it is performing the full attack animation both upper and lower body.
To not deal with double animation parameter input,
You can add a script with an update that copies all input parameters (this will not work with triggers, so you need to make these into bools, which they basically are anyway)
public class AnimatorParametersCopier : MonoBehaviour
{
public Animator sourceAnimator;
public Animator targetAnimator;
void CopyParameters()
{
if (sourceAnimator == null || targetAnimator == null) {
Debug.LogError("Source or Target Animator is not assigned.");
return;
}
foreach (AnimatorControllerParameter parameter in sourceAnimator.parameters) {
switch (parameter.type) {
case AnimatorControllerParameterType.Float:
targetAnimator.SetFloat(parameter.name, sourceAnimator.GetFloat(parameter.name));
break;
case AnimatorControllerParameterType.Int:
targetAnimator.SetInteger(parameter.name, sourceAnimator.GetInteger(parameter.name));
break;
case AnimatorControllerParameterType.Bool:
targetAnimator.SetBool(parameter.name, sourceAnimator.GetBool(parameter.name));
break;
case AnimatorControllerParameterType.Trigger:
break;
}
}
}
void Update()
{
CopyParameters();
}
}
Lastly you copy the rotation of the spine bone from the dummy to the real rig
public class BoneRotationSyncroniser : MonoBehaviour
{
public Transform boneReal;
public Transform boneDummy;
void LateUpdate()
{
boneReal.rotation = boneDummy.rotation;
}
}
This gets the job done
I couldn’t get this to work without the skinned mesh renderer on the dummy
So I just remove the material from it
Thanks for the tip. I’m doing something similar with Final IK and two rigs. I like your AnimatorParametersCopier, I was just straight updating both at the same time.