2
\$\begingroup\$

I'm going mad to clamp rotation of an object.

I've tested using Inspector that correctly rotation range is Z>-15 and Z<30.

I've written this code but it isn't working properly !

if (rb.transform.rotation.eulerAngles.z > 30)
    rb.transform.Rotate (-Vector3.forward * speedTurretMovement  , Space.Self);
if (rb.transform.rotation.eulerAngles.z < -15 )
    rb.transform.Rotate (Vector3.forward * speedTurretMovement , Space.Self);   

Thanks

\$\endgroup\$
4
  • \$\begingroup\$ 2 things : 1) You are not really clamping the values between -15 and 30, rather you are trying to apply a reverse rotation and do not control what the new angle will be. 2) it isn't working properly is a very poor bug description. What is it supposed to mean exactly? \$\endgroup\$ Commented Mar 2, 2017 at 15:26
  • \$\begingroup\$ Yes I know, you're right. What I mean is "how to limit via code the rotation of an object ... how to say Unity : "despite the user input, DON'T rotate that object over this value" \$\endgroup\$
    – stighy
    Commented Mar 2, 2017 at 15:28
  • \$\begingroup\$ You need to use Mathf.Clamp function for this. \$\endgroup\$ Commented Mar 3, 2017 at 7:04
  • \$\begingroup\$ Usually these required some exra logic because -15 degrees may well get represented as 345 degrees, in which your clamping &c won't work as expected. \$\endgroup\$
    – Stormwind
    Commented Mar 5, 2017 at 18:52

3 Answers 3

3
+50
\$\begingroup\$
using UnityEngine;

public class Body : MonoBehaviour
{
    public GameObject head; //ref the head / turret via inspector
    public int angle = 0;
    public int min = -15;
    public int max =  30;

    void Update ()
    {
        angle += Input.GetKey(KeyCode.LeftArrow) ? 1 : 0;
        angle += Input.GetKey(KeyCode.RightArrow) ? -1 : 0;
        angle = Mathf.Clamp(angle, min, max);
        head.transform.eulerAngles = new Vector3(0, angle, 0);
    }
}

Create a new, clean scene. Create a cube GameObject called Body and drop this script on it. Create another cube called Head and drop it inside the Body. Drag inspector connection for Head onto the Body script. Make sure they are both at world origin. Use arrow keys to control. Have fun.

P.S. Nothing stops you from calling this script Head and dropping it on Head instead. I just like the idea of the Head controlling the Body, and providing angular constraints.

\$\endgroup\$
2
  • \$\begingroup\$ Pefect! Thank you. I've just changed eulerAngles with localEulerAngles because my turret is "child" of another object already rotated!!! Thanks \$\endgroup\$
    – stighy
    Commented Mar 5, 2017 at 13:42
  • \$\begingroup\$ @stighy You're welcome. Would you assign the bounty / checkmark if this solved your problem? \$\endgroup\$
    – Engineer
    Commented Mar 5, 2017 at 16:06
0
\$\begingroup\$

just use Mathf.Clamp(value,min,max);

\$\endgroup\$
3
  • \$\begingroup\$ why has this got down votes when it works? there really isn't much to explain here. \$\endgroup\$ Commented Mar 5, 2017 at 12:55
  • \$\begingroup\$ Probably because this is not a detailed answer as was explicitly requested below the question. \$\endgroup\$
    – Engineer
    Commented Mar 5, 2017 at 13:46
  • \$\begingroup\$ @JustinWilliamStanleyBryant Sorry I am late for answering. I did downvote as this is a very lazy answer imho. Tbh it feels like you just read the title, saw clamp, and answered without trying to understand OP's problem. For example OP was doing a 1st rotation going too far, then 2nd rotation to go back to normal. Where do you include your clamp? Before doing the 1st rotation? After it? Many things you could have added to get an upvote instead of downvote. \$\endgroup\$ Commented Jul 18, 2017 at 23:22
0
\$\begingroup\$
rb.transform.localRotation = Quaternion.Euler(new Vector3(0, 0, Mathf.Clamp(transform.eulerAngles.z + rotationAmount * Time.deltaTime, -15, 30)));

If you don't want to use Quaternion.

direction = -1 or 1
rb.transform.Rotate(new Vector3(0, 0, Mathf.Clamp(speedTurretMovement * direction, -15 - rb.transform.eulerAngles.z, 30 - rb.transform.eulerAngles.z)), Space.Self);
\$\endgroup\$
2
  • 3
    \$\begingroup\$ Code like that is difficult to debug, because when the compiler tells you "Error on line X" you're left wondering "where, exactly, on line X?". Break it down into individual statements instead of thinking that a massive one-liner is useful. It's better for you and better for the person you're trying to help. \$\endgroup\$
    – Engineer
    Commented Mar 5, 2017 at 15:54
  • 1
    \$\begingroup\$ @ArcaneEngineer I don't think that it is so complicated that it will be hard to debug.... Is it better to create a variable inside update loop to allocate memory every frame? But ofc it will be easier to debug. I post only solutions and best performance practices. If you are concerned about readability it's your responsibility to make it "easier to debug". It doesn't change answer and code correctness, code does what it is supposed to do. Thanks. \$\endgroup\$ Commented Mar 5, 2017 at 18:14

You must log in to answer this question.

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