UI창고 드래그드랍 시연 영상
플레이어의 인벤토리와 창고 사이에 아이템을 옮긴다면
유니티에서 제공하는 EventSystems 에서 제공하는 인터페이스를 써서 실습

public class DropZone : MonoBehaviour, IDropHandler
{
public void OnDrop(PointerEventData eventData)
{
//온 드롭이 발동되었을때 마우스 드래깅 중인 컨텐츠가 존재했다면
if(eventData.pointerDrag != null)
{
//드래그중이던 대상의 부모를 이거로 바꾼다
eventData.pointerDrag.transform.SetParent(transform);
}
}
}
public class DragableImage : MonoBehaviour, IBeginDragHandler, IDragHandler,IEndDragHandler
{
//드래깅을 당할 수 있는 모든 UI오브젝트들이 들고 있을 내용
//원래라면 EventSystem에서 UI인지 체크하거나 레이 쏴서 UI 확인하는? 어려운 과정이 필요하지만 정의된 인터페이스 사용
//드래깅 3가지 스탭을 위해 인터페이스 추가. 드래깅 시작, 드래깅 중, 드래그 종료 ,IBeginDragHandler 등
private Transform originalParent; //원래 부모 패널
private Image image;
private CanvasGroup canvasGroup;
[SerializeField] GameObject cubePrefab; //인스펙터로 넣어줄 프리팹
private void Start()
{
image = GetComponent<Image>(); //드래그중에 이미지 색상을 바꾼다던가 가능(코드에는 없음)
canvasGroup = gameObject.AddComponent<CanvasGroup>(); //컴포넌트 코드로 추가, 물론 미리 추가해놓고 가져와도 됨
}
public void OnBeginDrag(PointerEventData eventData)
{
//1. 원래 부모를 기억
originalParent = transform.parent;
//2. 위에서 기억 미리 해놨으니 이제 집을 나온다. 최상위 계층으로 이동(드래그 원활하게 해줌)
transform.SetParent(originalParent.root); //최상위 계층인 Canvas를 부모로 적용
//3. 드래깅 중인 이미지를 반투명
canvasGroup.alpha = 0.5f;
//4. 레이케스트 블라킹을 끔 //드롭 영역 감지가 원활하도록, 자기자신 감지가 잘되도록
canvasGroup.blocksRaycasts = false; //드롭 영역 감지가 수월하도록
}
//드래그 중일땐, 위치정보 등 드래깅에 필요한 모든 정보가 eventData에 들어있음
public void OnDrag(PointerEventData eventData)
{
transform.position = eventData.position; //마우스 위치로 따라감
}
//마우스 떼버리면?
public void OnEndDrag(PointerEventData eventData)
{
// 패널에 놓기,이미지남기기, 아니면 돌아간다
canvasGroup.alpha = 1f; //반투명 이미지 원복
canvasGroup.blocksRaycasts = true; //다시 감지 가능하게
/*
//아래코드 주석 해제하면 드래그한 오브젝트 위치에 게임오브젝트 생성함
if(!IsDroppedOnUI(eventData))
{
SpawnCubeAtMoustPosition();
Destroy(gameObject); //이건 만약 UI 이미지 없애버릴거면
}
else
{
transform.SetParent(originalParent);
}
*/
//드롭이 감지되지 않았다면 원래 위치로 복귀
//조건에 맞으면 변경하는 코드는 DropZone.cs에서 함
if(transform.parent == originalParent.root)
{
transform.SetParent(originalParent);
}
}
//UI에 드롭시켰는지 판단할 메서드
private bool IsDroppedOnUI(PointerEventData eventData)
{
//포인터엔터는 (터치 혹은) 마우스가 닿아있는 UI 오브젝트를 가리킴
//드롭 시점에 마우스가 UI위에 있다면 그 UI의 게임오브젝트가 담기고
//아무 UI위에 없으면 널이 담김
return eventData.pointerEnter != null &&
eventData.pointerEnter.transform.IsChildOf(originalParent.root);
}
private void SpawnCubeAtMoustPosition()
{
Vector2 mousePos = Mouse.current.position.ReadValue(); //마우스 위치 받아올 수 있음 (유니티6)
Ray ray = Camera.main.ScreenPointToRay(mousePos);
RaycastHit hit;
if(Physics.Raycast(ray, out hit))
{
Instantiate(cubePrefab,hit.point,Quaternion.identity);
}
}
}
유니티엔진에서 사용되는 UnityEngine.EventSystems 클래스중 하나
UI요소에 대한 포인터(moust/touch) 입력 관련 정보를 처리하기위해 사용
if(eventData.pointerDrag != null) //드래그 상태였다면
transform.position = eventData.position; //마우스 위치로 따라감
eventData.pointerEnter //포인터가 어떤 UI요소 안으로 진입 하였는지
eventData.pointerEnter.transform //해당 요소에 접근하는듯
이미지에는 C#스크립트로 IBeginDragHandler, IDragHandler, IEndDragHandler 를 상속받는 스크립트 정의
드래그 시작, 드래그중, 드래그 끝을 체크하는 메서드를 상속받아서 코드를 작성한다
이미지를 넣을 Panel에는 IDropHandler 를 상속받는 스크립트 정의
마우스를 놓았을때 Panel끼리 해당 이미지를 넣을 수 있도록 한다
패널에 Grid Layout Group을 넣어서 이미지가 정렬될 수 있게끔 (스크립트로도 가능하긴 함)