1. 프로젝트 생성
2. 데이터 연동에 사용될 캐릭터 리소스 임포트
3. 캐릭터 데이터 엑셀 테이블 작성 및 저장
4. 캐릭터 생성 버튼에 사용할 텍스쳐 저장 및 임포트
5. 텍스처 리소스들을 Inspector에서 Texture Type을 Sprite (2D and UI)로 변경 및 Apply
6. 엑셀 테이블 데이터 복사
7. Converter를 이용해 Json 문법으로 변환
8. JsonVIewer로 문법 검사
9. 메모장으로 데이터 입력 후, 저장 (hero_data.json)
10. Resources 폴더를 만들어서 그 안에 json파일 옮기기
11. 데이터 연동이 되는지 테스트 해볼 씬을 생성(App)
12. 빈 오브젝트(AppMain)과 데이터를 연동할 스크립트(AppMain)을 생성후 연결

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

public class AppMain : MonoBehaviour
{
    void Start()
    {
        TextAsset asset = Resources.Load<TextAsset>("Data/hero_data");
        Debug.Log(asset.text);
    }
}

13. 스크립트(AppMain)에 json파일의 경로(path)연결 후 Debug로 로그 확인 해보기

14. 씬 실행 후, 콘솔 창에서 데이터 로드 확인
15. 데이터 직렬화&역직렬화를 위해 HeroData 스크립트 생성 및 데이터 타입 정의
16. Package Manager에서 Add package by name 클릭 후, 위와 같이 작성 후, Add 클릭
17. Packages에서 json 검색 후, 인스톨

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;  //네임 스페이스 추가 

public class AppMain : MonoBehaviour
{
    void Start()
    {
        TextAsset asset = Resources.Load<TextAsset>("Data/hero_data");//Unity의 Resources 폴더에서 파일을 로드
        Debug.Log(asset.text);  //json 문자열 

        //역직렬화 
        HeroData[] heroDatas= JsonConvert.DeserializeObject<HeroData[]>(asset.text); //Json 문자열을 HeroData[] 타입으로 역직렬화
        foreach (HeroData data in heroDatas) { //역직렬화 된 HeroData 객체들의 정보를 순회하며 출력
            Debug.LogFormat("{0} {1} {2} {3} {4} {5}", data.id, data.name, data.max_hp, data.damage, data.prefab_name, data.sprite_name);
        }
    }
}

18. AppMain 스크립트에서 데이터 역직렬화를 위한 코드 추가

19. 콘솔 창에서 데이터 역직렬화 확인
20. 싱글톤 패턴으로 관리하기 위해 DataManager 스크립트 생성
21. instance를 전역 변수로 선언(싱글톤 패턴), App의 코드를 옮겨 LoadHeroData()로 메서드 선언
22. AppMain에서는 instance로 LoadHeroData() 호출
22. 싱글톤으로 씬 정상적으로 작동 확인
24. 효과적인 데이터 관리와 빠른 검색을 위해 HeroData 객체를 Dictionary에 저장
25. 콘솔 창에서 Dictionary 저장 확인
26. 변동 데이터를 관리할 HeroInfo 스크립트 생성
27. 변동될 데이터(hp, damage)와 id 선언, 생성자를 통해 해당 변수들의 초기 값 설정 가능
28. 데이터를 연동받아 생성될 프리팹을 만들기 위해 리소스 모델을 생성한 후, Unpack
29. Resources 폴더 내에 Prefabs 폴더 생성 후, 리소스 모델들을 Prefabs 폴더로 프리팹으로 저장
30. 프리팹들을 로드하기 위해 필요한 이름들을 가져오기 위해 DataManager에서 GetHeroPrefabNames() 선언
31. DataManager의 GetHeroPrefabNames를 통해 Prefabs 폴더 안의 프리팹들의 경로(path)를 연결하고 순차적으로 불러와 프리팹 로드, GameObject List에 저장
32. 콘솔 창에서 프리팹이 로드되었는지 확인
33. Hero(캐릭터)를 생성할 버튼 생성
34. id를 버튼의 텍스트에 입력 후 버튼 배치

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;  //네임 스페이스 추가 
using UnityEngine.UI;
using System;

public class AppMain : MonoBehaviour
{

    //프리팹이 저장될 변수 
    private List<GameObject> prefabs = new List<GameObject>();

    [SerializeField]
    private Button[] btns; //버튼 배열 인스턴스 선언

    void Start()
    {
        DataManager.instance.LoadHeroData();

        //프리팹 리소스 로드 
        this.LoadPrefabs();


        //버튼 이벤트 붙이기 
        foreach (Button btn in this.btns)
        {
            btn.onClick.AddListener(() => {
                var text = btn.gameObject.GetComponentInChildren<Text>(); //버튼의 텍스트(id)를 받아옴
                Debug.Log(text.text);
                int id = Convert.ToInt32(text.text); 
                this.CreateHero(id); //id를 통해 Hero프리팹 인스턴스 생성
            });
        }
    }

    private void CreateHero(int id)
    {
        int index = id - 100; 
        Debug.LogFormat("index: {0}", index);
        GameObject prefab = this.prefabs[index];
        Debug.Log(prefab);
		GameObject heroGo = new GameObject();
        heroGo.name = "Hero";
        Instantiate<GameObject>(prefab, heroGo.transform);

        
       



        
    }

    private void LoadPrefabs()
    {
        List<string> heroPrefabNames = DataManager.instance.GetHeroPrefabNames();

        foreach (string prefabName in heroPrefabNames)
        {
            string path = string.Format("Prefabs/{0}", prefabName);
            Debug.Log(path);
            GameObject prefab = Resources.Load<GameObject>(path);
            this.prefabs.Add(prefab);
        }
        Debug.LogFormat("프리팹들이 로드 되었습니다. count: {0}", this.prefabs.Count);
    }
}

35. 버튼 배열 선언과 버튼 이벤트 넣기(Hero 생성)

36. 스크립트의 버튼 배열 인스턴스에 버튼 연결
37. 씬 실행 후, 잘 생성되는지 확인
38. Hero 오브젝트의 정보를 담을 Hero 스크립트 생성

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

public class Hero : MonoBehaviour
{
    private HeroInfo info; //hero의 가변적 데이터
    private GameObject model; // hero의 프리팹
    public void Init(HeroInfo info, GameObject model)
    {
        this.info = info; 
        this.model = model; 

        Debug.LogFormat("Init: {0}, {1}", this.info, this.model);
    }
}

39. HeroInfo와 프리팹을 담는 Hero 스크립트 작성

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;  //네임 스페이스 추가 
using UnityEngine.UI;
using System;
using System.IO;

public class AppMain : MonoBehaviour
{

    //프리팹이 저장될 변수 
    private List<GameObject> prefabs = new List<GameObject>();

    [SerializeField]
    private Button[] btns; //버튼 배열 인스턴스 선언

    void Start()
    {
        DataManager.instance.LoadHeroData();

        //프리팹 리소스 로드 
        this.LoadPrefabs();


        //버튼 이벤트 붙이기 
        foreach (Button btn in this.btns)
        {
            btn.onClick.AddListener(() => {
                var text = btn.gameObject.GetComponentInChildren<Text>(); //버튼의 텍스트(id)를 받아옴
                Debug.Log(text.text);
                int id = Convert.ToInt32(text.text); 
                this.CreateHero(id); //id를 통해 Hero프리팹 인스턴스 생성
            });
        }
    }

    private void CreateHero(int id)
    {
        string filePath = string.Format("{0}/hero_info.json", Application.persistentDataPath);

        Debug.Log(filePath);

        HeroInfo heroInfo = null; //변수 정의 

        if (File.Exists(filePath)) //있다 (기존유저)
        {
            Debug.Log("<color=red>기존유저</color>");
            // 파일 로드 후 역직렬화, HeroInfo 객체 생성
            string jsonData = File.ReadAllText(filePath);
            heroInfo = JsonConvert.DeserializeObject<HeroInfo>(jsonData);

          

        }
        else //없다 (신규유저)
        {
            Debug.Log("<color=green>신규유저</color>");
            HeroData heroData = DataManager.instance.GetHeroData(id);
            heroInfo = new HeroInfo(heroData.id, heroData.max_hp, heroData.damage);

            // 생성된 HeroInfo 객체를 직렬화하여 JSON 파일로 저장
            string jsonData = JsonConvert.SerializeObject(heroInfo);
            File.WriteAllText(filePath, jsonData);
        }




        int index = id - 100;
        Debug.LogFormat("index: {0}", index);
        GameObject prefab = this.prefabs[index];
        Debug.Log(prefab);
        GameObject heroGo = new GameObject();
        heroGo.name = "Hero";
        GameObject model = Instantiate<GameObject>(prefab, heroGo.transform); // model은 heroGo의 자식객체로 인스턴스화

        Hero hero = heroGo.AddComponent<Hero>();
        
        hero.Init(heroInfo, model); //Hero 컴포넌트에 model과 info를 넘김




    }

    private void LoadPrefabs()
    {
        List<string> heroPrefabNames = DataManager.instance.GetHeroPrefabNames();

        foreach (string prefabName in heroPrefabNames)
        {
            string path = string.Format("Prefabs/{0}", prefabName);
            Debug.Log(path);
            GameObject prefab = Resources.Load<GameObject>(path);
            this.prefabs.Add(prefab);
        }
        Debug.LogFormat("프리팹들이 로드 되었습니다. count: {0}", this.prefabs.Count);
    }
}

40. hero_info.json 파일을 로드 또는 생성하기 위해 AppMain 수정

41. hero_info.json 파일이 없을 때 (신규 유저)
42. hero_info.json 파일이 있을 때 (기존 유저)

+ Recent posts