Search Unity

Mathf Clamp don't clamp!

Discussion in 'Scripting' started by PaxStyle, Jun 21, 2014.

  1. PaxStyle

    PaxStyle

    Joined:
    May 22, 2013
    Posts:
    63
    Hey.. I don't understand why this not limit the rotation! are two months that I'm trying to do this.. hope someone can help me! thankss!


    Code (CSharp):
    1.     void Update () {
    2.  
    3.         //go up
    4.         if (Input.GetKey (KeyCode.Z)) {
    5.            
    6.             Vector3 rot = -Vector3.right * Time.deltaTime*speedUp;
    7.             float rotX = Mathf.Clamp(rot.x, 0, -50f);
    8.             arm[0].transform.Rotate(rot);
    9.  
    10.  
    11.  
    12.         }
    13.        
    14.         //go down
    15.         if (Input.GetKey (KeyCode.X)) {
    16.            
    17.             Vector3 rot = Vector3.right * Time.deltaTime*speedUp;
    18.             float rotX = Mathf.Clamp(rot.x, -50f, 0);
    19.             arm[0].transform.Rotate(rot);
    20.  
    21.  
    22.            
    23.         }
     
  2. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    You clamp rot.x to be within -50 and 0 and you store the result in the variable rotX without using it. But you are ignoring the case that rot.x could be 330°, which is identical to -30°. Instead of using Clamp only, I would use Repeat and Clamp. Like that you can make sure upfront that the angle is between 0 and 360 and than operate within this interval.

    WARNING: UNTESTED CODE
    Code (csharp):
    1. Vector3 rot = Vector3.right * Time.deltaTime*speedUp;
    2.  
    3. // Make sure rotX is between 0 and 360
    4. float rotX = Mathf.Repeat(rot.x, 360f);
    5.  
    6. // Clamp it to be within 310 and 360 which is identical to -50 and 0.
    7. Mathf.Clamp(rot.x, 310f, 360f);
    8.  
    9. // You forgot this line in your code!
    10. rot.x = rotX;
    11.  
    12. arm[0].transform.Rotate(rot);
     
  3. PaxStyle

    PaxStyle

    Joined:
    May 22, 2013
    Posts:
    63
    Thank you for your reply.
    I should set the clamp (loking the transform rotation in inspector) within 0 to -40 about.
    So i changed the values so, but the rotation is still at 360°.. (in script, "//GoUp" should go from 0 to -45 about, and "//GoDown" from -45 to 0)

    Code (CSharp):
    1. //go up
    2.         if (Input.GetKey (KeyCode.Z)) {
    3.            
    4.             Vector3 rot = -Vector3.right * Time.deltaTime*speedUp;
    5.             float rotX = Mathf.Repeat(rot.x, 360f);
    6.             Mathf.Clamp(rot.x, 0f, -45f);
    7.             rot.x = rotX;
    8.             arm[0].transform.Rotate(rot);
    9.  
    10.  
    11.  
    12.         }
    13.        
    14.         //go down
    15.         if (Input.GetKey (KeyCode.X)) {
    16.            
    17.             Vector3 rot = Vector3.right * Time.deltaTime*speedUp;
    18.             float rotX = Mathf.Clamp(rot.x, -45f, 0);
    19.             arm[0].transform.Rotate(rot);
    20.  
    21.  
    22.            
    23.         }
     
  4. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    The code should be something like that:
    Code (csharp):
    1. //go up
    2. if (Input.GetKey (KeyCode.Z)) {
    3.   Vector3 rot = -Vector3.right * Time.deltaTime*speedUp;
    4.   float rotX = Mathf.Repeat(rot.x, 360f);
    5.   Mathf.Clamp(rot.x, 360f-45f, 360f);
    6.   rot.x = rotX;
    7.   arm[0].transform.Rotate(rot);
    8. }
    9.    
    10. //go down
    11. if (Input.GetKey (KeyCode.X)) {
    12.   Vector3 rot = Vector3.right * Time.deltaTime*speedUp;
    13.   float rotX = Mathf.Repeat(rot.x, 360f);
    14.   Mathf.Clamp(rot.x, 360f-45f, 360f);
    15.   rot.x = rotX;
    16.   arm[0].transform.Rotate(rot);
    17. }
    If we make rotX with Repeat to be between 0 and 360, we can't Clamp it to be between 0 and -45, because it will always end up being 0 in that case.
    We bring rotX with Repeat to a value between 0 and 360, that means, we have to Clamp with values from the same range. That means as a consequence, we have to use 360-45 and 360. Otherwise it will not work!
     
  5. PaxStyle

    PaxStyle

    Joined:
    May 22, 2013
    Posts:
    63
    Uff no.. is still at 360° o.o :(
     
  6. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Did you try to debug the code to see at which point something happens that is not expected?
     
  7. zaxvax

    zaxvax

    Joined:
    Jun 9, 2012
    Posts:
    220
    If I understand your problem right, you want to limit object's rotation between minimum angle and maximum angle.
    If I'm right here is a simple example for you. Attach it to an object and it will limit rotation from -50 to 50.
    Z and X to left and right.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class ClampScript : MonoBehaviour
    5. {
    6.         public float speedUp = 100.0f;
    7.  
    8.         void Update ()
    9.         {
    10.    
    11.                 if (Input.GetKey (KeyCode.Z)) {
    12.                         float currentAngle = transform.rotation.eulerAngles.y;
    13.                         while (currentAngle < -180.0f)
    14.                                 currentAngle += 360.0f;
    15.                         while (currentAngle > 180.0f)
    16.                                 currentAngle -= 360.0f;
    17.                         Debug.Log ("currentAngle " + currentAngle);
    18.                         float destinationAngle = currentAngle - Time.deltaTime * speedUp;
    19.                         Debug.Log ("destinationAngle before clamp " + destinationAngle);
    20.                         destinationAngle = Mathf.Clamp (destinationAngle, -50.0f, 50.0f);
    21.                         Debug.Log ("destinationAngle after clamp " + destinationAngle);
    22.                         float deltaAngle = destinationAngle - currentAngle;
    23.                         transform.Rotate (Vector3.up, deltaAngle);
    24.        
    25.        
    26.        
    27.                 }
    28.    
    29.                 if (Input.GetKey (KeyCode.X)) {
    30.                         float currentAngle = transform.rotation.eulerAngles.y;
    31.                         while (currentAngle < -180.0f)
    32.                                 currentAngle += 360.0f;
    33.                         while (currentAngle > 180.0f)
    34.                                 currentAngle -= 360.0f;
    35.                         Debug.Log ("currentAngle " + currentAngle);
    36.                         float destinationAngle = currentAngle + Time.deltaTime * speedUp;
    37.                         Debug.Log ("destinationAngle before clamp " + destinationAngle);
    38.                         destinationAngle = Mathf.Clamp (destinationAngle, -50.0f, 50.0f);
    39.                         Debug.Log ("destinationAngle after clamp " + destinationAngle);
    40.                         float deltaAngle = destinationAngle - currentAngle;
    41.                         transform.Rotate (Vector3.up, deltaAngle);
    42.                 }
    43.         }
    44. }
    I put a lot of variables to make it easier to understand and also logging so you can watch it work.

    In your code you limit rotation speed which is not what you wanted to do, I believe, as you have a speedUp variable for that purpose.
     
    Last edited: Jun 21, 2014
  8. PaxStyle

    PaxStyle

    Joined:
    May 22, 2013
    Posts:
    63
    This seems to work but the rotation should be up and down, this is hoizontal, so i tryied to change rotation.eulerAngles.y with rotation.eulerAngles.X but is always horizontal. Why?
     
  9. zaxvax

    zaxvax

    Joined:
    Jun 9, 2012
    Posts:
    220
    Code (CSharp):
    1. transform.Rotate(Vector3.right, deltaAngle);
    Code (CSharp):
    1. float currentAngle = transform.rotation.eulerAngles.x;
    for X axis
     
  10. zaxvax

    zaxvax

    Joined:
    Jun 9, 2012
    Posts:
    220
    Code (CSharp):
    1. transform.Rotate(Vector3.forward, deltaAngle);
    Code (CSharp):
    1. float currentAngle = transform.rotation.eulerAngles.z;
    for Z axis
     
  11. PaxStyle

    PaxStyle

    Joined:
    May 22, 2013
    Posts:
    63
    Thank you friend work!! :')
    If I want increment speed when I press Z and X so that the start is not jerky, what I have to look?
     
  12. zaxvax

    zaxvax

    Joined:
    Jun 9, 2012
    Posts:
    220
    Your speedUp variable?
     
  13. PaxStyle

    PaxStyle

    Joined:
    May 22, 2013
    Posts:
    63
    Yes :)