2

Mathf.Clamp is resetting my eulerangle to minValue when it reaches the maxValue instead of constraining it at maxValue. I have tried This :

            rotateX = Input.GetAxis("Mouse X") * senseX;
        player.transform.Rotate(player.up, Mathf.Deg2Rad * rotateX, Space.World);

        playerXRotation = player.eulerAngles;

        while (playerXRotation.y > 180f)
            playerXRotation.y -= 360f;

        Debug.Log("Y Rotation: " + playerXRotation.y);
        playerXRotation.y = Mathf.Clamp(playerXRotation.y, lowLimitY, highLimitY);
        player.transform.eulerAngles = playerXRotation;

And This :

         rotate = Input.GetAxis("Mouse X") * senseX;
         rotation = player.transform.eulerAngles;
         rotation.y += rotate * RateOfRotate;

         while (rotation.y > 180)
         {
             rotation.y -= 360;
         }
         rotation.y = Mathf.Clamp(rotation.y, lowLimitY, highLimitY);
         player.transform.eulerAngles = rotation;

Here my lowLimitY = 0 and highLimitY = 180 in both the cases; I am stuck at this and have no clue how to work around it. Any help will be appreciated.

Kaustav
  • 33
  • 6
  • 2
    Well, if the value is being clamped to _lowLimitY_, then it means the value to be clamped was less than _lowLimitY_. Looking at your `while` loops there i wouldn't be surprised if `playerXRotation.y` and `playerXRotation.y` actually are negative after the `while` loop has been executed... –  Oct 29 '18 at 20:29
  • @elgonzo what do you suggest I should do because without that `while` loop the opposite happens, when _lowLimitY_ is reached instead of clamping it to its value at _0_ it resets it to _highLimitY_ value which is _180_. – Kaustav Oct 29 '18 at 20:39
  • I don't really know what you should do (i do not really have Unity3D experience to give meaningful suggestions), but testing whether the y value is larger than 180 and then going to substract twice that amount isn't looking proper... –  Oct 29 '18 at 20:40

2 Answers2

2

Because rotations are quaternions

And they get converted to Euler angles with range [0-360), so while (rotation.y > 180) will never work.

You need to track the rotation value separately, clamp to desired values, then apply it to the object's rotation.

rotation = player.transform.eulerAngles;
float rotationY = rotation.y + rotate * RateOfRotate;
rotationY = Mathf.Clamp(rotationY, lowLimitY, highLimitY);
rotation.y = rotationY;
player.transform.eulerAngles = rotation;
Community
  • 1
  • 1
-1

If your

lowLimit = 0, and highLimit = 180, and you run:

while (rotation.y > 180)
{
  rotation.y -= 360; 
}

If in the case your rotation is the maxValue (180), then rotation.y would equal -180 (180 - 360 = -180).

Then your clamp is Mathf.Clamp(-180, 0, 180) // 0

If you're trying to keep the y rotation in that range, then removing the while should do the trick. If you're going for a different effect, we will need more information.

  • when I remove that while loop the opposite happens, when `lowLimitY` is reached instead of clamping it to its value at `0` it resets it to `highLimitY` value which is `180`. – Kaustav Oct 29 '18 at 22:38
  • @Kaustav Your limits are just wrong in any case. There are 360 degrees in a circle and your clamp is restricting things to 180 degrees. It doesn't matter how you get the value that goes into it (loop or no loop) the limits are wrong. – Draco18s no longer trusts SE Oct 29 '18 at 22:58
  • @Draco18s I am trying to restrict the movement between 0 to 180 degrees, I don't need a full 360 degree rotation. That's why I am clamping the value of eulerangle.y between 0 and 180 degrees. And I don't get how can the limits be wrong? Can you please explain what you meant. – Kaustav Oct 29 '18 at 23:10
  • @Kaustav If your thing is rotated 179 degrees and your `RateOfRotate` is 5, what do you *want* to happen? Odds are you want the thing to squish up against the 180 degree barrier. But right now you're going "184? that's more than 180!" and subtracting 360, making it -176, then clamping it to 0. Only when you removed the loop and it the rotation bashed up against the 180 degree limit that was also somehow not what you wanted? *If your thing is rotated 179 degrees and your `RateOfRotate` is 5, what do you **want** to happen?* – Draco18s no longer trusts SE Oct 29 '18 at 23:36
  • @Draco18s I have tried removing the loop, when I remove the loop my gameobject bashes against the 180 degree limit and is properly clamped to the maxvalue, but when it bashes against the minimum value of 0 degree it somehow gets reset back to the maxvalue of 180 degree instead of being clamped back to 0 degree. – Kaustav Oct 30 '18 at 00:07
  • Probably because euler angles aren't the native storage type, but quaternions, and when it gets converted, those values are above 180...not negative. – Draco18s no longer trusts SE Oct 30 '18 at 00:49