i have an ui image draggable , but I want to move it just inside the canvas.
the code i have allows me to move the image but not within the limits of canvas.
i use unity 4.6
This is my code:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
public class DragUI : MonoBehaviour, IPointerDownHandler, IPointerUpHandler {
public Vector2 Canvas_Size;
public Vector2 a;
//public float b;
public RectTransform Rt; /***/
public GameObject bot; /****/
private bool mouseDown = false;
private Vector3 startMousePos;
private Vector3 startPos;
public void OnPointerDown(PointerEventData ped)
{
//BoxCollider2D.widht =
//Canvas.
mouseDown = true;
startPos = transform.position;
startMousePos = Input.mousePosition;
}
/*******************************************/
void Get()
{
Rt = bot.GetComponent<RectTransform>();
a.x = Rt.rect.height;
a.y = Rt.rect.width;
//Rt.rect.center = a;
}
/***********************************************/
public void OnPointerUp(PointerEventData ped)
{
mouseDown = false;
}
void Update ()
{
if (mouseDown) {
Vector3 currentPos = Input.mousePosition;
Vector3 diff = currentPos - startMousePos;
Vector3 pos = startPos + diff;
transform.position = pos;
}
//it is the test on the canvas limits
if(transform.position.x <= -(Rt.rect.width/2 ))
{
transform.position = new Vector2(-(Rt.rect.width/2), transform.position.y);
}
else if (transform.position.x >= (Rt.rect.width/2))
{
transform.position = new Vector2((Rt.rect.width/2), transform.position.y);
//transform.position.x = b; //Rt.rect.width;
}
if(transform.position.y <= -(Rt.rect.width /2))
{
transform.position = new Vector2(transform.position.x, -(Rt.rect.width/2 ));
}
else if(transform.position.y >= (Rt.rect.width/2 ))
{
transform.position = new Vector2(transform.position.x, (Rt.rect.width/2));
}
//a = new Vector2(0, 0);
}
}
Hey @LAFI that code I updated in the last question works perfectly well for canvases as well as panels, in fact it’ll work with any two objects that have a RectTransform in the new UI.
I’ll post the updated code here as well just make the Canvas the ParentRT and the image MyRect.
Really you need to tick questions that have been answered correctly. It benefits you as well because some people won’t help if someone gets a reputation for not marking correct answers.
This is a piece of code I made using the example Unity provides. (Forum post and asset store)
using UnityEngine;
using UnityEngine.EventSystems;
public class DragableUI : UIBehaviour, IBeginDragHandler, IDragHandler
{
/// <summary>
/// The RectTransform that we are able to drag around.
/// if null: the transform this Component is attatched to is used.
/// </summary>
public RectTransform dragObject;
/// <summary>
/// The area in which we are able to move the dragObject around.
/// if null: canvas is used
/// </summary>
public RectTransform dragArea;
private Vector2 originalLocalPointerPosition;
private Vector3 originalPanelLocalPosition;
private RectTransform dragObjectInternal
{
get
{
if (dragObject == null)
return (transform as RectTransform);
else
return dragObject;
}
}
private RectTransform dragAreaInternal
{
get
{
if (dragArea == null)
{
RectTransform canvas = transform as RectTransform;
while (canvas.parent != null && canvas.parent is RectTransform)
{
canvas = canvas.parent as RectTransform;
}
return canvas;
}
else
return dragArea;
}
}
public void OnBeginDrag(PointerEventData data)
{
originalPanelLocalPosition = dragObjectInternal.localPosition;
RectTransformUtility.ScreenPointToLocalPointInRectangle(dragAreaInternal, data.position, data.pressEventCamera, out originalLocalPointerPosition);
}
public void OnDrag(PointerEventData data)
{
Vector2 localPointerPosition;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(dragAreaInternal, data.position, data.pressEventCamera, out localPointerPosition))
{
Vector3 offsetToOriginal = localPointerPosition - originalLocalPointerPosition;
dragObjectInternal.localPosition = originalPanelLocalPosition + offsetToOriginal;
}
ClampToArea();
}
// Clamp panel to dragArea
private void ClampToArea()
{
Vector3 pos = dragObjectInternal.localPosition;
Vector3 minPosition = dragAreaInternal.rect.min - dragObjectInternal.rect.min;
Vector3 maxPosition = dragAreaInternal.rect.max - dragObjectInternal.rect.max;
pos.x = Mathf.Clamp(dragObjectInternal.localPosition.x, minPosition.x, maxPosition.x);
pos.y = Mathf.Clamp(dragObjectInternal.localPosition.y, minPosition.y, maxPosition.y);
dragObjectInternal.localPosition = pos;
}
}
The reason why I post this is because even though @Mmmpies his answer does work in some cases, this code works better when you change the pivot or when you change the Render Mode of the Canvas to ‘Screen Space - Camera’ or ‘World Space’.
ps. I did make it in a way that it uses default values when you leave dragObject or dragArea empty/null, though it is better for performance when you set those values in the inspector