Search Unity

Animator.SetLookAtPosition

Discussion in 'Animation' started by rchavarria, Sep 17, 2014.

  1. rchavarria

    rchavarria

    Joined:
    Nov 20, 2013
    Posts:
    5
    Hey everyone,

    I've been trying to get Mecanim's SetLookAtPosition() to work, to no avail. I've done this type of head look systems manually in the past, using the legacy system and LateUpdate(), but I cannot for the life of me, get Mecanim to cooperate and orient the Neck.

    I've tried doing this in FixedUpdate(), OnAnimatorIK() and LateUpdate(), but nothing is working:

    Code (CSharp):
    1. if (_lookAtPosition != null)
    2.             {
    3.                 animator.SetLookAtPosition(_lookAtPosition.Value);
    4.                
    5.                 _lookAtWeight = Mathf.Lerp(_lookAtWeight, 1.0f, Time.deltaTime);
    6.                
    7.                 #if ENABLE_DEBUG_DISPLAY
    8.                 if (animator)
    9.                 {
    10.                     Transform animTX = animator.GetBoneTransform(HumanBodyBones.Neck);
    11.                     if (animTX)
    12.                     {
    13.                         Debug.DrawLine(animTX.position, _lookAtPosition.Value, Color.red);
    14.                     }
    15.                 }
    16.                 #endif
    17.             }
    18.             else
    19.             {
    20.                 _lookAtWeight = Mathf.Lerp(_lookAtWeight, 0.0f, Time.deltaTime);
    21.             }
    22.            
    23.             _animator.SetLookAtWeight(_lookAtWeight);
    The debug line I have clearly shows properly between the character's neck joint and the target position, yet I never get the character to orient properly. I downloaded the MecanimTute and looked at the code and it seems they are doing EXACTLY the same thing I am. That tutorial has a problem where the head snaps back and for, so I'm wondering if there is an Unity bug causing problems.
     
  2. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    The right place to call this is in OnAnimatorIK() callback, also you need unity pro to get Mecanim IK.

    Also it seem to me that you are not using Mathf.Lerp corretly.
    http://docs.unity3d.com/ScriptReference/Mathf.Lerp.html
    first two argument are minimum and maximum and the third argument is the weight which should go from 0 to 1, right now you are using Time.deltaTime which is almost always the same value ~0.02 depending of your frame rate and project settings
     
    PQ-kazuki likes this.
  3. rchavarria

    rchavarria

    Joined:
    Nov 20, 2013
    Posts:
    5
    I am using Unity Pro for this, this is how I tested the your MecanimTute I spoke about in my post.

    Also, I'm using Lerp properly. The lower value of the range changes constantly, so the result of Mathf.Lerp will be scaled on a decreasing range, creating a curve that slows down the Mathf.Lerp towards the end. This is EXACTLY how it's used in the MecanimeTute also:

    Code (CSharp):
    1. lookWeight = Mathf.Lerp(lookWeight, 1f,Time.deltaTime * lookSmoother);
    The problem is that documentation and tools for Mecanim are so sparse, that it's nearly impossible to tell what is going wrong. The Animator window doesn't tell the user what LookAtWeight is currently set on the controller, or what LookAtPosition it is aiming towards.
     
  4. rchavarria

    rchavarria

    Joined:
    Nov 20, 2013
    Posts:
    5
    After further investigation, it seems like this is a problem with how we have setup our models.

    The first model I tried it with has multiple meshes to define certain body parts that we can swap at runtime. HeadLook didn't work in this instance.

    The second model I tried it with has a single mesh. HeadLook works properly with this model.

    Is there any limitation (no multiple meshes, etc) on what we can do for HeadLook?
     
  5. rchavarria

    rchavarria

    Joined:
    Nov 20, 2013
    Posts:
    5
    I was able to solve this. The problem was that our animations were using a Generic animation import instead of Humanoid with the Avatar copied from the base model.

    Tools should be improved to show this kind of problem, as there is 0 indication of what is going on.

    We now have to deal with weird animations caused by the Humanoid stuff.

    Is there a way of controlling Mecanim-animated bones manually? I don't mind writing my own code for look at, it would have taken a fraction of the time it took to figure out all the Mecanim intricacies.
     
  6. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    The thing is that this is a valid workflow, you can have a generic animation clip inside your controller even if the destination is a humanoid avatar. This is often used to animate extra bone, like wing, tail on another animation layer.

    Yes you can control the bones manually. It should be done in MonoBehaviour.LateUpdate(), this callback is called when all other system have finish updating the scene

    You have a good point here, so we did add an animator gizmo in unity 5.0 that show you all the IK goal target, look at target, mass center and root position. There is no feedback for the weight but that could be improved.

    No there is no limitation, we have some examples with multiple mesh working, maybe it related to how your skinning is done. You should log a bug with your scene if you think there is something wrong.

    What kind of weird stuff?
     
  7. rchavarria

    rchavarria

    Joined:
    Nov 20, 2013
    Posts:
    5
    Thanks for your detailed response.

    I understand. I guess the only way to know is to know and there is no easy way to determine this?

    Yeah, I got this working after I posted. Thanks!

    That will definitely be useful to tell what is going on.

    For some reason some of our characters look like they are in the "Mecanim muscle editor animation". Some of our animations seem to try to do foot IK when it is disabled, We also have misaligned weapons that were attached to bones previously.