0
\$\begingroup\$

I'm building a player controller.

While aiming, the player can rotate the chest bone. This looks as if the character aims in different directions.

The chest bone should only be allowed to rotate within a certain range. If this range is exceeded (either to the left or to the right), the chest bone should stay at its current rotation, and the player should be rotated instead.

I'm having problems applying the desired rotation to the parent game object instead.

I'm trying to work with the localEulerAngles in order to applying an additional Y rotation to the gameobject, but the Y rotation value tells me for example "359.9" while I expected to work with a value of ~0.

enter image description here

private void pHandle_LateUpdate_Aim()
{
    Quaternion oldNeckRotation = Neck.transform.rotation;

    // Fade old input before capturing new, so we don't dull the freshest data.
    float yawBlend = Mathf.Pow(1.0f - Aim_yawInputFalloff, referenceFramerate * Time.deltaTime);
    // A Lerp toward zero is just the same as a multiplication by the blend factor.    
    Chest_yawRate *= yawBlend;
    // Accelerate by mouse movement over the past frame.
    // (May need adjustment for display resolution).
    Chest_yawRate += Input.GetAxis("Mouse X");

    float yawDelta = Chest_yawSpeed * Chest_yawRate * Time.deltaTime;
    float offCenterYaw = Chest_currentYaw - Chest_yawCenter;

    float fDesiredChestYaw = Chest_currentYaw + yawDelta;
    float fHeroRotation = 0f;

    if (fDesiredChestYaw > Chest_rotateRange) // the allowed chest rotate range would be exceeded. Instead, move the gameobject / the parent.
    {
        fHeroRotation = (fDesiredChestYaw - Chest_rotateRange);
        fHeroRotation += this.transform.localEulerAngles.y;
        this.transform.Rotate(0, fHeroRotation, 0);
        return;
    }
    else if (fDesiredChestYaw < -Chest_rotateRange)
    {
        fHeroRotation = (Chest_rotateRange + fDesiredChestYaw);
        fHeroRotation += this.transform.localEulerAngles.y;
        this.transform.Rotate(0, fHeroRotation, 0);
        return;
    }
    else
    {
        // If we're moving away from the center, slow down as we approach the edge.
        if (yawDelta * offCenterYaw > 0)
        {
            float extremityYaw = offCenterYaw / Aim_yawMaxRange;
            yawDelta *= 1.0f - extremityYaw * extremityYaw;
            fHeroRotation = yawDelta;
        }
    }


    // Ensure we never overshoot the allowed range.
    Chest_currentYaw = Mathf.Clamp(Chest_currentYaw + yawDelta,
                              Chest_yawCenter - Aim_yawMaxRange,
                              Chest_yawCenter + Aim_yawMaxRange);

    Vector3 nNewChestRotation = new Vector3(Chest.localEulerAngles.x, Chest_currentYaw, Chest.localEulerAngles.z);
    Chest.localRotation = Quaternion.Euler(nNewChestRotation);

    Quaternion newNeckRotation = Neck.transform.rotation;

    //the neck should not rotate with the chest. So I first counter-rotate it against the new chest rotation, then rotate it a little towards the chest rotation
    Neck.transform.rotation = Quaternion.Lerp(oldNeckRotation, newNeckRotation, neckFollowChest);
}
\$\endgroup\$
  • \$\begingroup\$ You could use docs.unity3d.com/Manual/Joints.html. \$\endgroup\$ – Aybe Feb 26 at 22:31
  • \$\begingroup\$ Thank you, but I want to solve it with pure math. \$\endgroup\$ – tmighty Feb 27 at 16:29
  • \$\begingroup\$ @DMGregory DM, you always have such wonderfully elegant solutions. Would you mind sharing your skills on this one, too? \$\endgroup\$ – tmighty Feb 27 at 16:31
  • 5
    \$\begingroup\$ FYI: Tagging a user doesn't send them a notification unless they've already commented on the thread. \$\endgroup\$ – DMGregory Feb 27 at 19:27
2
\$\begingroup\$

Damn, I was stupid.

All the time I didn't realize I could simply add a rotation Y like this:

    if (fDesiredChestYaw > Chest_rotateRange) // the allowed chest rotate range would be exceeded. Instead, move the gameobject / the parent.
    {
        fHeroRotation = yawDelta;
        this.transform.Rotate(0, fHeroRotation, 0);
        return;
    }
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.