유니티 인벤토리 시스템 구현하기 #7[드래그 앤 드롭]
Intro
-
이번 포스팅에서는 인벤토리내의 아이템 드래그 앤 드롭 기능을 구현해보려합니다.
-
아이템의 드래그 앤 드롭 기능을 구현하는 방법은 다양합니다.
- 각 아이템 아이콘마다 스크립트 부여
- 각 슬롯마다 자식 오브젝트로 아이템의 아이콘이 있습니다.
- 슬롯의 갯수만큼 아이콘의 갯수가 있을겁니다.
- 그렇다면 아이콘을 위한 스크립트를 작성하고 각 슬롯의 아이템에 컴포넌트로 넣어줍니다.
- 드래그 앤 드롭은 포인터 인터페이스로 구현합니다.
- 각 슬롯에 스크립트 부여
- 슬롯을 관리하는 ItemSlotUI에서 드래그 앤 드롭을 구현하는 방법이 있습니다.
- 인벤토리 UI 에서 구현
- 포인터 인터페이스를 사용하지 않고 GraphicRaycaster를 이용하여 InventoryUI 스크립트에서 직접 구현합니다.
- 각 방법마다 장단점이 있습니다. 여기서는 세번째 방법으로 구현해봅니다.
InventoryUI 클래스
private GraphicRaycaster gr;
private PointerEventData ped;
private List<RaycastResult> rrList;
private ItemSlotUI beginDragSlot; // .. 현재 드래그를 시작한 슬롯
private Transform beginDragIconTransform; // .. 해당 슬롯의 아이콘
private Vector3 beginDragIconPoint; // .. 드래그 시작 시 슬롯 위치
private Vector3 beginDragCursorPoint; // .. 드래그 시작 시 커서 위치
private int beginDragSlotSiblingIndex;
void Update()
{
ped.position = Input.mousePosition;
OnPointerClick();
OnPointerDrag();
OnPointerUp();
}
// .. 레이케스트하여 얻은 첫번째 UI에서 컴포넌트 찾아 리턴
private T RaycastAndGetFirstComponent<T>() where T : Component
{
rrList.Clear();
gr.Raycast(ped, rrList);
if (rrList.Count == 0)
return null;
return rrList[0].gameObject.GetComponent<T>();
}
// .. 슬롯 클릭 이벤트(드래그 및 아이템 사용)
private void OnPointerClick()
{
// .. 좌클릭(드래그)
if (Input.GetMouseButtonDown(leftClick))
{
beginDragSlot = RaycastAndGetFirstComponent<ItemSlotUI>();
// .. 아이템이 있는 슬롯일 경우
if(beginDragSlot != null && beginDragSlot.HasItem && beginDragSlot.IsAccessible)
{
// .. 드래그 위치,참조 등록
beginDragIconTransform = beginDragSlot.IconRect.transform;
beginDragIconPoint = beginDragIconTransform.position;
beginDragCursorPoint = Input.mousePosition;
beginDragSlotSiblingIndex = beginDragSlot.transform.GetSiblingIndex();
beginDragSlot.transform.SetAsLastSibling();
beginDragSlot.SetHighlightOnTop(false);
}
else
{
beginDragSlot = null;
}
}
}
// .. 드래그 하는 중
private void OnPointerDrag()
{
if (beginDragSlot == null) return;
if(Input.GetMouseButton(leftClick))
{
// .. 슬롯 아이콘 위치 업데이트
beginDragIconTransform.position = beginDragIconPoint + (Input.mousePosition - beginDragCursorPoint);
}
}
// .. 클릭을 뗄 때
private void OnPointerUp()
{
if(Input.GetMouseButtonUp(leftClick))
{
// .. End Drag
if(beginDragSlot != null)
{
// .. 위치 복원시키기
beginDragIconTransform.position = beginDragIconPoint;
// .. UI 순서 복원
beginDragSlot.transform.SetSiblingIndex(beginDragSlotSiblingIndex);
// .. 드래그 완료 처리
EndDrag();
// .. 하이라이트 이미지를 아이콘보다 앞에
beginDragSlot.SetHighlightOnTop(true);
// .. 참조 제거
beginDragSlot = null;
beginDragIconTransform = null;
}
}
}
- 마우스 포인터의 Down, Drag, Up 이벤트를 구현해주었습니다.
댓글남기기