But I’m testing this on 4 different rigs and getting inconsistent results because of the default orientation of hand bones - also screwing it up is the axis of the hand bones.
Currently the weapon is put into the hand like this:
bonetransform.right is X aiming down the arm. Some rigs have it inverted… This part actually works great. The weapon sets in the hand perfectly every time even with totally jacked up bone setups.
Then the weapon it parented to the hand bone and I make IK calls to put the hand bone where I want it, but then I need to rotate the hand so that the gun actually points forward but I can’t seem to figure out the rotation math to do it. I’m stuck here.
I’ve tried various things to get the rotation but bottom line I can’t figure out how to compensate for the base hand rotation offset variance even when I know all of the correct variables. ThumbDirection and X direction should be enough to formulate a signed direction but I need some help figuring out doing this with the rotations respecting that.
Tried posting this on Answers, but for some reason my posts now go to Moderation?
The Weapons set into the hands correct, the IK just doesn’t seem to set the rotation precisely. Tried some options with layering in the Animator too, didn’t seem to change anything.
Here is a helpful class to test you hand ik target
create a new scene
add you character with script below attached
create a sphere/cude and drop it to rightHandIKGoal variable
instead of using this Quaternion.LookRotation(SubjectObj.transform.forward) you can just change the position/rotation of the rightHandIKGoal, I think it’s much easier and intuitive
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class HandIK : MonoBehaviour {
public bool enabledIK;
public Transform rightHandIKGoal = null;
Animator animator;
// Use this for initialization
void Start () {
animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update () {
animator.Update(0.0f);
}
void OnAnimatorIK(int layerIndex)
{
if (enabledIK)
{
animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1.0f);
animator.SetIKRotation(AvatarIKGoal.RightHand, rightHandIKGoal.rotation);
animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1.0f);
animator.SetIKPosition(AvatarIKGoal.RightHand, rightHandIKGoal.position);
}
else
{
animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 0.0f);
animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 0.0f);
}
}
}
Yes but the problem is that the hand does not align to the given target. There is some sort of offset from the rig that the IK does not take into consideration.
Thats why I’m building a rotation to add to it to make up the difference, but my efforts to do that haven’t been working.
Here’s the current code, which basically produces the same result as the LookRotation() alone.
Red line are actual, green lines are what it should be.
The zombie is the worst rig, the other 3 are pretty good but all yield different offsets. In any case, the detal calc and multiplication isn’t working to fix the issue.
Yes, its just a shorthand method. The code should be getting the delta rotation between where it should be pointing and where it is pointing, then adding it to the desired rotation to compensate for the offset. It doesnt seem to work.
I need to pragmatically fix the rotation, i can’t manually do it in the inspector for each character because it will never be exact. The entire problem is that SetIKRotation is not setting the rotation correctly, there is some inherit offset from each model’s hand rotation that is screwing it up and must be fixed pragmatically.
Thanks, here is what I’m doing for the debug rays.
void Update()
{
Debug.DrawRay(RightHandBone().position, RightHandBone().right * 2, Color.red);
Debug.DrawRay(RightHandBone().position, SubjectObj.transform.forward, Color.green);
// the zombie's X is actually inverted, so you need -RightHandBone().right
}
Technically this problem should be evident on any rig, I’ve used 4 different ones with the same Animator Controller and they all exhibit some amount of offset caused by how the model is rigged/setup which Mecanim’s retargeting does not compensate for.
The goal is to get the hand to orient inline with a given direction.
Ok either I’m going crazy, or there is some magical hand rotation offset buried in the Humanoid rig that you have to have to use to get the hand to point at something properly.
if (DummyTarget) Animator.SetIKRotation(AvatarIKGoal.RightHand, Quaternion.LookRotation(DummyTarget.position - RightHandBone().position));
I’m at wits end. It seems like a bug at this point. The wireframe of the IK target isn’t even in the right spot!
The only way that even sort of works is adding a ‘correction’ vector to the LookRotation(), then tweaking it until it looks straight and applying that to the prefab. It’s not perfect, but it seems like the best that can be done at this point.
FYI for those interested I filed a bug report on this last night and it was repro’d/accepted this morning. (<12 hrs[!])
You can also get the delta quaternion and iterate closer to the correct direction, I was just doing the math wrong. It still doesn’t seem to get it perfect, but I think that has something to do with the same issue thats causing the offset to begin with. The same exact code in Debug rays does what it is intended to do.
@LaneFox So we did investigate this issue and the offset that you see is related to your avatar T-pose. If you want a perfect match you need to align your hand characterization pose on the X axis.
@Mecanim-Dev Ahh, I found where you can adjust the bone rotation in the Avatar Configuration screen. Was not aware we could make changes there. Did not test to confirm yet - out of town all this week.
Is there a way to auto-align this or bind the avatar into a known T-pose that will alleviate alignment issues like this one? It’s not ideal to have users manually adjust their avatars by eyeballing the hand alignment, especially so if you need to rely on the hand pointing in a specific direction with consistency.