[Unity] 2019-11-13 Study_002 역직렬화(캐릭터,웨폰) 인게임(캐릭터,웨폰 생성)

APP 2019. 11. 13. 00:49

character_data.json
0.00MB
weapon_data.json
0.00MB

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

public class App : MonoBehaviour
{
    Dictionary<int, CharacterData> dicCharacterData; //CharacterData를 관리하는 컬렉션
    Dictionary<int, GameObject> dicPrefab; //Prefab을 관리하는 컬렉션
    Dictionary<int, WeaponData> dicWeaponData; //WeaponData를 관리하는 컬렉션
    Dictionary<int, GameObject> dicWeaponPrefab; //WeaponPrefab을 관리하는 컬렉션
    InGame inGame; //인게임을 관리하는 InGame 컴포넌트
    DataBundle dataBundle; //인게임에 넘길 데이터 묶음을 관리할 멤버
    private void Awake()
    {
        //컬렉션들의 객체 생성
        dicCharacterData = new Dictionary<int, CharacterData>();
        dicPrefab = new Dictionary<int, GameObject>();
        dicWeaponData = new Dictionary<int, WeaponData>();
        dicWeaponPrefab = new Dictionary<int, GameObject>();
    }
    // Start is called before the first frame update
    void Start()
    {
        //arrCharacterData에 character_data.json파일내용 역직렬화        
        CharacterData[] arrCharacterData = JsonConvert.DeserializeObject<CharacterData[]>(Resources.Load<TextAsset>("Data/character_data").text);

        //dicCharacterData에 <id,CharacterData>로 담기
        foreach (CharacterData data in arrCharacterData)
        {
            dicCharacterData.Add(data.id, data);
        }

        //arrWeaponData에 weapon_data.json파일 내용 역직렬화
        WeaponData[] arrWeaponData = JsonConvert.DeserializeObject<WeaponData[]>(Resources.Load<TextAsset>("Data/weapon_data").text);

        //dicWeaponData에 <id, WeaponData>로 담기
        foreach (WeaponData data in arrWeaponData)
        {
            dicWeaponData.Add(data.id, data);
        }

        //dicCharacterData의 모든id에 해당하는 prefab을 dicPrefab에 추가
        foreach (KeyValuePair<int, CharacterData> keyValuePair in dicCharacterData)
        {
            LoadCharacterPrefab(keyValuePair.Key);
        }
        //dicWeaponData 의 모든id에 해당하는 prefab을 dicWeaponPrefab에 추가
        foreach (KeyValuePair<int, WeaponData> keyValuePair in dicWeaponData)
        {
            LoadWeaponPrefab(keyValuePair.Key);
        }

        //App 인스턴스의 데이터묶음에 dicCharacterData,dicPrefab,dicWeaponData를 추가한 DataBundle의 참조를 전달함
        this.dataBundle = new DataBundle(this.dicCharacterData, this.dicPrefab, this.dicWeaponData, this.dicWeaponPrefab);

        //GameObject타입의 inGameGo생성
        GameObject inGameGo = new GameObject("InGame");
        //App 인스턴스의 멤버 inGame에 inGameGo의 InGame스크립트를 컴포넌트로 추가해서 참조를 전달함
        this.inGame = inGameGo.AddComponent<InGame>();
        //inGame객체에 필요한 데이터들을 넘기는 Init메서드 호출
        this.inGame.Init(this.dataBundle);
        //게임을 시작하는 StartGame메서드 호출
        this.inGame.StartGame();
    }

    //Charcter의 Prefab을 id를 매개변수로 로드해서  dicPrefab에 추가
    public void LoadCharacterPrefab(int id)
    {
        string path = $"Prefabs/{dicCharacterData[id].prefab_name}";
        dicPrefab.Add(id, Resources.Load<GameObject>(path));
    }
    //Weapon의 Preafab을 id를 매개변수로 로드해서 dicWeaponPrefab에 추가
    public void LoadWeaponPrefab(int id)
    {
        string path = $"Prefabs/{dicWeaponData[id].prefab_name}";
        dicWeaponPrefab.Add(id, Resources.Load<GameObject>(path));
    }

    // Update is called once per frame
    void Update()
    {

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

public class Character : MonoBehaviour
{
    public CharacterInfo info;
    // Start is called before the first frame update
    void Start()
    {
        
    }
    public void Init(CharacterInfo info)
    {
        this.info = info;
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CharacterData 
{
    //int   string    int   int     float       string      string      string      string      string      string      string      string
    //id    name      hp    damage  atk_range   prefab_name anim_idle   anim_run    anim_atk01  anim_atk02  anim_atk03  anim_damage anim_die

    public int id;
    public string name;
    public int hp;
    public int damage;
    public float atk_range;
    public string prefab_name;
    public string anim_idle;
    public string anim_run;
    public string anim_atk01;
    public string anim_atk02;
    public string anim_atk03;
    public string anim_damage;
    public string anim_die;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CharacterInfo
{
    //int   int  
    //id    hp 

    public int id;   
    public int hp;
    public CharacterInfo(CharacterData characterData)
    {
        this.id = characterData.id;
        this.hp = characterData.hp;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DataBundle
{
    public Dictionary<int, CharacterData> dicCharacterData;
    public Dictionary<int, GameObject> dicPrefab;
    public Dictionary<int, WeaponData> dicWeaponData;
    public Dictionary<int, GameObject> dicWeaponPrefab;
    public DataBundle(Dictionary<int, CharacterData> dicCharacterData, Dictionary<int, GameObject> dicPrefab, Dictionary<int, WeaponData> dicWeaponData, Dictionary<int, GameObject> dicWeaponPrefab)
    {
        this.dicCharacterData = dicCharacterData;
        this.dicPrefab = dicPrefab;
        this.dicWeaponData = dicWeaponData;
        this.dicWeaponPrefab = dicWeaponPrefab;
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public static class GameUtils
{
    //HOW TO USE
    //var cube = this.transform.FirstChildOrDefault(x => x.name == "deeply_nested_cube");
    public static Transform FirstChildOrDefault(this Transform parent, Func<Transform, bool> query)
    {
        if (parent.childCount == 0)
        {
            return null;
        }

        Transform result = null;
        for (int i = 0; i < parent.childCount; i++)
        {
            var child = parent.GetChild(i);
            if (query(child))
            {
                return child;
            }
            result = FirstChildOrDefault(child, query);
        }

        return result;
    }


    public static Transform SearchHierarchyForBone(Transform current, string name)
    {
        //sb.Append(current.name + "\n");

        // check if the current bone is the bone we're looking for, if so return it
        if (current.name == name)
            return current;

        // search through child bones for the bone we're looking for
        for (int i = 0; i < current.childCount; ++i)
        {
            // the recursive step; repeat the search one step deeper in the hierarchy
            var child = current.GetChild(i);

            Transform found = SearchHierarchyForBone(child, name);

            // a transform was returned by the search above that is not null,
            // it must be the bone we're looking for
            if (found != null)
                return found;
        }

        // bone with name was not found
        return null;
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InGame : MonoBehaviour
{
    Dictionary<int, CharacterData> dicCharacterData;
    Dictionary<int, GameObject> dicPrefab;
    Dictionary<int, WeaponData> dicWeaponData;
    public Dictionary<int, GameObject> dicWeaponPrefab;
    Character[] character = new Character[5];   
    Weapon weapon1;
    Weapon weapon2;
    // Start is called before the first frame update
    void Start()
    {

    }
    internal void Init(DataBundle dataBundle)
    {
        this.dicCharacterData = dataBundle.dicCharacterData;
        this.dicPrefab = dataBundle.dicPrefab;
        this.dicWeaponData = dataBundle.dicWeaponData;
        this.dicWeaponPrefab = dataBundle.dicWeaponPrefab;
    }

    internal void StartGame()
    {
        //캐릭터 2명 생성
        this.character[0] = CreateCharacter(200, Vector3.zero);
        this.character[1] = CreateCharacter(300, new Vector3(3, 0, 3));

        //무기 2개 생성       
        this.weapon1 = CreateWeapon(1000);
        this.weapon2 = CreateWeapon(1000);

        //캐릭터0의 DummyRHand를 찾아서 자식으로 wepon1 설정
        Transform character0Hand = GameUtils.SearchHierarchyForBone(this.character[0].transform, "DummyRHand");
        this.weapon1.transform.SetParent(character0Hand, false);
        //캐릭터1의 DummyRHand를 찾아서 자식으로 wepon2 설정
        Transform character1Hand = GameUtils.SearchHierarchyForBone(this.character[1].transform, "DummyRHand");
        this.weapon2.transform.SetParent(character1Hand, false);


    }
   public CharacterInfo CreateInfo(int id)
    {
        return new CharacterInfo(dicCharacterData[id]);
    }

    //캐릭터를 만들어서 캐릭터에 붙인 Character 컴포넌트를 반환
    public Character CreateCharacter(int id,Vector3 initPos)
    {
        GameObject go = new GameObject(dicCharacterData[id].name);
        GameObject modelGo = Instantiate(dicPrefab[id]);
        modelGo.transform.position = Vector3.zero;
        modelGo.transform.SetParent(go.transform, false);
        go.transform.position = initPos;
        return go.AddComponent();
    }

    //무기를 만들어서 무기에 붙인 Weapon 컴포넌트를 반환
    public Weapon CreateWeapon(int id)
    {
        GameObject go = new GameObject(dicWeaponData[id].name);
        GameObject modelGo = Instantiate(dicWeaponPrefab[id]);
        modelGo.transform.position = Vector3.zero;
        modelGo.transform.SetParent(go.transform, false);
        go.transform.position = Vector3.zero;
        return go.AddComponent();
    }

    // Update is called once per frame
    void Update()
    {

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

public class Weapon : MonoBehaviour
{
    public WeaponInfo info;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WeaponData 
{   
    public int id;
    public string name;
    public string prefab_name;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WeaponInfo 
{
    public int id;
}
: