[StarChaser] 로그라이크 게임 프로젝트

[유니티/C#] 데이터를 관리하는 클래스 만들기

진서박 2023. 6. 6. 00:35
반응형

이전에 데이터를 csv에서 읽어와 저장하는 코드를 작성했었다. 하지만 기능 구현에 중점을 두고 코드를 짜다보니 보기에도, 사용하기에도 별로고 유지보수에도 별로 좋지 못했다.

 

이번에는 csv로 불러온 데이터들을 관리하는 클래스를 만들었다. 이전에 만들어 둔 코드들을 해당 클래스로 옮김으로써 재사용성과 유지보수성을 높이고자 했다.

 

우선 데이터를 총괄하는 "DataClasses" 클래스를 만든다.

 

public class DataClasses
{
    // 데이터를 저장할 클래스들의 리스트 생성
    public List<Skill_Ability_Data> PassiveSkillData = new List<Skill_Ability_Data>();
    public List<Quest_Normal_Data> Quest_NormalData = new List<Quest_Normal_Data>();
	
    // 데이터에 이미지 경로가 지정되어 있다면, 경로상의 이미지를 불러와 이름으로 이미지 저장
    private Dictionary<string, Sprite> loadedSprites = new Dictionary<string, Sprite>();

    public DataClasses()
    {
    	// 생성자 호출 시 데이터를 리스트에 저장
    }
}

 

그 후, 데이터를 불러와 저장할 클래스들을 만든다. 단순히 데이터를 저장할 용도로만 쓸것이기에, 불러올 데이터의 수와 종류에 맞게 변수를 선언하고 생성자를 정의한다.

 

// 일반 퀘스트
public class Quest_Normal_Data
{
    public int QuestID { get; private set; }
    public string QuestCategory { get; private set; }
    public string QuestTitle { get; private set; }
    ...

    public Quest_Normal_Data(int questID, string questCategory, string questTitle, int priorQuestID, int nextQuestID, string questExplainText,
        int questType, int questClearValue, int reward1, int reward1Amount, int reward2, int reward2Amount, int reward3, int reward3Amount)
    {
        QuestID = questID;
        QuestCategory = questCategory;
        QuestTitle = questTitle;
        ...
    }
}

// 스킬
public class Skill_Ability_Data
{
    #region 변수
    public int Skill_ID { get; private set; }
    public int GodID { get; private set; }
    public string SkillName { get; private set; }
    ...

    public Sprite Icon_IMG { get; set; }
    #endregion
    
    public Skill_Ability_Data(int skillID, int godID, string skillName, int skillLevel, int skillGroupID, int priorSkillID,
                 int skillType, int reqWeaponType, int reqPlayerState, int coolTime, float option, int optionType,
                 string icon, string description, Sprite icon_IMG)
    {
        Skill_ID = skillID;
        GodID = godID;
        SkillName = skillName;
        ...
    }
}

 

마지막으로, DataClasses에 데이터를 추가하는 함수를 추가하면 완성!

 

public class DataClasses
{
    // 데이터를 저장할 클래스들의 리스트 생성
    public List<Skill_Ability_Data> PassiveSkillData = new List<Skill_Ability_Data>();
    public List<Quest_Normal_Data> Quest_NormalData = new List<Quest_Normal_Data>();
	
    // 데이터에 이미지 경로가 지정되어 있다면, 경로상의 이미지를 불러와 이름으로 이미지 저장
    private Dictionary<string, Sprite> loadedSprites = new Dictionary<string, Sprite>();

    public DataClasses()
    {
        // 생성자 호출 시 데이터를 리스트에 저장
        PassiveSkillData = ReadSkillTable(GameManagers.DataManager.tableDic[ECSVDatas.SkillTable]);
        Quest_NormalData = ReadQuestTable(GameManagers.DataManager.tableDic[ECSVDatas.NormalQuestTable]);
    }

    // 형식에 맞게 데이터를 불러오는 함수 선언
    private List<Skill_Ability_Data> ReadSkillTable(DataTable table)
    {
        List<Skill_Ability_Data> m_list = new List<Skill_Ability_Data>();

        foreach (DataRow row in table.Rows)
        {
            int skillID = int.Parse(row["Skill_ID"].ToString());
            int godID = int.Parse(row["GodID"].ToString());
            string skillName = row["SkillName"].ToString();
            ...

            Sprite _icon = LoadImage(icon);

            Skill_Ability_Data skill = new Skill_Ability_Data(skillID, godID, skillName, skillLevel, skillGroupID, priorSkillID, skillType,
                                    reqWeaponType, reqPlayerState, coolTime, option, optionType,
                                    icon, description, _icon);
            m_list.Add(skill);
        }

        return m_list;
    }

    private List<Quest_Normal_Data> ReadQuestTable(DataTable table)
    {
        List<Quest_Normal_Data> m_list = new List<Quest_Normal_Data>();

        foreach (DataRow row in table.Rows)
        {
            int questID = int.Parse(row["QuestID"].ToString());
            string questCategory = row["QuestCategory"].ToString();
            string questTitle = row["QuestTitle"].ToString();
            ...

            Quest_Normal_Data skill = new Quest_Normal_Data(questID,questCategory, questTitle, priorQuestID, nextQuestID, questExplainText,
        questType, questClearValue, reward1, reward1Amount, reward2, reward2Amount, reward3, reward3Amount);

            m_list.Add(skill);
        }
        return m_list;
    }

    // 경로를 매개변수로 받아 경로에 있는 이미지를 반환
    private Sprite LoadImage(string path)
    {
        if (loadedSprites.ContainsKey(path))
        {
            return loadedSprites[path];
        }

        Sprite sprite = null;

        if (path != Application.streamingAssetsPath + "NULL")
        {
            byte[] byteTexture = System.IO.File.ReadAllBytes(Application.streamingAssetsPath + path);
            Texture2D texture = new Texture2D(0, 0);
            texture.LoadImage(byteTexture);

            Rect rect = new Rect(0, 0, texture.width, texture.height);
            sprite = Sprite.Create(texture, rect, new Vector2(0.5f, 0.5f));

            loadedSprites.Add(path, sprite);
        }

        return sprite;
    }
}

 

데이터를 저장하고, 불러온 데이터를 사용하는 모든 동작을 담당하던 이전과는 다르게 데이터를 편하게 관리할 수 있게 되었다.

데이터가 추가되면 클래스를 정의하고, 그에 맞게 ReadTable 함수만 새롭게 작성해주면 끝!

 

사실 ReadTable() 함수도 자동화 하고 싶었으나 테이블마다 데이터의 갯수와 종류도 다르기에 실현 불가능한 꿈이 되었다 ㅜ_ㅜ

 

데이터를 이전보다 편하게 관리할 수 있게 된것에 만족

반응형