Hello,
I want to be able to move ui sprites in my scene
OnMouseDrag gets called but does not move sprite, pls help
I attached this script to my ui sprite and added a boxcollider2d in order to use OnMouseDrag
I am not able to find out why this isnt working
Because the perspective camera is a cone shape, the screen is a point in the world. That makes that regardless where your cursor is, translating this to a world point will always end up being the same exact point. Because of this, no change is actually made in moving the mouse and the sprite does not change position.
What you want to do is project a ray from the point on the screen into the world, and project it onto the plane your sprite is on. On this you can detect the change.
I use this code to drag squares over a plane in the scene view. I am sure you can use this code to write something for your own situation that works.
private void performFloorDrag()
{
//Drag a floor to move it
if (dragFloor != null)
{
//If no floor selected, nothing to drag
if (selectedFloor == null)
{
dragFloor = null;
return;
}
//If the mouse is on the plane
if (getPointOnPlaneOnMouse(out Vector2 point))
{
//If the mouse has moved since last drag
if (point != dragPoint)
{
//Calculate the move onthe mouse
Vector2 move = point - dragPoint;
//Get the current position for the dragging floor
Vector3 currentFloorPosition = dragFloor.LocalPosition;
//Calculate the new intended position for the floor
Vector3 intendedNewFloorPosition = dragFloor.LocalPosition + new Vector3(move.x, 0f, move.y);
//Set the new floor position
moveFloor(dragFloor, intendedNewFloorPosition);
//Get actual new floor position
Vector3 newFloorPosition = dragFloor.LocalPosition;
//Calculate actual performed move on the floor
Vector3 performedFloorMove = newFloorPosition - currentFloorPosition;
//Set new dragpoint to increase with actual move on floor
dragPoint += new Vector2(performedFloorMove.x, performedFloorMove.z);
}
}
}
//If mouse up of leaves window, stop dragging
if (Event.current.type == EventType.MouseUp && Event.current.button == 0 || Event.current.type == EventType.MouseLeaveWindow)
{
dragFloor = null;
dragPoint = Vector2.zero;
}
}
private bool getPointOnPlaneOnMouse(out Vector2 _point)
{
//Set default value
_point = Vector2.zero;
//Create a ray from the scene view into the world
Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
//Create a plane for the floorplan plane
Plane plane = new Plane(component.transform.up, component.transform.position);
//If the cast ray has hit
if (plane.Raycast(ray, out float hit))
{
//Get the point of the hit
Vector3 point = component.transform.InverseTransformPoint(ray.GetPoint(hit));
//Convert to a Vector2 position on the floorplan
_point = new Vector2(point.x, point.z);
//Return true because hit
return true;
}
//Return false if not hit
return false;
}
Hi! I’m having the same issue… did you fix the issue with the suggested resolution?
The only difference in my case is that switching to an orthographic camera doesn’t seem to fix the issue.
public class CellDragScript : CellScript
{
public Transform tr;
public float offsetX;
public float offsetY;
public Vector3 origin;
void Start()
{
tr = transform;
}
private void OnMouseDown()
{
origin = transform.localPosition;
Vector3 point = Camera.main.ScreenToWorldPoint(Vector3.right * Input.mousePosition.x + Vector3.up * Input.mousePosition.y + Vector3.forward * tr.localPosition.y);
offsetX = tr.localPosition.x - point.x;
offsetY = tr.localPosition.z - point.y; // this is intentional, the object is flipped.
}
private void OnMouseDrag()
{
Vector3 point = Camera.main.ScreenToWorldPoint(Vector3.right * Input.mousePosition.x + Vector3.up * Input.mousePosition.y + Vector3.forward * tr.localPosition.y);
tr.localPosition = (Vector3.right * (point.x + offsetX)) + (Vector3.forward * (point.y + offsetY)) + (Vector3.up * tr.localPosition.y);
}
private void OnMouseUp()
{
tr.localPosition = origin;
}
}
The directions work correctly, the problem is the speed of the sprite, is not as fast as the cursor.