이 영상들을 보고 정리하였음.
[Unity INVENTORY: A Definitive Tutorial]
https://www.youtube.com/watch?v=oJAE6CbsQQA
[Drag and drop in Unity UI - create your own inventory UI!]
https://www.youtube.com/watch?v=kWRyZ3hb1Vc
Toolbar : 하단 플레이어가 가진 아이템을 보여줌
InventorySlot : ToolBar 안에 들어갈 아이템 슬롯
UI -> Image Toolbar 만들기Source Image 추가UI -> Image InventorySlot 만들고 Toolbar 자식으로 추가Source Image 추가Toolbar에 Grid Layout Group 추가InventorySlot 복사MainInventory : 메인 인벤토리
1. Toolbar 복사
2. 적당히 크기를 조정하고 InventorySlot 복사
3. UI -> Image DarkBackground 만들기
4. 적당히 크기를 조정하고 밝기를 조정
5. DarkBackground를 Canvas의 최상위 자식으로 만들기
6. MainInventroy를 DarkBackground 밑에 위치
7. Create Empty Obejct에서 MainInventoryGroup 만들기
8. MainInventory, DarkBackground를 MainInventoryGroup의 자식으로 만들기
UI -> Image ShowMainInventoryButton 만들기Toolbar 옆에 배치Button 컴포넌트 추가Button On Click() MainInventoryGroup 오브젝트 추가 후, GameObject.SetActive trueButton On Clock() ShowMainInventoryButton 오브젝트 추가 후, GameObject.SetActive falseButton 컴포넌트 추가Button On Click() MainInventoryGroup 오브젝트 추가 후, GameObject.SetActive falseButton On Click() ShowMainInventoryButton 오브젝트 추가 후, GameObject.SetActive trueUI -> Image InventoryItem 만들기InventoryItem.cs 스크립트 만들기InventoryItem.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystem;
/*
IBeginDragHandler : OnBeginDrag Called by a BaseInputModule before a drag is started.
IDragHandler : OnDrag When draging is occuring this will be called every time the cursor is moved.
IEndDragHandler : OnEndDrag Called by a BaseInputModule when a drag is ended.
*/
public class InventoryItem : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler {
[Header("UI")]
public Image image;
// 드래그 이후 부모 Transform을 저장하기 위함
[HideInInspector] public Transform parentAfterDrag;
// Drag and Drop
public void OnBeginDrag(PointerEventData eventData) {
// image.raycastTarget = true 면, 최상위가 자기 자신이라서 InventorySlot을 지정할 수 없음.
image.raycastTarget = false;
// 정확한 위치에 옮기지 않았을 경우 원래 자리로 되돌아가기 위함.
parentAfterDrag = transform.parent;
// 하이어러키에서 제일 밑에 가도록 해서 가장 위에 보이도록 하기위함.
transform.SetParent(transform.root);
}
public void OnDrag(PointerEventData eventData) {
// InvntoryItem의 위치를 마우스 위치로 이동
transform.position = Input.mousePosition;
}
public void OnEndDrag(PointerEventData eventData) {
image.raycastTarget = true;
// 중간에 parentAfterDrag가 변경되지 않았으면 원래 위치로 복귀. 중간에 바뀌었으면 다른 위치로 이동.
transform.SetParent(parentAfterDrag);
}
}
image.raycastTarget = false 사용하는 이유!
raycast를 통해서 가장 위에 있는 오브젝트를 선택하는데, 이 경우 InventoryItem이 최상위에 위치하므로 raycast 시 자신을 무시하게 하는 것!자세한 설명은 여기 참고 : https://danac.tistory.com/210
유니티에서는 하이어러키에서 가장 밑에 있는 게 가장 높은 레이어에 위치!
InventorySlot Grid Layout Group 추가InventorySlot.cs 추가InventorySlot.csusing System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystem;
public class InventorySlot : MonoBehabiour, IDropHandler {
// 마우스에서 손을 때면
public void OnDrop(PointerEventData eventData) {
// InventorySlot의 자식이 없을 때
if(transform.childCount == 0) {
// eventData가 들고있는 InventoryItem을 받고
InventoryItem inventoryItem = eventData.pointerDrag.GetComponent<InventoryItem>();
// Inventory의 parentAfterDrag를 자신의 transform으로 저장. (복귀 위치가 변경됨.)
inventoryItem.parentAfterDrag = transform;
}
}
}