논스톱 나이츠 라이크 프로토타입 만들기 - 케릭터 생성 (데이터 바인딩)

Unity3D 2021. 10. 22. 14:52
반응형

씬을 하나 만들어 주고 

 

TestCreateHeroFromDataMain스크립트를 생성하고 

빈 오브젝트 만들어서 부착 해줍니다 

 

에셋스토어에서 jso을 검색합니다

 

JSON .NET for Unity를 찾아서 다운로드 합니다 

 

 

유니티에서 열기버튼을 선택하고 열리지 않는다면 

이름을 복사해서 

 

 

유니티 에디터에서 패키지 매니저를 열고 

내 에셋을 선택한후 

검색에 붙여 넣고 import 합니다 

 

 

다음과 같이 플레이어를 프리팹으로 만들어 주고 

엑셀 파일을 열어서 다음과 같이 작성 합니다 

hero_data이름으로 저장하고 

아래 사이트를 열어서 엑셀에 작성 했던 내용을 복사해서 윗부분에 붙여넣기 합니다 

 

hero_data.json
0.00MB
hero_data.xlsx
0.01MB

 

https://shancarter.github.io/mr-data-converter/

 

Mr. Data Converter

 

shancarter.github.io

 

 

아래부분에 선택된 내용을 지우고 

 

 

구글에서 json online parser를 검색후 

 

아래부분의 내용을 복사해 붙여 넣고 

 

Format을 눌러줍니다 

 

Viewer를 선택합니다 (문법이 틀렸으면 틀력다고 에러가 날거예요)

다음과 같이 나오면 성공!

다시 text를 눌러서 

내용을 복사한뒤 

메모장을 열어 붙여 넣고

hero_data.json으로 저장합니다 

이때 파일 형식은 모든 파일 

인코딩은 UTF-8로 저장 합니다 

 

다음과 같이 저장되었다면 

파일을 드레그 해서 Assets/Resources 폴더에 넣고 

여기서 Resources폴더는 예약 폴더기 때문이 이름이 반드시 Resources 여야 합니다 

 

 

파일을 눌러보면 형식이 Text Asset이라고 되어 있습니다 

 

 

네임스페이스를 작성하고 

텍스트 에셋을 로드 합니다 

 

로드할때는 매개변수로 path에 파일 명만 적어주면 됩니다 

TextAsset 필드 text를 출력합니다

실행하고 

결과를 확인 합니다 

잘 출력 되었습니다 

 

HeroData스크립트를 만들고 

 

모노 상속을 제거 하고 이벤트 메서드도 제거 합니다 

 

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

public class HeroData 
{

}

 

컬럼 부분을 필드로 만들어 주세요 

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

public class HeroData 
{
    public int id;
    public string prefab_name;
    public float damage;
    public float hp;
}

 

 

아래 코드는 텍스트 에셋을 로드 하고 역직렬화 한뒤 출력하는 코드 입니다 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;

public class TestCreateHeroFromDataMain : MonoBehaviour
{
    void Start()
    {
        TextAsset textAsset = Resources.Load<TextAsset>("hero_data");
        string json = textAsset.text;

        HeroData[] arrHeroDatas = JsonConvert.DeserializeObject<HeroData[]>(json);
        Debug.Log(arrHeroDatas.Length);

        for (int i = 0; i < arrHeroDatas.Length; i++) {
            HeroData heroData = arrHeroDatas[i];
            Debug.LogFormat("{0}, {1}, {2}, {3}", heroData.id, heroData.prefab_name, heroData.damage, heroData.hp);
        }
    }
}

 

 

컬렉션 사전을 생성하고 

넣어줍니다

이때 키는 id고 값은 heroData입니다 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;

public class TestCreateHeroFromDataMain : MonoBehaviour
{
    private Dictionary<int, HeroData> dicHeroDatas = new Dictionary<int, HeroData>();

    void Start()
    {
        this.LoadDatas();
    }

    private void LoadDatas()
    {
        TextAsset textAsset = Resources.Load<TextAsset>("hero_data");
        string json = textAsset.text;

        HeroData[] arrHeroDatas = JsonConvert.DeserializeObject<HeroData[]>(json);
        Debug.Log(arrHeroDatas.Length);

        for (int i = 0; i < arrHeroDatas.Length; i++)
        {
            HeroData heroData = arrHeroDatas[i];
            //Debug.LogFormat("{0}, {1}, {2}, {3}", heroData.id, heroData.prefab_name, heroData.damage, heroData.hp);
            this.dicHeroDatas.Add(heroData.id, heroData);
        }
    }
}

 

 

프리팹 로드 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;

public class TestCreateHeroFromDataMain : MonoBehaviour
{
    private Dictionary<int, HeroData> dicHeroDatas = new Dictionary<int, HeroData>();
    private Dictionary<int, GameObject> dicHeroPrefabs = new Dictionary<int, GameObject>();

    void Start()
    {
        this.LoadDatas();
        this.LoadPrefabs();
    }

    private void LoadPrefabs()
    {
        foreach (KeyValuePair<int, HeroData> pair in this.dicHeroDatas)
        {
            HeroData heroData = pair.Value;
            GameObject prefab = Resources.Load<GameObject>(heroData.prefab_name);
            this.dicHeroPrefabs.Add(heroData.id, prefab);
        }
    }

    private void LoadDatas()
    {
        TextAsset textAsset = Resources.Load<TextAsset>("hero_data");
        string json = textAsset.text;

        HeroData[] arrHeroDatas = JsonConvert.DeserializeObject<HeroData[]>(json);
        Debug.Log(arrHeroDatas.Length);

        for (int i = 0; i < arrHeroDatas.Length; i++)
        {
            HeroData heroData = arrHeroDatas[i];
            //Debug.LogFormat("{0}, {1}, {2}, {3}", heroData.id, heroData.prefab_name, heroData.damage, heroData.hp);
            this.dicHeroDatas.Add(heroData.id, heroData);
        }
    }
}

 

 

 

 

 

네임 스페이스를 추가 하고 

씬을 전환 합니다 

씬 로드시 개체가 사라지지 않도록 해주고 

 

 

 

새씬을 만들어 

이름을 TestGameScene라고 정하고 저장 합니다 

빈 오브젝트를 만들어 이름을 TestGameScene이라고 정해주고 

TestGameSceneMain스크립트를 만들어 부착 합니다 

 

 

빌드 세팅을 열어서 씬을 추가해주고 

 

 

실행 합니다 

 

사전의 접근 제한자를 공개로 바꿔주고 

다음과 같이 작성해주세요 

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

public class TestGameSceneMain : MonoBehaviour
{
    TestCreateHeroFromDataMain testCreateHeroFromDataMain;
    private const int DEFAULT_HERO_ID = 100;

    void Start()
    {
        this.testCreateHeroFromDataMain = GameObject.FindObjectOfType<TestCreateHeroFromDataMain>();

        this.CreateHero(DEFAULT_HERO_ID);
    }

    private void CreateHero(int id)
    {
        HeroData heroData = testCreateHeroFromDataMain.dicHeroDatas[id];

    }
}

 

HeroInfo 스크립트를 만들어 모노와 이벤트 함수를 제거 하고 다음과 같이 만들어 줍니다 

이것은 저장되는 객체 입니다 

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

public class HeroInfo 
{
    public int id;
    public float damage;
    public float hp;

    public HeroInfo(int id, float damage, float hp)
    {
        this.id = id;
        this.damage = damage;
        this.hp = hp;
    }
}

 

데이터를 기반으로 인포 객체를 생성해주고 

 

private void CreateHero(int id)
    {
        HeroData heroData = testCreateHeroFromDataMain.dicHeroDatas[id];

        HeroInfo heroInfo = new HeroInfo(heroData.id, heroData.damage, heroData.hp);
        GameObject heroPrefab = this.testCreateHeroFromDataMain.dicHeroPrefabs[heroInfo.id];
        GameObject heroModel = Instantiate<GameObject>(heroPrefab);


    }

 

 

모델을 로드 한뒤 

새 오브젝트를 만들어 Hero라고 이름을 정해주고 

모델 프리팹을 인스턴스화 해서 자식으로 설정 합니다 

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

public class TestGameSceneMain : MonoBehaviour
{
    TestCreateHeroFromDataMain testCreateHeroFromDataMain;
    private const int DEFAULT_HERO_ID = 100;

    void Start()
    {
        this.testCreateHeroFromDataMain = GameObject.FindObjectOfType<TestCreateHeroFromDataMain>();

        this.CreateHero(DEFAULT_HERO_ID);
    }

    private void CreateHero(int id)
    {
        HeroData heroData = testCreateHeroFromDataMain.dicHeroDatas[id];

        HeroInfo heroInfo = new HeroInfo(heroData.id, heroData.damage, heroData.hp);
        GameObject heroPrefab = this.testCreateHeroFromDataMain.dicHeroPrefabs[heroInfo.id];
        GameObject heroModel = Instantiate<GameObject>(heroPrefab);

        GameObject heroGo = new GameObject();
        heroGo.name = "Hero";
        heroModel.transform.SetParent(heroGo.transform);

    }
}

 

 

TestHero 스크립트를 생성하고 

다음과 같이 작성하고 Init메서드를 만들어 정보와 모델을 매개변수로 전달 할수 있게 해줍니다 

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

public class TestHero : MonoBehaviour
{
    private HeroInfo info;
    private GameObject model;

    public void Init(HeroInfo info, GameObject model)
    {
        this.info = info;
        this.model = model;
    }
}

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

public class TestHero : MonoBehaviour
{
    private HeroInfo info;
    private GameObject model;

    public void Init(HeroInfo info, GameObject model)
    {
        this.info = info;
        this.model = model;

        Debug.LogFormat("id : {0}, damage : {1}, hp : {2}", this.info.id, this.info.damage, this.info.hp);
        Debug.LogFormat("model : {0}", this.model);
    }
}

 

플레이 버튼을 눌러 결과를 확인 합니다 

데이터를 기반으로 플레이어가 잘 생성 되었네요 

반응형
: