- Home /
Restricting movement with Mathf.Clamp
Hi, I'm new to Unity and I'm trying to clone the Pong game right now but I'm stuck with movement restriction. I found one example that worked, but it worked in JS and I'm trying to learn C# so don't want to use any JS scripts now. The problem is that I want to restrict vertical movement of the paddle to -4.1f min and 4.1f max.
using UnityEngine;
using System.Collections;
public class RacketController : MonoBehaviour {
public float speed = 5.0f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
float yMove = Input.GetAxis("Vertical") * Time.deltaTime * speed;
transform.Translate(0f ,yMove, 0f);
transform.position.y = Mathf.Clamp(transform.position.y, -4.1f, 4.1f);
}
}
The similar code worked in JS but in C# the compiler returns an error on line where I try to clamp transform.position.y. I tried a lot of different solutions found on Unity Answers or in forums but I can't get it (or those examples won't work with my situation).
Answer by asafsitner · Mar 16, 2015 at 09:52 AM
In C#, unlike UnityScript, the individual elements in a Transform's position property are not accessible directly.
Instead, you need to define a new vector and assign the whole of it, so for instance in your example you would do something like:
void Update()
{
float yMove = Input.GetAxis("Vertical") * Time.deltaTime * speed;
transform.Translate(0f, yMove, 0f);
// initially, the temporary vector should equal the player's position
Vector3 clampedPosition = transform.position;
// Now we can manipulte it to clamp the y element
clampedPosition.y = Mathf.Clamp(clampedPosition.y, -4.1f, 4.1f);
// re-assigning the transform's position will clamp it
transform.position = clampedPosition;
}
Thank you for such a detailed explanation! Now it's more clear to me :)
Thank you Asaf! I was looking for hours to find this, and your code helped me to solve it. Really appreciate you posting!
Thanks again, Blaine
Holy moses man. Took me ages to find a viable code. Thank you ever so much!
This is life-saving code. My advice to fellow newbs is to make sure at all time you are comparing apples to apples and oranges to oranges. I was stuck for a while because I was comparing Vectors of different kinds to each other (screen, viewPort, world...)
Answer by Priyanshu · Mar 16, 2015 at 10:00 AM
In C# you cannot directly assign transform.position vector. As it is read only.
Change
transform.position.y = Mathf.Clamp(transform.position.y, -4.1f, 4.1f);
to
transform.position = new Vector3 (transform.position.x, Mathf.Clamp(transform.position.y, -4.1f, 4.1f), transform.position.z);
Answer by tarahugger · Feb 01, 2018 at 05:55 PM
Building upon Priyanshu's Answer, the following was what i needed to limit my top-down perspective camera movement for panning.
void ClampTransform(Transform t, Vector3 origin, float distanceX, float distanceZ)
{
var z = Mathf.Clamp(t.position.z, origin.z - distanceZ, origin.z + distanceZ);
var x = Mathf.Clamp(t.position.x, origin.x - distanceX, origin.x + distanceX);
t.position = new Vector3(x, t.position.y, z);
}
Answer by madhu_unity425 · May 18, 2019 at 06:49 AM
you can write Simple if condition also like this below
if(transform.position.y<=-4.1f) { transform.position = new Vector3( transform.position.x, -4.1f, transform.position.z); }
if(transform.position.y>=4.1f) { transform.position = new Vector3( transform.position.x, 4.1f, transform.position.z); }
This is not really simpler nor easier to read nor better for performance. Each time you use transform.position you actually call a native code method which will return the whole vector3. Using a temporary variable as asafsitner did is easier to read and in most cases better for performance.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Script will be found on the client but not on the server. 0 Answers
My sphere is not moving in the unity? 1 Answer
Adding a delay for weapon switching 1 Answer