- Home /
Constrain the drag limits on a GameObject
Hi!
I'm making a 2D menu that you scroll up and down through the levels.
I've got the following Click and Drag script on my GameObject:
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(BoxCollider))]
public class Drag : MonoBehaviour
{
private Vector3 screenPoint;
private Vector3 offset;
private float _lockedYPosition;
void OnMouseDown() {
_lockedYPosition = screenPoint.y;
offset = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
Screen.showCursor = false;
}
void OnMouseDrag()
{
Vector3 curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
Vector3 curPosition = Camera.main.ScreenToWorldPoint(curScreenPoint) + offset;
curPosition.x = _lockedYPosition;
transform.position = curPosition;
}
void OnMouseUp()
{
Screen.showCursor = true;
}
}
It drags on only one axis but I want to prevent it from dragging too far up or down and disappearing off the screen. I've tried with Box Colliders and Rigidbody but this seems to be a bit too unstable. I've briefly looked into doing it by calculating the min and max height/width and have the following script to print the GameObjects coordinates, but don't know how to implement them:
#pragma strict
function Start () {
}
//Unity will constantly check the position of the GameObject.
function Update () {
//Creates a variable to check the objects position.
var myPosition = transform.position;
//Prints the position to the Console.
Debug.Log(myPosition);
}
Could anyone point me in the right direction of how to go about this?
If you're setting the transform.position to a custom vector3, you can always use $$anonymous$$athf.Clamp or $$anonymous$$in/$$anonymous$$ax to limit certain values.
Something like this:
public Vector2 limits = new Vector2(-20, 20);
void On$$anonymous$$ouseDrag()
{
Vector3 curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
Vector3 curPosition = Camera.main.ScreenToWorldPoint(curScreenPoint) + offset;
curPosition.x = _lockedYPosition;
//Assu$$anonymous$$g you want to limit the Y axis
curPosition.y = $$anonymous$$athf.Clamp(curPosition.y, limits.x, limits.y);
transform.position = curPosition;
}
Or you could use an if statement to check if that value is over the limit, and then set that value to the limit directly. $$anonymous$$ake sure you set the position after you clamp/limit the values or you will still be able to pop past the limit for a single frame.
if(curPosition.y > limits.y){
curPosition.y = limits.y;
}
else if(curPosition.x < limits.x){
curPosition.x = limits.x;
}
Depending on the used camera (ortho or perspective) it might be easier to clamp the inco$$anonymous$$g screen position of the mouse
curScreenPoint.y = $$anonymous$$athf.Clamp(curScreenPoint.y, 20, Screen.height-30); // 30 pixels from top and 20 from bottom
$$anonymous$$eep in $$anonymous$$d that screen coordinates start at the bottom, not at the top.
I was about to suggest something along the lines of what Josh707 posted, that just about covers it in my opinion.
I tried Josh707's approach but it doesn't seem to work. I'm actually moving it on the z axis but the problem that I see is that you give the public variable 'Vector2', but it's not referenced anywhere in the script; only Vector3 is. Also, when I put in the $$anonymous$$ and max values, is this the local position thats printed to the console or do I have to use the world position? Basically, I want to be able to click and drag from (0.0, -2.0, 369.9) to (0.0, -2.0, 2929.3) if that helps with your answers?