[Unity3D] 인벤토리 [Part 4] - Load
※ 주의
이 글은 아마추어가 개인적으로 생각하여 작성하는 것으로, 이곳에 나오는 내용을 맹신하지 않는것을 당부드립니다.
Menu
1. 인벤토리 껍데기 만들기.
- 인벤토리의 Pivot 설정.
- 슬롯의 Pivot 설정.
- 슬롯 사이즈 설정.
- 슬롯 간 거리 설정.
- 슬롯의 가로, 세로 개수 설정.
- 인벤토리의 가로 사이즈, 세로 사이즈 설정.
- 슬롯 생성 및 부모설정.
- 모든 슬롯을 관리해줄 리스트를 생성.
2. 아이템 획득 시 검사조건 만들기 및 슬롯 기능 만들기.
- 아이템을 먹었을 때, 인벤토리 내의 슬롯을 모두 검사한다.
*검사조건 : -> 슬롯 내에 같은 아이템이 존재하는지?
-> 슬롯내에 같은 아이템이 존재할 경우 겹칠수 있는지?
-> 슬롯내에 같은 아이템이 존재하지만, 겹칠수 없는경우 빈 슬롯이 존재 하는지?
- 슬롯을 스택으로 만들어 아이템 관리하기
->아이템이 슬롯에 들어갔을때 이미지 변경.
->아이템을 겹칠경우 텍스트 갱신.
->아이템을 사용할 경우 텍스트 갱신.
->아이템을 모두 사용했을 때 이미지 변경.
3. 아이템 만들기 및 획득
- 아이템 타입 설정.
- 아이템의 이미지 설정.
- 아이템 겹칠수 있는 최대치 설정.
- 아이템과의 충돌로 아이템 획득하기.
4. 인벤토리내에 아이템 드래그 앤 드랍으로 아이템 옮기기 및 자리 바꾸기.
- 처음 마우스 버튼을 누를 때
- 누르고 이동할 때
- 드래그가 끝났을 때
- 누른 버튼을 땠을 때
의 4가지 상태로 나눠 드래그 앤 드랍 구현.
5. XML문서를 이용한 인벤토리 아이템 저장.
- Save
- Load
5. XML문서를 이용한 인벤토리 아이템 저장. - Load
우선 흐름부터 살펴보도록 하자.
1. InventoryData.xml이라는 파일이 존재하는지 확인한다.
=> 파일이 존재하지 않으면 함수종료.
=>System.IO.File.Exists(경로) : 이 함수는 경로내의 파일이 존재하면 true 존재하지 않으면 false를 되돌려주는 함수이다.
2. xml문서를 하나 만든다.
3. 만든 xml문서에 InventoryData.xml을 불러온다.
4. 요소를 하나 만들어서 불러온 xml파일로 초기화 시킨다.
5. 필드를 하나 만들어서 InventoryData.xml문서의 최상위에 있는 필드로 초기화 시킨다.
6. 필드의 존재하는 슬롯번호를 하나 꺼내와서 슬롯의 n번째 번호를 가져와, 그 번호를 이용하여 슬롯의 'Slot'스크립트를 꺼내온다.
7. 아이템 클래스로 아이템 객체를 하나 만든다.
8. 필드에서 Name, MaxCount를 꺼내와서 새로 생성된 아이템의 내용을 초기화 시킨다.
Item Script 추가사항.
9. 필드에서 Count를 꺼내와서 Count의 수만큼 반복문을 돌린다.
=> 위에서 6에서 가져왔던 Slot스크립트를 이용하여 이 슬롯에 아이템을 AddItem()을 호출하여 집어넣는다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | public static List<GameObject> Load(List<GameObject> SlotList) { if (!System.IO.File.Exists(Application.dataPath + "/Save/InventoryData.xml")) return SlotList; XmlDocument XmlDoc = new XmlDocument(); // 문서를 만듬. XmlDoc.Load(Application.dataPath + "/Save/InventoryData.xml"); // 경로상의 XML파일을 로드 XmlElement Xmlel = XmlDoc["ItemDB"]; // 속성 ItemDB에 접속. foreach (XmlElement ItemElement in Xmlel.ChildNodes) { // 슬롯의 n번째 스크립트를 가져온다. Slot slot = SlotList[System.Convert.ToInt32(ItemElement.GetAttribute("SlotNumber"))].GetComponent<Slot>(); // 아이템 생성. Item item = new Item(); // 아이템의 정보를 셋팅한다. string Name = ItemElement.GetAttribute("Name"); // 아이템 이름을 가져옴. int MaxCount = System.Convert.ToInt32(ItemElement.GetAttribute("MaxCount")); // 겹칠수 있는 한계. item.Init(Name, MaxCount); // 위의 가져온 정보를 토대로 아이템의 정보를 초기화. int Count = System.Convert.ToInt32(ItemElement.GetAttribute("Count")); // 슬롯에 아이템을 n개 집어넣기 위해서 개수를 가져옴. for (int i = 0; i < Count; i++) slot.AddItem(item); } return SlotList; } | cs |
'Inventory' 스크립트에 Awake()에서는 인벤토리와 슬롯이 만들어진다.
슬롯이 만들어지게 되면 슬롯객체 안에 존재하는 'Slot' 스크립트의 Start()가 수행되는데,
이 Start()의 수행이 끝난뒤 우리가 저장한 정보를 Load해야한다.
만약 Inventory 스크립트의 Awake()가 수행되기전에 Load()를 수행하면 아직 만들어지지도 않은 슬롯에
정보를 할당하려 했으므로 에러를 내뿜게 된다.
마찬가지로 Slot 스크립트의 Start()가 수행되기전에 Load()를 수행한다면 슬롯의 아이템을 담아놓는 Stack자체가
생성되지 않았기 때문에 에러를 내뿜게 된다.
그렇기 때문에 모든 슬롯의 Start()가 끝나게 되면 Load를 수행하면 된다.
하지만 모든 슬롯의 Start()의 수행이 언제 끝날지는 알 수 없으므로 사용자가 임의로 시작을 지연시키고 그 뒤 정보를 Load시킨다. 불안정한 방법이지만 Awake() 및 Start() 수행속도는 빠른 편이므로 시간을 아주 조금만 지연시켜주면 된다.
Inventory스크립트에 Awake()안에 Invoke를 이용하여 Init()함수를 호출해주고, 시간을 0.01f초 지연시키도록 하자.
1 2 3 4 5 6 | Invoke("Init", 0.01f); void Init() { ItemIO.Load(AllSlot); } | cs |
'Unity3D > Project' 카테고리의 다른 글
[Unity3D] 헥사게임 만들기 두 번째 - 블럭보드 만들기. (0) | 2018.02.13 |
---|---|
[Unity3D] 헥사게임 만들기 첫 번째 - 리소스 준비하기 및 캔버스 크기 설정. (0) | 2018.02.11 |
[Unity3D] 인벤토리 [Part 4] - Save (3) | 2017.04.23 |
[Unity3D] 인벤토리 [Part 3] - Item Drag & Swap (5) | 2017.04.13 |
[Unity3D] 인벤토리 [Part 2] - Item Add (13) | 2017.04.12 |