2 분 소요

Intro

이번 포스팅에서는 실제로 무기데이터를 JSON 형태의 파일로 작성하고, 그 파일에 담긴 데이터를 게임내에서 사용할 수 있도록 읽어들이는것을 구현 정리하였습니다.

image

예를들어 상점이 있다고할 때,

상점에서 보여지는 각 아이템들은 완성된 오브젝트가 아닌 단순히 버튼 또는 이미지이고 실제로 구입했을 땐 각 UI에 붙여놓았던 ‘ID’를 가지고 JSON 파일에서 해당 ID에 맞는 데이터를 가져와 실제로 생성하는식의 방법을 생각했습니다.

이게 맞는 방식인지는 모르겠으나, 저는 이런식으로 한번 구현해보려고합니다.

JSON 파일 작성

먼저 무기아이템의 정보를 WeaponData.json 파일을 하나 생성하여 작성했습니다.

JSON 파일의 위치는 persistentDataPath 경로입니다.

(JSON 파일을 작성하는 방법은 인터넷에 많이 나와있으므로 따로 정리하지않았습니다.)

{
    "Sword": [
        {
            "id": 1001,
            "itemName": "기본 검",
            "itemToolTip": "기본 검이다.",
            "damage": 10,
            "rate": 1.0
        },
        {
            "id": 1002,
            "itemName": "강철 검",
            "itemToolTip": "강철 검이다.",
            "damage": 20,
            "rate": 1.0
        }
    ]
}

저는 ‘Sword’ 배열안에 검 데이터 두개를 넣어봤습니다.

이제 만든 JSON 파일을 가져오는 작업을 해야합니다.

DataManager 클래스

기존 DataManager 클래스에 JSON 파일을 불러오는 부분을 추가했습니다.

using Newtonsoft.Json;

    private string weaponItemDataPath;      // 무기 데이터 저장경로
    // WeaponData를 저장할 딕셔너리
    private Dictionary<int, WeaponItemData> weponDataDictionary;

    private void Awake()
    {
        weponDataDictionary = LoadWeaponData(); 
    }

    // 무기 데이터 불러오기
    private Dictionary<int, WeaponItemData> LoadWeaponData()
    {
        if(File.Exists(weaponItemDataPath))
        {
            string jsonData = File.ReadAllText(weaponItemDataPath);
            var weaponDict = JsonConvert.DeserializeObject<Dictionary<string, List<WeaponItemDTO>>>(jsonData);
            
            // 우선은 검 데이터만
            if(weaponDict.TryGetValue("Sword", out List<WeaponItemDTO> weaponList))
            {
                Dictionary<int, WeaponItemData> dataDictionary = new Dictionary<int, WeaponItemData>();

                // DTO를 WeaponItemData로 변환하여 저장
                foreach(var weaponDTO in weaponList)
                {
                    WeaponItemData weaponData = new WeaponItemData(weaponDTO);
                    dataDictionary[weaponData.ID] = weaponData;
                }
                return dataDictionary;
            }
            else
            {
                Debug.LogWarning("WeaponData.json 파일에 'Sword'키가 없습니다.");
            }
        }
        else
        {
            Debug.LogWarning("불러올 파일이 없습니다.");
        }
        return new Dictionary<int, WeaponItemData>();
    }
  • 복잡한 JSON 파일같은경우 Newtonsoft.Json 라이브러리를 사용하여 역직렬화할 수 있습니다.
    • 패키지매니저를통해 다운로드 받을 수 있습니다.
  • 게임이 시작되면 LoadWeaponData() 함수가 호출됩니다.
  • LoadWeaponData() 함수에서는 WeaponData.json 파일의 내용을 List 형태로 읽어와서 이것을 Dictionary 형태로 변환합니다.
    • 굳이 리스트형태로 읽어와 딕셔너리로 변환하는것은
    • 만약 데이터의 양이 방대해지게되면 Dictionary를 사용하는것이 효율적이기 때문입니다.
  • 우선은 Sword 배열의 데이터만 가져와 각 리스트(검1, 검2 데이터)를 WeaponItemData로 변환시켜 딕셔너리에 저장합니다.
    • 변환한 데이터는 우리가 실제로 ‘id’를 통해 검색하기위한 딕셔너리 weaponDataDictionary에 <int, WeaponData> 쌍으로 데이터를 저장합니다.

이제 JSON 파일을 읽어오긴했고, 이것을 사용하기만한다면 완성입니다.

DataManager 클래스에 아이템 ‘ID’를 통해 검색할 수 있는 기능을 추가합니다.

// ID로 무기 데이터 가져오기
    public WeaponItemData GetDataById(int id)
    {
        if(weponDataDictionary != null && weponDataDictionary.TryGetValue(id, out var resultData))
        {
            return resultData;
        }
        else
        {
            Debug.LogWarning("ID에 해당하는 데이터가 없음.");
            return null;
        }
    }
  • 아이디를 가지고 GetDataById() 함수를 호출하면 WeaponItemData 형태로 데이터를 반환하게됩니다.
    • 예를들어, WeaponController 라는 클래스에서 GetDataByID(1001) 를 호출하면 ID = 1001 인 객체의 데이터가 반환됩니다.

테스트

임의로 WeaponController 라는 클래스를 만들어 동작되는지 확인해봤습니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WeaponController : MonoBehaviour
{
    int testId = 1001;          // 검색 테스트용 id

    void Start()
    {
        // ID = 1001인 데이터 객체 검색하기
        WeaponItemData weaponData = DataManager.Instance.GetDataById(testId);

        // 콘솔창에 데이터 표시
        if(weaponData != null)
        {
            Debug.Log("무기 ID : " + weaponData.ID);
            Debug.Log("무기 이름 : " + weaponData.ItemName);
            Debug.Log("무기 툴팁 : " + weaponData.ItemToolTip);
            Debug.Log("무기 데미지 : " + weaponData.Damage);
            Debug.Log("무기 공격속도 : " + weaponData.Rate);
        }
        else
        {
            Debug.Log("데이터가 없습니다!");
        }
    }
}

image

댓글남기기