using UnityEngine; using UnityEngine.EventSystems; namespace Gpm.Ui { /// /// UI 요소를 마우스 드래그로 이동할 수 있게 만드는 컴포넌트입니다. /// 이 컴포넌트를 UI GameObject에 추가하면 해당 UI를 화면 내에서 자유롭게 움직일 수 있습니다. /// /// /// 사용 방법: /// /// 1. 움직이게 하고 싶은 UI GameObject(예: Image, Panel)를 선택합니다. /// 2. 인스펙터 창에서 [Add Component] 버튼을 누르고 'DraggableRect'를 검색하여 추가합니다. /// 3. 'Drag Rect Transform' 필드에 움직일 대상을 지정합니다. 비워두면 컴포넌트가 부착된 GameObject 자신이 움직입니다. /// 4. 게임을 실행하고 UI를 마우스로 드래그하면 이동하는 것을 확인할 수 있습니다. /// public class DraggableRect : DragaEventHandler { /// /// 드래그 시 실제로 위치가 변경될 UI의 RectTransform입니다. /// 만약 비어있다면, 이 스크립트가 부착된 GameObject의 RectTransform이 기본값으로 사용됩니다. /// public RectTransform dragRectTransform; // 성능 최적화를 위해 Canvas 컴포넌트를 캐싱하는 변수입니다. private Canvas m_Canvas; /// /// 이 UI가 속해 있는 최상위 Canvas에 대한 참조입니다. /// 드래그 이동량을 계산할 때 Canvas의 scaleFactor를 적용하여, /// Canvas Scaler의 설정과 관계없이 일관된 속도로 움직이게 합니다. /// public Canvas canvas { get { if(m_Canvas == null) { // 컴포넌트의 부모 계층에서 Canvas를 찾아서 할당합니다. m_Canvas = GetComponentInParent(); } return m_Canvas; } } /// /// 컴포넌트가 활성화될 때 호출되는 Unity 생명주기 함수입니다. /// 필요한 변수를 초기화하고, 드래그 이벤트를 리스너에 등록합니다. /// protected override void OnEnable() { if (dragRectTransform == null) { // dragRectTransform이 설정되지 않았다면, 현재 GameObject의 RectTransform으로 설정합니다. dragRectTransform = gameObject.GetComponent(); } // 필수적인 RectTransform이나 Canvas가 없으면 컴포넌트를 비활성화합니다. if (dragRectTransform == null || canvas == null) { enabled = false; } // 부모 클래스(DragaEventHandler)의 onDrag 이벤트에 OnDragMove 함수를 연결합니다. // 이제 드래그가 발생할 때마다 OnDragMove 함수가 호출됩니다. onDrag.AddListener(OnDragMove); } /// /// 컴포넌트가 비활성화될 때 호출되는 Unity 생명주기 함수입니다. /// 메모리 누수를 방지하기 위해 등록했던 이벤트 리스너를 제거합니다. /// protected override void OnDisable() { // OnEnable에서 연결했던 OnDragMove 함수를 onDrag 이벤트에서 제거합니다. onDrag.RemoveListener(OnDragMove); } /// /// 드래그 이벤트가 발생할 때 호출되는 함수입니다. /// 마우스의 움직임에 따라 dragRectTransform의 위치를 업데이트합니다. /// /// 드래그 이벤트와 관련된 정보(예: 마우스 이동량)를 담고 있습니다. public void OnDragMove(PointerEventData eventData) { // eventData.delta는 이번 프레임에서 마우스가 움직인 거리(픽셀 단위)입니다. // 이를 canvas.scaleFactor로 나누어주어 Canvas 좌표계에 맞는 이동량으로 변환합니다. // 변환된 값을 anchoredPosition에 더하여 UI를 이동시킵니다. dragRectTransform.anchoredPosition += eventData.delta / canvas.scaleFactor; } /// /// 이 컴포넌트의 부모 계층 구조가 변경될 때 호출됩니다. /// (예: 다른 Canvas 하위로 이동될 경우) /// 캐시된 Canvas 정보를 다시 최신 상태로 갱신합니다. /// protected override void OnCanvasHierarchyChanged() { m_Canvas = GetComponentInParent(); } } }