4
\$\begingroup\$

this is the code for rotating spine in my character model:

Transform spine;
float horzMovement;

void Awake() {
    spine = transform.Find("Character/Healthmale/Root/pelvis/spine_01");
}

void Update() {
    horzMovement = Input.GetAxis("Mouse Y");
}

void LateUpdate() {
    spine.localRotation = Quaternion.Euler(
        spine.localEulerAngles.x + horzMovement,
        spine.localEulerAngles.y,
        spine.localEulerAngles.z
    );

    print(horzMovement + " / " + spine.localRotation.eulerAngles.x + "    " + Time.time);
}

Code is quite simple, I'm just rotating "X" axis from y mouse movement. The problem is when running this code, it seems work but it keeps rotating back to the original rotation.

This is the log that I printed into the console. Note that spine's original x rotation is about 27.62928.

0 / 27.69298    4.510662
0 / 27.69298    4.527147
-0.1 / 16.33139    4.543715    // minus movement detected
-0.1 / 16.3314    4.560284
-0.1 / 16.33139    4.57685
-0.1 / 16.33139    4.593714
-0.1 / 16.3314    4.609998
-0.1 / 16.33139    4.626548
-0.1 / 16.33139    4.643115    // but it seems not much changed, why?
-0.15 / 10.51222    4.659858
-0.15 / 10.51222    4.676248
-0.15 / 10.51222    4.692952
0 / 27.69298    4.759083       // this is when I stopped the mouse. It's reset.
0 / 27.69298    4.775648

As you see the above log, first time, it prints 27.692.. and it's original x rotation of spine.

Next, I moved my mouse so the "horzMovement" value was updated to minus, and it updates x localRotation also.

But when I stopped move mouse, it just return to initial x rotation 27.69298!

There is no code or functionality to "rotating back" to original rotation of spine. I don't know why this is happening. Wham am I missing?

Any advice will very appreciate it!!

\$\endgroup\$
5
  • \$\begingroup\$ Do you have an animation / animator affecting this character? This may be setting the spine back to its animated orientation each frame, before your script gets at it. \$\endgroup\$
    – DMGregory
    Jul 27, 2017 at 11:47
  • \$\begingroup\$ @DMGregory Yes yes, I have animator and it's animating! Then how should I solve this problem? \$\endgroup\$
    – modernator
    Jul 27, 2017 at 11:52
  • 1
    \$\begingroup\$ This depends a bit on your context. You could use animation layers to mask out its influence on this spine bone, or accumulate the desired rotation yourself rather than counting on it persisting frame to frame unchanged after animation. \$\endgroup\$
    – DMGregory
    Jul 27, 2017 at 12:16
  • \$\begingroup\$ @DMGregory Thanks! I achieved by saving previous x rotation and keep adding here! Please write your comment as answer so that I can accept your answer. \$\endgroup\$
    – modernator
    Jul 27, 2017 at 12:45
  • \$\begingroup\$ Go ahead and show the code you used in your own answer. There's no rule here against answering your own questions. :) \$\endgroup\$
    – DMGregory
    Jul 27, 2017 at 13:00

1 Answer 1

3
\$\begingroup\$

I solved this problem by follow DMGregory's saying: "Accumulate the desired rotation yourself rather than counting on it persisting frame to frame unchanged after animation".

This is the code:

Transform spine;
float horzMovement;
float prevSpineX;

void Awake() {
    spine = transform.Find("Character/Healthmale/Root/pelvis/spine_01/spine_02/spine_03");
    prevSpineX = spine.localEulerAngles.x;    // Save initial X rotation of spine
}

void Update() {
    horzMovement = -Input.GetAxis("Mouse Y");    // Invert direction so that aiming down results look down!
}

void LateUpdate() {
    spine.localRotation = Quaternion.Euler(
        prevSpineX + horzMovement;    // Calculate new x rotation by adding mouse movement and previous spine's X rotation
        spine.localEulerAngles.y,
        spine.localEulerAngles.z
    );

    prevSpineX = spine.localEulerAngles.x;    // Update previous x rotation to current rotation
}

I hope answer might help your problem. Special thanks for DMGregory who gaves me a good advice!

\$\endgroup\$
3
  • \$\begingroup\$ You can check your own answer as accepted (the green Check icon under the answer score). This way the question will be seen as resolved to anyone having similar issues. \$\endgroup\$
    – Leo
    Jul 27, 2017 at 15:34
  • 1
    \$\begingroup\$ @Leo Yes, but I can't accept my answer until tomorrow because site doesn't allow yet. I will do that as soon it's possible. :) \$\endgroup\$
    – modernator
    Jul 28, 2017 at 5:49
  • \$\begingroup\$ Didn't realize it was answered recently. My bad! \$\endgroup\$
    – Leo
    Jul 28, 2017 at 8:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .