Clamping the player with different code than you used in your example

This is a picture of the code I am using I came to the conclusion that I wanted my player to be moved by holding down the left mouse button. movement is working and i am happy with the functionality, the only issue is that I do not know where to now incorporate the Mathf.Clamp. If you could please point me in the right direction that would be helpful.

1 Like

Hi Dominic,

You’d need to use it between lines 39 and 40. Use the Mathf.Clamp method to keep the values within the specific boundaries, then, pass those clamped values to a new Vector2 (currently on line 40).

On a related note, please copy/paste your code into your posts and apply code formatting characters before/after it instead of using screenshots. Whilst screenshots can be very useful for details from within the Unity editor or error messages, they are not very readable for code, especially on mobile devices. You also prevent those that may offer to help you the ability to copy/paste parts of your code back to you with suggestions/corrections.

Hope this helps :slight_smile:


See also;

1 Like

Hey Rob,

thank you very much for your help. Although I am just a bit confused.

Which values are you referring to? maybe you can give me an example with arbitrary values just so i have a image of what it looking like in code?

i really appreciate your help

1 Like

Hi Dominic,

Let’s break down what it actually is you are trying to achieve.

You want to restrict the player movement on the X axis, possibly the Y axis also depending on your game.

You are currently using a series of values, crammed into the parameters for a new Vector2, these include;

  • direction.x
  • mouseMoveSpeed
  • Time.deltaTime

When all of the above are multiplied together you get a value which you are then using to represent the X axis and the same again for the Y axis.

At this point these values could be way outside of the restriction you want to put in place, e.g. to prevent the player from moving outside of the playspace.

You could, for example, use something like this before the creation of the new Vector2 (line 39.5!);

float deltaX = direction.x * mouseMoveSpeed * Time.deltaTime;
float deltaY = direction.y * mouseMoveSpeed * Time.deltaTime;

This gives you two variables which you can then plug in to your Vector2 creation on line 40, like this;

rb.velocity = new Vector2(deltaX, deltaY);

At this point, you have exactly what you started with, although arguably more readable. What you can do now however is clamp the values of those variables as required before using them to create the Vector2.

For example;

float deltaX = direction.x * mouseMoveSpeed * Time.deltaTime;
float deltaY = direction.y * mouseMoveSpeed * Time.deltaTime;

deltaX = Mathf.Clamp(deltaX, xMin, xMax);
deltaY = Mathf.Clamp(deltaY, yMin, yMax);

The additional two lines above assume that you have two variables named xMin and xMax for the horizontal boundaries, and two variables named yMin and yMax for your vertical boundaries.

Hope this helps - oh, and this was a prime example of how it would have been quicker/easier for me to be able to copy/paste a part of your code back to you. You will often find that people are more willing to help when it is easy to :slight_smile:

(happy forum anniversary day also!)

Thank you very much Rob I made the changes that you suggested and they were very clear and helpful.

as for the any further posts in the future i’ll make sure ill refresh on the etiquette of posting, it has been awhile.

I definitely understand the concept much more but for some reason this is still not working.
-the player now moves again, but does not recognize the edges of the camera.
-side note the movement feels off now.

here is the respective code.

void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        Moveboundaries();
    }

 private void Moveboundaries()
    {
        Camera gameCamera = Camera.main;
        xMin = gameCamera.ViewportToWorldPoint(new Vector3(0, 0, 0)).x;
        xMax = gameCamera.ViewportToWorldPoint(new Vector3(1, 0, 0)).x;
        yMin = gameCamera.ViewportToWorldPoint(new Vector3(0, 0, 0)).y;
        yMax = gameCamera.ViewportToWorldPoint(new Vector3(0, 1, 0)).y;
    }

void Update()
    {
Move();
     }

private void Move()
    {
        if (Input.GetMouseButton(0))
        {
            mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            direction = (mousePosition - transform.position).normalized;
            float newX = direction.x * mouseMoveSpeed * Time.deltaTime;
            float newY = direction.y * mouseMoveSpeed * Time.deltaTime;
            var deltaX = Mathf.Clamp(newX, xMin, xMax);
            var deltaY = Mathf.Clamp(newY, yMin, yMax);
            
            rb.velocity = new Vector2(deltaX, deltaY);
             }

p.s its good to be back

Hi Dominic,

Just running the same code this end and I see what you mean.

I think there is an overlap here. In the original game code the transform.position is being set to the clamped values, this is what prevents the player from leaving the playspace. In your version you are using a Rigidbody2D component and setting the velocity, you won’t be able to use the Mathf.Clamp method in the same way as the original code.

As you are using a Rigidbody2D component you could just add Rigidbody2Ds/BoxCollider2Ds to prevent the player from moving outside of a the specific area. Any reason not to?

The reason I didn’t want to do that is because I didn’t want to stray too far from the tutorial outline of the game, but if you don’t think that will be a problem later in the video colliders are a good idea.

What do you suggest? A collider on my character and around the place base? That only my player couldn’t pass through i.e. I’ll tag him as a player?

The above uses a couple of empty GameObjects on either side of the playspace, scaled on the Y and they have a Rigidbody2D component attached. Both are set to static. The player’s Rigidbody component is set to Dynamic and I’ve added a Constraint on the Rotation Z Axis, otherwise when there’s a collision you’re ship rotates a bit.


Alternatively;

You could also do something like this, in the Move method I guess;

if(transform.position.x <= xMin || transform.position.x >= xMax)
{
    rb.velocity = new Vector2(0f, 0f);
}

The above will stop your player ship if they reach either of the sides of the playspace without the need of the other GameObjects/components, however… because the player is at that position, that test returns true each time and thus keeps them there…

This seems to work;

if(transform.position.x <= xMin)
{
    transform.position = new Vector2(xMin, transform.position.y);
}

if(transform.position.x >= xMax)
{
    transform.position = new Vector2(xMax, transform.position.y);
}

It isn’t very graceful and I’m sure you could tidy it up a bit, refactor to another method etc.

Rob
thank you very much for the help this will definitely get me onto the next step of the process. there will just need to be a few kinks that i work out with the colliders. great teacher and i appreciate your time.

With the code example above, you won’t need the colliders on the sides… that last part of my post was pure code solution instead. :slight_smile:

I’ve added a horizontal rule in my post above to separate out the two approaches.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms