오늘의 목표
1. 원하는 슬롯의 물품 버리기
2. 물품을 버릴 때 겹치지 않게 하기 (생성 방식의 문제)
3. 물품이 '사용'되는 방식 만들기
4. 물품을 사용하거나 ,특정 위치에 버리면 특정 행동(열리거나 소리가 나거나 이벤트가 진행되거나) 하는 물품 만들기
1. 원하는 슬롯의 물품 버리기
구현해보고 싶은 물품을 버리는 방식에는 크게 두 가지가 있다.
커서로 드래그해서 버리거나, 마인크래프트 식으로 1,2,3,4,5로 표현해서 버리거나 하는 방식이다.
우선은 구현이 쉽다고 생각하는 마인크래프트 식의 방식으로 구현해보고, 시간이 남는다면 다른 방법을 도전해볼 것이다.
if (inventory.gameObject.activeInHierarchy)
{
inventory.HandleSelotSlection();
if (Input.GetKeyDown(KeyCode.F))
{
if (inventory.selectedSlot != null)
{
inventory.RemoveItem(inventory.selectedSlot,rb.transform.position + Vector3.forward);
}
}
}
public void HandleSelotSlection()
{
if (Input.GetKeyDown(KeyCode.Alpha1)) SelectSlot(0);
if (Input.GetKeyDown(KeyCode.Alpha2)) SelectSlot(1);
if (Input.GetKeyDown(KeyCode.Alpha3)) SelectSlot(2);
if (Input.GetKeyDown(KeyCode.Alpha4)) SelectSlot(3);
if (Input.GetKeyDown(KeyCode.Alpha5)) SelectSlot(4);
}
private void SelectSlot(int input)
{
if (0 <= input && input < 5)
{
selectedSlotIndex = input;
Debug.Log($"Selected slot {selectedSlotIndex}");
}
}
생각보다 간단하게 바꿀 수 있었다. 역시 힘든건 드래그 방식인 듯 하다.
나중에는 선택된 슬롯에 하이라이트 표시를 한다던가 하는 방식으로 구분할 것이다(편의성 증진).
2. 물품을 버릴 때 겹치지 않게 하기
public GameObject SpawnItem(ItemData itemData , Vector3 position)
{
Vector3 randomOffset = new Vector3(0, 0, Random.Range(1.0f, 2.0f));
GameObject itemObeject = Instantiate(itemData.itemprefab, position + randomOffset, Quaternion.identity);
Item item = itemObeject.GetComponent<Item>();
item.Initialize(itemData);
return itemObeject;
}
생성할 때 랜덤 오프셋을 주어 완전히 겹치는 문제를 막고, Rigidobyd와 Collider로 자연스럽게 흩어지게 했다.
지금은 물품을 습득할 때 , 물품을 파괴하고 데이터만 받아온다.
반대로 물품을 버릴 때는 데이터를 바탕으로 물품만 생성한다.
오브젝트 풀 방식으로 더 효율적으로 바꿀 수 있다면 바꿔보고 싶다. 다만 지금은 그정도로 대규모의 아이템이 필요하지 않기 때문에 일단은 보류했다.
3. 물품이 '사용' 되는 방식 만들기
예를 들어 포션과 같은 경우, 아이템을 버리는 것 이외에도 '사용'이라는 선택지가 있다.
아이템 데이터들 중에서, 사용 가능한 아이템들을 선택하고 사용하면 성공을, 아니면 실패의 로그를 찍을 것이다.
else if (hit.transform.CompareTag("interactive"))
{
textMesh.text = "Interactive object";
Item raycastedItem = hit.transform.GetComponent<Item>();
if (currentItem == raycastedItem) return;
currentItem = raycastedItem;
textMesh.gameObject.SetActive(true);
canInteract = true;
}
check아이템에 다음과 같은 코드를 넣어주고
if (playerCursor.canInteract)
{
InteractiveItem interactiveItem = playerCursor.currentItem.GetComponent<InteractiveItem>();
if (inventory.selectedSlot.itemData.ItemName != null)
{
interactiveItem.Interact(inventory.selectedSlot.itemData.ItemName);
}
if (interactiveItem.interactComplete)
{
interactiveItem.interactComplete = false;
inventory.selectedSlot.count--;
if (inventory.selectedSlot.count == 0)
{
inventory.ClearSlot(inventory.selectedSlot);
}
//이벤트를 부름
}
else
{
Debug.Log("Can't interact with this item.");
}
}
}
}
컨트롤러에서 다음과 같이 작성해준다.
public void ClearSlot(InventorySlot slot)
{
slot.itemData = null;
slot.count = 0;
slot.ItemCount.text = slot.count.ToString();
slot.ItemImage.sprite = null;
}
그리고 slot의 count가 0이 되었을 때 작동할 기능을 두 번 이상 썼으므로 함수로 묶어 저장했다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InteractiveItem : Item
{
public string interactiveItemName;
public bool interactComplete = false;
public void Interact(string inputItemName)
{
if (inputItemName != null)
{
if (inputItemName == interactiveItemName)
{
Debug.Log("Succeed");
interactComplete = true;
}
else
{
Debug.Log("Wrong interactive item name");
interactComplete = false;
}
}
}
}
각각의 InteractiveItem마다 다른 함수를 갖고 있고, 이를 바탕으로 다른 이벤트를 동작하게 할 것이다.
들어온 아이템 이름이 자기가 갖고 있는, 동작해야 하는 아이템 이름과 같으면 이벤트를 실행하고 아니면 실패를 반환한다.
4. 사용하면 특정 이벤트 발동하기
다 만들었으나, 코드 리뷰로 인한 시간 부족으로 일단은 저장은 패스.
너무 좋은 경험이었다.
'TIL' 카테고리의 다른 글
[멋쟁이사자처럼 부트캠프 TIL회고] 57일차 : 새로운 시작 (2) | 2025.01.15 |
---|---|
[멋쟁이사자처럼 부트캠프 TIL회고] 56일차 : 버그 수정과 구상 (0) | 2025.01.14 |
[멋쟁이사자처럼 부트캠프 TIL회고] 53일차 : 일요일은 쉬는날 (0) | 2025.01.13 |
[멋쟁이사자처럼 부트캠프 TIL회고] 52일차 : 혼자 공부하기는 즐거워(아님) (0) | 2025.01.12 |
[멋쟁이사자처럼 부트캠프 TIL회고] 51일차 : 스스로 공부하기 (0) | 2025.01.11 |