2024.12.16(월)
이전 글: [Unity] 드래그 앤 드롭 시스템 만들기 : UI to World & World to World
이전에 만들었던 드래그 앤 드롭 시스템에 사소한 문제가 있었다.
바로, 드래그 앤 드롭 시스템이 ScrollView의 Scroll 시스템을 가린다는 것이다.
찾아보니까 ScrollView의 시스템도 IBeginDragHandler, IDragHandler, IEndDragHandler에 의해 조절이 된다는 것을 알게 됐다.
그래서, 이것을 적절히 이용해서 드래그 앤 드롭 시스템을 ScrollView의 영역을 나갔을 때만 발동되게 만들어 주었다.
UI에서만 일어나는 일이기 때문에, DraggableUI만 손봐주면 된다.
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class DraggableUI : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
public DraggableContent draggableContent; // 연결된 콘텐츠 설정
[SerializeField] private ScrollRect scrollView; // ScrollView 참조 (Inspector에서 설정)
private bool isDragging = false; // 드래그 상태 확인
private bool isInScrollView = false; // 현재 스크롤 영역 내부인지 확인
private PointerEventData cachedEventData; // 스크롤 이벤트 캐싱용
public void OnBeginDrag(PointerEventData eventData)
{
// ScrollView 영역인지 확인
if (scrollView != null)
{
isInScrollView = RectTransformUtility.RectangleContainsScreenPoint(
scrollView.GetComponent<RectTransform>(),
eventData.position,
eventData.pressEventCamera
);
if (isInScrollView)
{
// ScrollView 내부라면 스크롤 이벤트를 캐싱하고 ScrollView의 OnBeginDrag 호출
cachedEventData = eventData;
scrollView.OnBeginDrag(eventData);
return;
}
}
// ScrollView 외부라면 드래그 시작
isDragging = true;
DragAndDropManager.Instance.BeginDrag(draggableContent, eventData);
}
public void OnDrag(PointerEventData eventData)
{
// 상태 전환 로직: 마우스 위치를 기반으로 상태 변경
if (scrollView != null)
{
bool currentlyInScrollView = RectTransformUtility.RectangleContainsScreenPoint(
scrollView.GetComponent<RectTransform>(),
eventData.position,
eventData.pressEventCamera
);
// ScrollView에서 Drag로 전환
if (isInScrollView && !currentlyInScrollView)
{
isInScrollView = false;
isDragging = true;
// ScrollView 동작 종료
scrollView.OnEndDrag(cachedEventData);
// Drag 동작 시작
DragAndDropManager.Instance.BeginDrag(draggableContent, eventData);
return;
}
// Drag에서 ScrollView로 전환
if (!isInScrollView && currentlyInScrollView)
{
isInScrollView = true;
isDragging = false;
// Drag 동작 종료
DragAndDropManager.Instance.EndDrag(eventData);
// ScrollView 동작 시작
scrollView.OnBeginDrag(eventData);
return;
}
}
// 현재 상태에 따라 적절한 동작 수행
if (isInScrollView)
{
scrollView.OnDrag(eventData); // ScrollView의 스크롤 처리
}
else if (isDragging)
{
DragAndDropManager.Instance.Drag(eventData); // Drag 처리
}
}
public void OnEndDrag(PointerEventData eventData)
{
// 현재 상태에 따라 동작 종료
if (isInScrollView)
{
scrollView.OnEndDrag(eventData);
}
else if (isDragging)
{
DragAndDropManager.Instance.EndDrag(eventData);
}
// 상태 초기화
isDragging = false;
isInScrollView = false;
cachedEventData = null;
}
}
다음과 같이 작성하면 ScrollView 내에서는 드래그로 ScrollView가 작동하고, ScrollView를 벗어나면 드래그 앤 드롭 시스템이 작동, 그리고 다시 ScrollView 내부로 마우스가 들어오면 ScrollView가 작동하게 된다.
ScrollView... 참 좋은 기능이죠