Impose limits to a variable in a control function

Greetings,

I am having problems at polishing some code of mine which I need to impose limits on a variable.

public float x = 0f;
void Update () {
        x += Input.GetAxis("Vertical");
        CheckLimit(x, minX, maxX);
    }

private void CheckLimit(float _x, float min, float max)
    {
        if (_x >= max) { _x = max; }
        else
            if (_x <= min) { _x = min; }

This is the code I would like to use, with the intent to modify x but then check at every iteration whether x is getting too large (or small) and put it at its maximum (or minimum) value.

Sadly this is not working and the variable is not getting limited, while the less-polished version below works.

 public float x = 0f;
 void Update () {
         x += Input.GetAxis("Vertical");
         CheckLimit();
     }
 
 private void CheckLimit()
     {
         if (x >= maxX) { x = maxX; }
         else
             if (x <= minX) {x = minX; }

Suppose that minX and maxX are float defined elsewhere.

Why is the first code not working correctly?
I could not find anything similiar through searching, but I admit I didn’t really know how to search for something like this. I sincerely apologize if this question has already been answered elsewhere.

In the first code sample you’re passing the value of the variable not the reference so you end up modifying a copy of the original.
If you want to pass a variable by a reference instead of a value here’s a resource: ref keyword - C# Reference | Microsoft Learn

All method parameters are always passed “by-value” by default. That means whatever you pass as parameter is actually copied into a local variable of the method. That means any changes to the variable won’t affect the original variable / value you passed into the method.

There are in general two solutions:

  • Let the method return the modified value and assign the returned value back to the variable when you call the method.
  • Use a “ref” parameter which allows you to pass a variable “by-reference”

If you want to go with the first solution you can actually get rid of your method since that method already exists. It’s called Mathf.Clamp.

Just do

x = Mathf.Clamp(x, minX, maxX);

If you want to use a ref parameter you would have to declare your method like this:

public static void CheckLimit(ref float _x, float min, float max)
{
    if (_x >= max)
        _x = max;
    else if (_x <= min)
        _x = min;
}

This method has to be called like this:

CheckLimit(ref x, minX, maxX);

In general using a return value is more flexible as it allows you to pass in an expression or store the clamped value in a different variable or use it as parameter to another method. A ref parameter always requires an actual variable. It has to be a real variable, properties won’t work as they do not represent a memory address which could be referenced.

Unity ships many useful utility methods like Clamp. Just check the documentation