[Unity] 인벤토리 시스템 1

이경현·2024년 1월 19일

유니티

목록 보기
1/4

이 영상들을 보고 정리하였음.
[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

1. Toolbar, InventorySlot UI 만들기

Toolbar : 하단 플레이어가 가진 아이템을 보여줌
InventorySlot : ToolBar 안에 들어갈 아이템 슬롯

  1. UI -> Image Toolbar 만들기
    • 적당한 Source Image 추가
  2. UI -> Image InventorySlot 만들고 Toolbar 자식으로 추가
    • 적당한 Source Image 추가
  3. ToolbarGrid Layout Group 추가
  4. InventorySlot 복사

2. MainInventroy UI 만들기

MainInventory : 메인 인벤토리
1. Toolbar 복사
2. 적당히 크기를 조정하고 InventorySlot 복사
3. UI -> Image DarkBackground 만들기
4. 적당히 크기를 조정하고 밝기를 조정
5. DarkBackgroundCanvas의 최상위 자식으로 만들기
6. MainInventroyDarkBackground 밑에 위치
7. Create Empty Obejct에서 MainInventoryGroup 만들기
8. MainInventory, DarkBackgroundMainInventoryGroup의 자식으로 만들기

3. ShowMainInventoryButton UI 만들기

  1. UI -> Image ShowMainInventoryButton 만들기
  2. Toolbar 옆에 배치
  3. Button 컴포넌트 추가
  4. Button On Click() MainInventoryGroup 오브젝트 추가 후, GameObject.SetActive true
  5. Button On Clock() ShowMainInventoryButton 오브젝트 추가 후, GameObject.SetActive false

4. DarkBackground 버튼 추가

  1. Button 컴포넌트 추가
  2. Button On Click() MainInventoryGroup 오브젝트 추가 후, GameObject.SetActive false
  3. Button On Click() ShowMainInventoryButton 오브젝트 추가 후, GameObject.SetActive true

5. Inventory Drag & Drop

  1. UI -> Image InventoryItem 만들기
  2. 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

유니티에서는 하이어러키에서 가장 밑에 있는 게 가장 높은 레이어에 위치!

  1. InventorySlot Grid Layout Group 추가

6. InventorySlot.cs

  1. InventorySlot.cs 추가
    InventorySlot.cs
using 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;
		}
	}
}
profile
게임 개발자 지망생

0개의 댓글