E4-Unreal / test-simple-game-framework

simpleFramework for UE 5.1.0
MIT License
0 stars 1 forks source link

인벤토리에 관한 고찰 #49

Open Eu4ng opened 1 year ago

Eu4ng commented 1 year ago

주제 : 인벤토리 슬롯의 Index와 인벤토리 배열의 Index를 1대1 대응시키면 좋지 않다

개요

가장 흔히 생각하는 인벤토리는 칸으로 이루어진 아이템 저장공간이다. 그렇기에 인벤토리의 각 칸을 구분하기 위해서 Index를 사용할 필요가 있다. 인벤토리를 코드로 구현하게 될 때 배열을 많이 사용하는데, 배열 역시 Index로 데이터를 구분하므로 배열의 Index를 인벤토리의 Index로 사용하고 싶은 생각이 들었는데, 이는 다음과 같은 단점이 존재한다.

단점

검색 효율

인벤토리 슬롯과 배열의 요소를 1대1 대응시킬 경우 아이템 검색을 위해 배열의 크기만큼 반복문을 돌려야 하지만, 인벤토리 슬롯에 추가된 아이템과 배열의 요소를 1대1 대응시킬 경우 아이템 검색을 위해 추가된 아이템의 개수만큼만 반복문을 돌리면 된다.

특정 퀘스트 아이템이 필요하다던가 아이템 제작을 위한 재료 아이템을 인벤토리에서 꺼내는 경우를 생각해보자.

인벤토리 슬롯이 100개이고 이를 고정 배열로 구현했다면 아이템이 10개만 들어있더라도 배열의 크기는 100개로 동일할 것이며, 이로 인해 인벤토리 안에 찾고자 하는 아이템이 있는지 확인하기 위해서는 배열의 모든 요소, 즉 100개를 모두 확인해야 한다. 배열 안의 값이 비어있는지 확인하는 것도 결국 해당 요소에 접근해야 알 수 있기 때문이다.

그렇기 때문에 아이템이 추가된 개수만큼 배열의 요소를 추가하는 것이 검색 효율을 높이는 데 좋다. 하지만 그렇다고 Tarray 배열 선언 후 TArray::Add()만 사용하게 되면 힙 메모리 영역에 공간을 확보하는데 효율적이지 않으므로 인벤토리의 최대 슬롯 수만큼 TArray::Reserve로 미리 공간을 확보해두는 것이 좋다.

구현

인벤토리 UI에서는 인벤토리 내에 아이템이 꼭 앞에서부터 차례대로 아이템이 쌓이는 것을 보여주지 않는다. 게임이나 플레이어에 따라 아이템을 가장 끝에서부터 쌓고 싶을 수도 있고 플레이어의 편의에 따라 아이템 위치를 재배치할 수도 있다. 이를 위해 아이템이 인벤토리의 어떤 슬롯에 존재하는지 나타내기 위한 Index가 필요하다.

앞서 언급했듯이 인벤토리 Index는 필요하지만 이를 배열의 Index와 동일하게 취급하는 것이 좋지 않은 방법이기 때문에, 이를 별도로 표기 해주어야 한다. 그렇기에 TArray 배열에 아이템을 추가할 때는 아이템 그 자체를 넣는 것이 아니라 인벤토리의 어떤 슬롯에 존재하는지 나타내기 위한 Index와 아이템 개수 정보를 같이 넣어주어야한다.

즉, FInventoryItem과 같이 아이템 정보, 아이템 개수, 인벤토리 Index 정보를 포함한 구조체를 넣는 방식으로 구현한다

Eu4ng commented 1 year ago

주제 : TSet과 TArray

개요

TSet은 해시를 이용한 컨테이너이고 TArray는 배열 컨테이너이다. TSet은 입력, 삭제, 검색 등이 O(1)인 반면 TArray는 입력, 삭제, 검색 등이 최악의 경우 O(N)이다. 이렇게만 본다면 TSet이 TArray의 상위 호환처럼 보이기 때문에 TSet을 사용하는 것이 좋아 보이지만 TSet은 해시 작업과 오버헤드 등이 있기 때문에 작은 크기의 요소들만 다루는 경우에는 TArray가 TSet보다 성능적으로 우위에 있다.

Java의 경우에는 어떤 사람이 테스트해보길 150개 미만의 경우에는 Array가 HashSet보다 성능이 더 좋았다고 한다.

언젠가 직접 테스트해보고 싶지만 기본적으로 인벤토리 슬롯 수가 몇 백개를 넘어가는 경우가 드믈기 때문에 게임에 따라 다르겠지만, 일반적으로는 TArray를 사용하는 것이 맞는 것 같다.

참고 링크