Last active
March 5, 2024 15:32
-
-
Save Monsoonexe/9c6749d6b561a40fba8dcd8221a8ca37 to your computer and use it in GitHub Desktop.
Drag component for windows in Unity
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEngine.EventSystems; | |
using UnityEngine.UI; | |
namespace SmolderSoft.Gists | |
{ | |
/// <summary> | |
/// Add this component to a Graphic to allow dragging. Keeps within the bounds of the screen. | |
/// </summary> | |
public class DraggableWindow : MonoBehaviour, IDragHandler, IBeginDragHandler | |
{ | |
public bool resetToOriginalPositionOnShow = true; | |
private RectTransform windowRectTransform; | |
private Vector2 offset; | |
public Vector2 OriginalPosition { get; private set; } | |
#region Unity Messages | |
private void Awake() | |
{ | |
windowRectTransform = GetComponent<RectTransform>(); | |
OriginalPosition = windowRectTransform.anchoredPosition; | |
} | |
private void OnEnable() | |
{ | |
if (resetToOriginalPositionOnShow) | |
windowRectTransform.anchoredPosition = OriginalPosition; | |
} | |
#endregion Unity Messages | |
public void OnBeginDrag(PointerEventData eventData) | |
{ | |
// don't start dragging if something like a button was pressed | |
if (eventData.pointerPress && eventData.pointerPress.TryGetComponent<Selectable>(out _)) | |
return; | |
// Calculate the initial offset from the window's position to the mouse position | |
offset = windowRectTransform.position.ToVector2() - eventData.position; | |
} | |
public void OnDrag(PointerEventData eventData) | |
{ | |
// Calculate the clamped position based on the screen bounds | |
Rect bounds = windowRectTransform.rect.Scale(0.9f); | |
Vector2 clampedPosition = eventData.position + offset; | |
// modify lower bounds so window can be moved off screen up to the title bar | |
float lowerBounds = -bounds.height * 0.3f; | |
// horizontal bounds such that window never leaves viewport | |
clampedPosition.x = QuickMath.Clamp(clampedPosition.x, -bounds.xMin, Screen.width - bounds.xMax); | |
// vertical bounds such that the title bar never leaves viewport | |
clampedPosition.y = QuickMath.Clamp(clampedPosition.y, lowerBounds, Screen.height - bounds.yMax); | |
// Update the window's position based on the clamped position | |
windowRectTransform.position = clampedPosition; | |
} | |
} | |
public static class Rect_Extensions | |
{ | |
/// <summary> | |
/// Creates a new rect scaled by <paramref name="scaleFactor"/>. | |
/// </summary> | |
public static Rect Scale(this Rect originalRect, float scaleFactor) | |
{ | |
// Calculate the new dimensions | |
float newWidth = originalRect.width * scaleFactor; | |
float newHeight = originalRect.height * scaleFactor; | |
// Calculate the new position to keep the Rect centered | |
float newX = originalRect.x + (originalRect.width - newWidth) / 2; | |
float newY = originalRect.y + (originalRect.height - newHeight) / 2; | |
// Create the new Rect | |
return new Rect(newX, newY, newWidth, newHeight); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment