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\$
4
  • \$\begingroup\$ You could use docs.unity3d.com/Manual/Joints.html. \$\endgroup\$
    – aybe
    Commented Feb 26, 2019 at 22:31
  • \$\begingroup\$ Thank you, but I want to solve it with pure math. \$\endgroup\$
    – tmighty
    Commented Feb 27, 2019 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
    Commented Feb 27, 2019 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
    Commented Feb 27, 2019 at 19:27

1 Answer 1

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\$

You must log in to answer this question.

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