2

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

stighy
  • 417
  • 6
  • 30
  • 60
  • 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? – realUser404 Mar 02 '17 at 15:26
  • 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" – stighy Mar 02 '17 at 15:28
  • You need to use Mathf.Clamp function for this. – Aditya Yadav Mar 03 '17 at 07:04
  • 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. – Stormwind Mar 05 '17 at 18:52

3 Answers3

3
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.

Engineer
  • 29,455
  • 4
  • 72
  • 120
  • Pefect! Thank you. I've just changed eulerAngles with localEulerAngles because my turret is "child" of another object already rotated!!! Thanks – stighy Mar 05 '17 at 13:42
  • @stighy You're welcome. Would you assign the bounty / checkmark if this solved your problem? – Engineer Mar 05 '17 at 16:06
0

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

Uri Popov
  • 3,007
  • 25
  • 46
  • why has this got down votes when it works? there really isn't much to explain here. – Justin William Stanley Bryant Mar 05 '17 at 12:55
  • Probably because this is not a detailed answer as was explicitly requested below the question. – Engineer Mar 05 '17 at 13:46
  • @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. – realUser404 Jul 18 '17 at 23:22
0
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);
Candid Moon _Max_
  • 2,856
  • 1
  • 18
  • 38
  • 3
    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. – Engineer Mar 05 '17 at 15:54
  • 1
    @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. – Candid Moon _Max_ Mar 05 '17 at 18:14