- Home /
Question by
AarnasS75 · Nov 30, 2021 at 09:36 PM ·
c#drag-and-dropsnapping
Drag and drop object and make it snap to the nearest edge
I want to do the same thing as in the Code.org project (gif below). I managed to create the drag and drop thingy, but I can't figure out how to make the object snap to bottom or top side of the placed object.
So far I have this:
public class UI_Drag : MonoBehaviour
{
public bool startDrag, inUse;
Vector2 startPos, slotPos;
RectTransform placementSlot;
RectTransform local;
List<RectTransform> snapPositions;
void Start()
{
startPos = transform.position;
local = GetComponent<RectTransform>();
}
void Update()
{
if (startDrag)
{
transform.position = Input.mousePosition;
}
}
public void StartDragUI()
{
startDrag = true;
}
public void StopDragUI()
{
startDrag = false;
if (inUse)
{
transform.position = new Vector2(slotPos.x + 30 + local.rect.width / 2, slotPos.y - 20 - local.rect.height / 2);
}
else
{
SnapToClosestSide();
}
}
public static Vector3 GetSpriteCorner(RectTransform img)
{
Vector3[] v = new Vector3[4];
img.GetWorldCorners(v);
return v[1];
}
private void SnapToClosestSide()
{
float closestDistance = -1;
RectTransform closestSnapPosition = null;
foreach (RectTransform snapPos in snapPositions)
{
float distanceToTopSide = Vector2.Distance(local.rect.position, new Vector2(snapPos.rect.xMax, snapPos.rect.yMax));
float distanceToBottomSide = Vector2.Distance(local.rect.position, new Vector2(snapPos.rect.xMin, snapPos.rect.yMin));
if (closestSnapPosition == null || distanceToTopSide < distanceToBottomSide)
{
closestSnapPosition = snapPos;
closestDistance = distanceToTopSide;
}
else if (closestSnapPosition == null || distanceToTopSide > distanceToBottomSide)
{
closestSnapPosition = snapPos;
closestDistance = distanceToBottomSide;
}
}
if (closestSnapPosition != null && closestDistance <= 0.5f)
{
transform.position = closestSnapPosition.rect.position;
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag("Slot"))
{
inUse = true;
placementSlot = collision.GetComponent<RectTransform>();
slotPos = GetSpriteCorner(placementSlot);
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.CompareTag("Slot"))
{
inUse = false;
}
}
}
Thank you!
drag-and-drop.gif
(440.3 kB)
current.gif
(133.5 kB)
Comment
Your answer

Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Make Object snap to position within Trigger area when mouse button released 0 Answers
I need help with moving a character in Unity2D c# but just along a path 0 Answers
Illuminating a 3D object's edges OnMouseOver (script in c#)? 1 Answer