참고 영상 : https://www.youtube.com/watch?v=kWRyZ3hb1Vc
https://www.youtube.com/watch?v=BGr-7GZJNXg
드래그 앤 드롭 순서
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "NewInventory", menuName = "Inventory/Inventory")]
public class Inventory : ScriptableObject
{
public List<Item> items = new List<Item>(); // 아이템 목록
public void AddItem(Item item)
{
items.Add(item);
}
public void RemoveItem(Item itemToRemove)
{
items.Remove(itemToRemove);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 아이템 타입
public enum ItemType
{
Equipment, // 장비형
Consumable, // 소비형
Material, // 재료
Quest, // 퀘스트
Misc // 기타
}
// 장비 슬롯 타입
public enum EquipmentSlotType
{
None,
Head,
Chest,
Legs,
Feet,
Weapon,
Shield,
Accessory
}
// 아이템 희귀도
public enum Rarity
{
Common,
Uncommon,
Rare,
Epic,
Unique,
Legendary
}
[CreateAssetMenu(fileName = "NewItem", menuName = "Inventory/Item")]
public class Item : ScriptableObject
{
[Header("기본 정보")]
public string itemName; // 아이템 이름
public Sprite itemIcon;// 아이템 아이콘
public string itemDescription;// 아이템 설명
public ItemType itemType;// 아이템 타입
public string itemID;// 고유 ID
public bool isStackable; // 중첩 가능 여부
public int maxStackSize = 1; // 최대 중첩 개수
[Header("아이템 효과")]
public float useTime = 1f; // 사용 시간
public bool canUseInBattle = true; // 전투중 사용 가능 여부
[Header("장비 속성")]
public bool isEquipment; // 장비 여부
public EquipmentSlotType equipSlot; // 장착 슬롯 종류
public int durability = 100; // 내구도
public int defense; // 방어력
public int attack; // 공격력
// 추가 : 무기 속성(빛,어둠,물,불)
[Header("소비 아이템 속성")]
public bool isConsumable; // 소비 아이템 여부
public float healthRestore; // HP 회복량
public float manaRestore; // MP 회복량
public float duration; // 효과 지속시간
[Header("기타")]
public int buyPrice; // 구매 가격
public int sellPrice; // 판매 가격
public string requiredLevel; // 필요 레벨
public Rarity rarity; // 희귀도
// 아이템 사용 메서드
public virtual void Use(Player player)
{
if (isConsumable)
{
// 소비 아이템 사용 로직
//player.RestoreHealth(healthRestore);
//player.RestoreMana(manaRestore);
}
}
// 장비 장착 메서드
public virtual void Equip(Player player)
{
if (isEquipment)
{
// 장비 장착 로직
//player.AddDefense(defense);
//player.AddAttack(attack);
}
}
// 장비 해제 메서드
public virtual void Unequip(Player player)
{
if (isEquipment)
{
// 장비 해제 로직
//player.RemoveDefense(defense);
//player.RemoveAttack(attack);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 아이템 데이터베이스 ScriptableObject
[CreateAssetMenu(fileName = "ItemDatabase", menuName = "Inventory/ItemDatabase")]
public class ItemDatabase : ScriptableObject
{
// 만들어둔 아이템 SO들을 리스트에 미리 전부다 할당해놓기.
public List<Item> items = new List<Item>();
// ID로 아이템 찾기
public Item FindItemById(string id)
{
return items.Find(item => item.itemID == id);
}
// Name으로 아이템 찾기
public Item FindItemByName(string name)
{
return items.Find(item => item.itemName == name);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemPickUp : MonoBehaviour
{
public string itemId; // 고유 아이템 ID를 Inspector에서 입력
//public Item itemData; // 인스펙터에서 아까 만든 아이템 에셋을 여기에 연결
private void OnTriggerEnter(Collider other)
{
transform.SetAsLastSibling();
//if (other.CompareTag("Player"))
//{
// InventoryManager.Instance.AddItemToInventory(itemData);
// // 아이템 획득 처리
// //bool wasPickedUp = InventoryManager.instance.AddItemToInventory(itemData);
// //if (wasPickedUp)
// //{
// // Debug.Log($"{itemData.itemName} 획득!");
// // Destroy(gameObject);
// //}
//}
if (other.CompareTag("Player"))
{
// 아이템 데이터베이스에서 ID로 아이템 찾기
Item itemToPickUp = InventoryManager.Instance.itemDatabase.FindItemById(itemId);
if (itemToPickUp != null)
{
bool wasPickedUp = InventoryManager.Instance.AddItemToInventory(itemToPickUp);
if (wasPickedUp)
{
Debug.Log($"{itemToPickUp.itemName} 획득!");
Destroy(gameObject);
}
}
else
{
Debug.LogError($"ID {itemId}에 해당하는 아이템을 찾을 수 없습니다.");
}
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InventoryManager : MonoBehaviour
{
public static InventoryManager Instance { get; private set; }
public Inventory playerInventory; // 인벤토리 ScriptableObject
public GameObject inventoryUI;
public ItemDatabase itemDatabase; // 아이템 데이터 베이스 SO
public bool activeInventory;
public List<Slot> slots = new List<Slot>();
public Transform slotHolder;
int slotCount { get { return slotCount; } set { } }
private void Awake()
{
// 싱글톤 패턴 구현
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject); // 씬 전환시에도 유지되도록 설정
}
else
{
Destroy(gameObject);
}
}
private void Start()
{
gameObject.SetActive(true);
slots.AddRange(slotHolder.GetComponentsInChildren<Slot>());
inventoryUI.SetActive(activeInventory);
//slotCount = 4;
}
private void Update()
{
if(Input.GetKeyDown(KeyCode.I))
{
activeInventory = !activeInventory;
inventoryUI.SetActive(activeInventory);
}
}
public bool AddItemToInventory(Item item)
{
if (playerInventory != null)
{
playerInventory.AddItem(item);
Debug.Log($"{item.itemName}이(가) 인벤토리에 추가되었습니다.");
}
else
{
Debug.LogError("playerInventory가 할당되지 않았습니다!");
}
// 빈 슬롯 찾기
foreach (Slot slot in slots)
{
// 슬롯의 이미지가 비어있다면
if (slot.itemImage.sprite == null)
{
// 슬롯에 아이템 설정
slot.SetItem(item);
Debug.Log($"{item.itemName} 아이템 획득!");
return true;
}
}
return false;
}
public void RemoveItemFromInventory(Item item)
{
if (playerInventory != null)
{
playerInventory.RemoveItem(item);
Debug.Log($"{item.itemName}이(가) 인벤토리에서 제거되었습니다.");
}
else
{
Debug.LogError("playerInventory가 할당되지 않았습니다!");
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class DraggableItem : MonoBehaviour, IBeginDragHandler, IDragHandler ,IEndDragHandler
{
public Transform parentAfterDrag; // 드래그가 끝난 후 아이템이 위치할 부모 객체를 저장
public Image image; // 아이템 이미지
// 드래그 시작 시 호출
public void OnBeginDrag(PointerEventData eventData)
{
parentAfterDrag = transform.parent; // 현재 부모를 parentAfterDrag에 저장
transform.SetParent(transform.root); // 아이템을 최상위 레벨로 이동시켜 다른 UI 요소 위에 표시되게 합니다.
transform.SetAsLastSibling(); // 부모의 자식 목록에서 가장 마지막으로 이동
image.raycastTarget = false; // 레이캐스트 타겟을 비활성화하여 드래그 중 다른 UI 요소와 상호작용하지 않게 합니다.
}
// 드래그 중 지속적으로 호출
public void OnDrag(PointerEventData eventData)
{
transform.position = Input.mousePosition; // 아이템의 위치를 마우스 커서 위치로 업데이트
}
// 드래그가 끝날 때 호출
public void OnEndDrag(PointerEventData eventData)
{
transform.SetParent(parentAfterDrag);
image.raycastTarget = true; // 레이캐스트 타겟을 다시 활성화 ( 상호작용 가능하게 만듦 )
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class Slot : MonoBehaviour, IDropHandler
{
public Image itemImage; // 현재 슬롯의 아이템 이미지
public Item currentItem; // 현재 슬롯의 아이템 정보
// 슬롯에 아이템 설정 메서드
public void SetItem(Item item)
{
// 아이템 이미지 활성화
//itemImage.gameObject.SetActive(true);
currentItem = item; // 현재 아이템 저장
// 아이템 아이콘 설정
itemImage.sprite = item.itemIcon;
}
// 슬롯 초기화 메서드
public void ClearSlot()
{
//itemImage.gameObject.SetActive(false);
currentItem = null; // 아이템 참조 제거
itemImage.sprite = null;
}
// 아이템이 이 슬롯에 드롭될 때 호출
public void OnDrop(PointerEventData eventData)
{
// 아래 코드는 이전의 코드
//if(transform.childCount == 1)
//{
// GameObject dropped = eventData.pointerDrag;
// DraggableItem draggableItem = dropped.GetComponent<DraggableItem>();
// draggableItem.parentAfterDrag = transform;
//}
GameObject dropped = eventData.pointerDrag;
// dropped가 null인지 먼저 체크
if (dropped == null)
{
Debug.LogWarning("드래그된 오브젝트가 없습니다.");
return;
}
DraggableItem draggableItem = dropped.GetComponent<DraggableItem>();
// draggableItem이 null인지 체크
if (draggableItem == null)
{
Debug.LogWarning("DraggableItem 컴포넌트를 찾을 수 없습니다.");
return;
}
// 드래그된 아이템의 원래 슬롯 찾기
//Slot originalSlot = draggableItem.GetComponentInParent<Slot>();
// 원래 슬롯 찾기 (GetComponentInParent 대신 다른 방법 사용)
//Slot originalSlot = dropped.GetComponentInParent<Slot>();
Slot originalSlot = draggableItem.parentAfterDrag.GetComponent<Slot>();
if (originalSlot == null)
{
Debug.LogWarning("원래 슬롯을 찾을 수 없습니다.");
return;
}
// 현재 슬롯에 아이템이 있는 경우
if (itemImage.sprite != null)
{
// 원래 슬롯 초기화
originalSlot.ClearSlot();
}
else
{
// 원래 슬롯에서 아이템 제거
originalSlot.ClearSlot();
}
// 드래그된 아이템을 현재 슬롯의 자식으로 설정
draggableItem.parentAfterDrag = transform;
// 현재 슬롯에 아이템 설정
SetItem(originalSlot.currentItem);
}
}
유니티 3D 발소리,footstep,Sound 적용하기 (0) | 2024.12.24 |
---|---|
유니티 OnValidate() (0) | 2024.12.21 |
유니티 인벤토리 데이터 베이스 (0) | 2024.11.26 |
유니티 인벤토리 아이템 설정 (1) | 2024.11.08 |
유니티 딕셔너리 (0) | 2024.11.01 |