Search Unity

When is a transform's forward vector not actually forward?

Discussion in 'Animation' started by JoeStrout, Dec 5, 2013.

  1. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    As noted in this other thread, I've been playing with ragdolls today. There's a bit of code that's supposed to select the appropriate stand-up animation, based on whether the hips are pointed up or down.

    This seems to work fine for a model where the hips are also the root transform. In the model I'm trying, however, the hips are right under the root transform, and I'm finding that transform.forward does not actually point in the direction it seems like it should.

    To shed some light, I added this debugging code:

    Code (csharp):
    1.         Transform hipsT = anim.GetBoneTransform(HumanBodyBones.Hips);
    2.         Debug.Log(gameObject.name + " " + hipsT.gameObject.name + ": " + hipsT.forward);
    3.         Vector3 forward = hipsT.forward;
    4.         for (Transform p = hipsT.parent; p != null; p = p.parent) {
    5.             forward = p.TransformDirection(forward);
    6.             Debug.Log("  ...transformed by " + p.gameObject.name + " gives " + forward);
    7.         }
    8.  
    I have here two experiments: in the first, the character fell face-up, and I got this output:

    Dwarf Bip003 Pelvis: (-1.0, 0.0, -0.2)
    ...transformed by Bip003 gives (-0.1, 0.8, 0.6)
    ...transformed by Dwarf gives (-0.1, 0.8, 0.6)

    OK, so more or less straight up, sounds good. Then in the second experiment, the character fell face-down. Hips were clearly pointed down into the ground. And yet I got this output:

    Dwarf Bip003 Pelvis: (0.6, 0.3, 0.7)
    ...transformed by Bip003 gives (0.5, 0.8, -0.4)
    ...transformed by Dwarf gives (0.5, 0.8, -0.4)

    Still more or less "up," according to the numbers. But that's not right — the dwarf was facing down. I'm stumped! Anybody know what might be going on, and how to find the "true" (world-space) forward direction for a transform in a hierarchy?
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Well, it took a while, but I think I've got it figured out. The problem is that I was assuming that (0,0,1) (which is Unity's idea of "forward") actually matched the direction I'm calling forward when I look at the scene. This isn't true because of the way this particular model is constructed; the hip bone starts out with a rotation of (270,90,0), so its local forward is sticking off to the side. (And this isn't noticeable because

    I think I can work around this by sampling the "real" forward direction — that is, out in front of the belt buckle — at startup, by converting from world to local coordinates:

    Code (csharp):
    1.     probe = transform.InverseTransformDirection(new Vector3(0,0,1));
    ...and then when I want to know which way that belt buckle is facing, use that instead of .forward, like so:

    Code (csharp):
    1.    facing = transform.TransformDirection(probe);
    For this particular model, at start, my "probe" direction comes out as (-0.3, 1.0, 0.0), which is quite different than what I was thinking. And when I transform that back, it reliably points in the direction the model's actually facing.

    Whew! Hopefully this will prove useful to somebody. :)
     
    samyam_ likes this.
  3. 01011110

    01011110

    Joined:
    Feb 2, 2014
    Posts:
    1
    I tried this, and applied a force in the direction of the new vector3 "facing" and my object always ended up going directly forward in relation to the world, not itself.