현재 만들고 있는 창고의 구도는 다음과 같다.
1. 아이템을 보관할 창고 공간
2. 인벤토리의 아이템 리스트를 불러올 창고 공간
이런 형식으로 인벤토리의 아이템을 관리할 예정이다.
이를 위해선 인벤토리의 정보가 필요했고 마침 캐릭터가 빌드 될 때 인벤토리의
객체 정보를 가지면서 생성됐다.
그래서 창고와 상호작용을 함과 동시에 캐릭터의 객체 정보를 넘겨줘야 했기 때문에
우선 창고 클래스에 상호작용 인터페이스를 적용했고
PlayerInput 쪽에 상호작용 키를 담당하는 부분에서 캐릭터 정보를 넘기도록 했다.
1. PlayerInput
public override async void OnInteractionAsync(InputAction.CallbackContext callbackContext)
{
if (!_senser.TryGetForwardObjectOrClosest(out GameObject closestGo))
{
Debug.Log("Interactive GameObject is Null");
return;
}
else
{
Debug.Log(closestGo.ToString());
}
if(!closestGo.TryGetComponent(out IInteractable interactableGo))
{
Debug.Log("GameObject is not Interactable");
return;
}
interactableGo.OnInteract(_character.gameObject);
}
2. Storage
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class Storage : MonoBehaviour, IInteractable
{
UI_Storage storage;
private void Start()
{
Debug.Log("상자 인스턴스 생성");
storage = UI_Manager.Instance.MakeSubItem<UI_Storage>();
}
public void OnInteract(GameObject interactor)
{
Character character = interactor.GetComponent<Character>();
InventoryController inventoryController = character.GetInventory();
storage.storageController.CopyInventoryList(inventoryController.GetItemList());
if (storage.gameObject.activeSelf)
{
storage.gameObject.SetActive(false);
}
else
{
storage.gameObject.SetActive(true);
}
Debug.Log("Interacting with the Box");
}
}
이를 통해 창고는 캐릭터의 정보를 잘 넘겨받았다.
다음으로 캐릭터에 있는 인벤토리의 정보를 사용하여 인벤토리의 아이템 리스트를 받아오고
이를 보관할 창고 클래스에 다시 보내줘야 했다.
하지만 창고 클래스는 모든 AI캐릭터가 빌드 되면서 생성되야 하기 때문에 싱글톤과 같은
방법으로 접근할 수 없었다.
그렇기 때문에 UI Manager의 기능을 통해 창고 클래스의 정보가 있는 UI_Storage에서 창고 객체 정보를 받아왔는데
사실 이 방법이 맞는지는 모르겠다.
왜냐하면 UI_Storage 클래스는 오로지 UI와 관련된 기능들로 구성되있어야만 했기 때문이다.
3. UI_Storage
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UI_Storage : UI_Base
{
public StorageController storageController;
}
하지만 지금 생각해보면 결국 UI_Storage안에 있는 스크립트 및 기능들이니깐 여기서
불러오는 것이 맞는 것 같다. 나중에 조금 더 고민해보고 구조를 바꿀지 말지 결정해야 겠다.
이제 모든 객체 정보가 모였으니 데이터를 넣어주기만 하면 됐기 때문에
UI_Strorage에서 가져온 StorageController에 리스트 Copy메서드를 제작했다.
4. CopyInventoryList()
public void CopyInventoryList(List<ItemSlotInfo> list)
{
items.Clear();
items.AddRange(list);
Refresh();
}
하지만 여기서도 문제가 발생했는데 창고에 리스트를 추가해서 넣어주는 형식이기 때문이었다.
실행 순서는 StorageController의 Copy메서드 -> StorageModel의 Init메서드로 이어졌는데
모델의 초기화 부분은 무조건 빈 리스트 공간을 사이즈만큼 만들었다.
그래서 컨트롤러의 복사 메서드가 실행되면 빈 리스트에 복사 리스트 데이터가 10개 추가되고
이어서 빈 공간 데이터 10개가 추가됐다.
순서가 모델부터 실행됐으면 초기화 - > 리스트 클리어 -> 새로운 리스트 정보 넣기
이러한 단계로 오류없이 실행이 됐을 거라 예상했지만 현실은 순서가 달랐다.
따라서 예방 조치로 리스트에 이미 데이터가 추가됐다면 초기화 부분에서 빈공간을 넣지
않도록 제작했다.
5. InitializeStorageModel()
public void InitializeStorageModel()
{
if(_items.Count == 0)
{
for (int i = 0; i < _storageSize; i++)
{
_items.Add(new ItemSlotInfo(null, 0));
}
}
}
이것도 뭔가 이상하다..
사실 Storage라는 기초 클래스를 만든 만큼, 이를 상속받는 클래스를 하나 더 만들어서
기능을 추가하면 깔끔하게 해결될 문제긴 하다.
하지만 메서드 하나 추가 하겠다고 상속받는 클래스를 하나 더 만드는 건 비효율적이라 생각했다.
그래서 이 부분을 어떻게 하면 더 깔끔하게 고칠 수 있을지 고민해봐야 겠다.
'프로젝트 기록 > Project N' 카테고리의 다른 글
창고 개발 기록 (NPC) (0) | 2024.04.25 |
---|---|
인벤토리 제작 과정 (아이템 소모) (0) | 2024.04.18 |
인벤토리 개발 기록 (창고와 인벤토리) (0) | 2024.04.03 |
UIManager 구현 기록 (1) | 2024.02.13 |
UIManager는 왜 만드는 걸까? (0) | 2024.02.07 |