About 'Limit With Mathf.Clamp()'!

In this video (objectives)…

  1. Figure out the range we want to allow the paddle to move on x axis.
  2. use Mathf.Clamp() to limit the paddle's movement.

After watching (learning outcomes)… Use Mathf.Clamp() to limit the movement of a game object.

(Unique Video Reference: 9_BR_CUD)

We would love to know…

  • What you found good about this lecture?
  • What we could do better?

Remember that you can reply to this topic, or create a new topic. The easiest way to create a new topic is to follow the link in Resources. That way the topic will…

  • Be in the correct forum (for the course).
  • Be in the right sub-forum (for the section)
  • Have the correct lecture tag.

Enjoy your stay in our thriving community!

[SUGGESTION] I thought I would have a go at avoiding magic numbers with this. The following code seems to do the job of calculating clamp limits using Unity variables, thereby eliminating the need to serialize or hardcode the limits or the screenwidth.

Any feedback would be appreciated.

using UnityEngine;

public class Paddle : MonoBehaviour {

    //config parameters
    float screenWidthInUnits;
    [SerializeField] Camera mainCamera;

    float minX;
    float maxX;
    
	// Use this for initialization
	void Start ()
    {
        GetScreenWidth();
        SetPaddleBoundaries();
    }

    private void GetScreenWidth()
    {
        float screenX = Screen.width;
        float screenY = Screen.height;
        float resolutionFactor = screenX / screenY;
        float cameraSizeInUnits = mainCamera.GetComponent<Camera>().orthographicSize;
        screenWidthInUnits = 2 * cameraSizeInUnits * resolutionFactor;
    }

    // Update is called once per frame
    void Update () {
        float mousePosInUnits = Input.mousePosition.x * screenWidthInUnits / Screen.width;
        Vector2 paddlePos = new Vector2(transform.position.x, transform.position.y);
        paddlePos.x = Mathf.Clamp(mousePosInUnits, minX, maxX);
        transform.position = paddlePos;
	}

    private void SetPaddleBoundaries()
    {
        float paddleHalfWidth = GetComponent<Collider2D>().bounds.extents.x;
        minX = paddleHalfWidth;
        maxX = screenWidthInUnits - paddleHalfWidth;
    }
}

Maybe paramaterize something for gameplay value, such as allowing a variable percentage of the paddle to disappear off screen (to compensate for the oddly-shaped paddle)?

Is there a tidier way of using 2 integers to calculate a float? It didn’t seem to work too well for me when i tried

float resolutionFactor = Screen.width / Screen.height;

as it seems the screen dimensions needed to be cast as floats first?

Dear Mr. Rick,

I am a student with your course, and very happy with this course.
So, I don’t understand with this code:

float mousePosInUnits = Input.mousePosition.x / Screen.width * screenWidthInUnits;

Could you explain for me?

Thanks and Best Regards!

Sure thing.

We are creating a variable (called mousePosInUnits). Its purpose is to tell us where the mouse is on our screen along the x axis (horizontal) and to convert that position into unity world units.

Input.mousePosition.x - this is the position of the mouse
Screen.width - this is how wide the game screen is (ie. the width of our camera’s view)
screenWidthInUnits - this is how many units we know our screen is in width (again, as defined by our camera)

So we are saying mouse position divided by screen width times by screen width in units.

So, I debug the Screen.with = 713 pixel, and the screenWidthInUnits = 16f
Why we use: Screen.width * screenWidthInUnits;
I don’t understand why we do that?

Apologies if you mention this in an earlier video, it’s possible I missed it. You mentioned not to use capitalisation for variables - out of interest why is this? Is it just a best practice thing, or can it cause technical issues in certain situations? I Googled it but it seems like there’s a whole bunch of arguments for either way.

In some ways its preference / styling and other ways its practical. For example, if you are declaring a variable which is type Text, the type will be capitalised which means we dont want our variable to be capitalised or else it we’ll lose track of which things are types (or classes) and which things are variables.

1 Like

This is my solution to the challenge. I’ve serialized the right-most extent, but set it to screen.width . I also created a variable called screenSpace to help me keep everything straight with the world space. I just multply the .x pixel position by it to get the correct translation.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Paddle : MonoBehaviour {

    [SerializeField] float screenWidthInUnits = 16f;
    [SerializeField] float leftMax= 0f;
    [SerializeField] float rightMax = Screen.width;
	
	// Update is called once per frame
	void Update () {
        float screenSpace = screenWidthInUnits / Screen.width;
        Vector2 paddlePosition = transform.position;
        paddlePosition.x = Mathf.Clamp(Input.mousePosition.x, leftMax, rightMax) * screenSpace;
        transform.position = paddlePosition;
	}
}

[Question]

Hi Rick,

I came across a little problem with paddle movement limiting.

In Visual Studio my Min and Max range were set to 1 and 15 respectively, but in the inspector it was a bit different. Min was set to 1, but Max was set to 16. It was confusing at first, but I fixed it pretty easily.
My question is why was the Max value set to 16 in the inspector, when in the script I set it to 15, and how to avoid that kind of issues in the future.

Sounds like this has to do with when the variable was first initialised. If you write [SerliaizeField] int variableName = 10; and then in the inspector change the value to 20 and then go back into the code and change it to 20, the variable will stay at 10 because the inspector overrides the code.

Privacy & Terms