본문 바로가기

Unity/과제

2020-05-14 과제 게임만들기(미완성)

먼저 오브젝트풀을 제대로 이해하고 싶었기에, 처음부터 다시 천천히 만들기로 결심했다.

 

그래서그런지 아직미완성이다.

 

하지만 오브젝트풀이 왜 필요한지 데이터매니져와 오브젝트풀을 연동하려면 어떻게 해야하는지, 얼추 알게 되었고, 어느정도 생각정리가 되었다.

 

그리고 하면서, 그전에 아리송했었던, Instantiate ,AddComponent, transform.SetParent가 

언제 어떻게 써야하는지를 확실히 알게 되었다. 

물론 완벽하게 이해한것은 아니지만, 전에는 어느시점에서 사용해야 결과가 어떻게나오는지를 전혀 모르고,

의식의흐름대로 사용했다면, 지금은 어떻게 사용해야, 결과가 어떻게 되는지 알게 되었다.

-----------------------------------------------------------------------------------------------------------------------

 

플레이 영상

 

 

오브젝트풀 사용

 

 

@@소스코드

 

App.class

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
 
public class App : MonoBehaviour
{
    private void Awake() //Awake에 로드하면 컴포넌트가 안넘어갑니다.
    {
        UnityEngine.Object.DontDestroyOnLoad(this.gameObject); // 앱 파괴 막기     
    }
    void Start()
    {
        DataManager.GetInstance().LoadAllData();  //데이터 매니져 로드.
        SceneManager.LoadScene("Title"); //타이틀로 화면전환
    }
 
    // Update is called once per frame
    void Update()
    {
        
    }
}
 
 
 

 

Title.class

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
 
public class Title : MonoBehaviour
{
    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            SceneManager.LoadScene("Lobby");
        }
    }
}
 
 
 

Lobby.class

더보기
using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
 
public class Lobby : MonoBehaviour
{
    public List<Button> btnRaceList;
    public List<Button> btnWeaponList;
    public List<Button> btnBlessList;
 
    public Button btnNext;
    public Sprite weaponImage;
    public Sprite[] arrSprite;
 
    private ObjectPool objectPool;
    private Hero hero;
 
    private List<string> characterNameList;
    private List<string> weaponNameList;
    private List<string> effectNameList;
 
    private void Awake()
    {
        //컴포넌트로 붙여줘야 스크립트 작동
        this.objectPool = this.gameObject.AddComponent<ObjectPool>();
        this.objectPool.Init();
        this.objectPool.LoadAllAsset();
    }
 
    public void Init()
    {
        this.characterNameList = new List<string>();
        this.weaponNameList = new List<string>();
        this.effectNameList = new List<string>();
 
        foreach (var pair in this.objectPool.dicCharacterData)
        {
            this.characterNameList.Add(pair.Value.res_name);
        }
 
        foreach (var pair in this.objectPool.dicWeaponData)
        {
            this.weaponNameList.Add(pair.Value.res_name);
        }
 
        foreach (var pair in this.objectPool.dicEffectData)
        {
            this.effectNameList.Add(pair.Value.res_name);
        }
 
 
    }
    // Start is called before the first frame update
    void Start()
    {
        this.Init();
 
        foreach (var element in this.weaponNameList)
        {
            Debug.Log(element);
        }
 
        for (int i = 0; i < this.btnRaceList.Count; i++)
        {
            int capturedIdx = i;
            this.btnRaceList[i].onClick.AddListener(() =>
            {
                Debug.Log(capturedIdx);
                this.CreateHero(capturedIdx);
                this.hero.Init(Vector3.zero);
            });
        }
 
        for (int i = 0; i < this.btnWeaponList.Count; i++)
        {
            int capturedIdx = i;
            this.btnWeaponList[i].onClick.AddListener(() =>
            {
                Debug.Log(capturedIdx);
                hero.EquipItem(this.Getitem(capturedIdx));
            });
        }
 
        for (int i = 0; i < this.btnBlessList.Count; i++)
        {
            int capturedIdx = i;
            this.btnBlessList[i].onClick.AddListener(() =>
            {
                Debug.Log(capturedIdx);
                //this.CreateHero(capturedIdx);
            });
        }
 
 
    }
 
    private void CreateHero(int capturedIdx)
    {
        if (GameObject.Find("Hero"== null)
        {
            var shellGo = new GameObject();
            shellGo.name = "Hero";
            shellGo.transform.SetParent(this.transform);
        }
 
        Debug.Log(GameObject.Find("Hero"));
 
        for (int i = 0; i < this.characterNameList.Count; i++)
        {
 
            if (i == capturedIdx)
            {
                var modelGo = this.objectPool.GetAsset(this.characterNameList[i]);
                var shellGo = GameObject.Find("Hero");
                modelGo.transform.SetParent(shellGo.transform);
 
                var hero = shellGo.AddComponent<Hero>();
                this.hero = hero;
                
            }
            else
            {
                this.objectPool.ReleaseAsset(GameObject.Find(this.characterNameList[i]));
            }
        }
    }
    private GameObject Getitem(int capturedIdx)
    {
        var item = this.objectPool.GetAsset(this.weaponNameList[capturedIdx]);
        return item;
    }
 
    // Update is called once per frame
    void Update()
    {
 
    }
}
 
 
 

DataManager.class

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using System.IO;
using System.Linq;
 
public class DataManager
{
    private static DataManager instance;
    private Dictionary<int, CharacterData> dicCharacterData;
    private Dictionary<int, WeaponData> dicWeaponData;
    private Dictionary<int, EffectData> dicEffectData;
 
    // Start is called before the first frame update
 
    private DataManager()
    {
        this.Init();
    }
 
    private void Init()
    {
        this.dicCharacterData = new Dictionary<int, CharacterData>();
        this.dicWeaponData = new Dictionary<int, WeaponData>();
        this.dicEffectData = new Dictionary<int, EffectData>();
    }
 
    public static DataManager GetInstance()
    {
        if (DataManager.instance == null)
        {
            DataManager.instance = new DataManager();
        }
 
        return DataManager.instance;
    }
 
    public void LoadAllData()
    {
        TextAsset characterDataTextAsset = Resources.Load("Json/character_data"as TextAsset;
        string json1 = characterDataTextAsset.text;
        this.dicCharacterData = (JsonConvert.DeserializeObject<CharacterData[]>(json1)).ToDictionary(x => x.id, x => x);
 
        TextAsset weapondataTextAsset = Resources.Load("Json/weapon_data"as TextAsset;
        string json2 = weapondataTextAsset.text;
        this.dicWeaponData = (JsonConvert.DeserializeObject<WeaponData[]>(json2)).ToDictionary(x => x.id, x => x);
 
        TextAsset effectdataTextAsset = Resources.Load("Json/effect_data"as TextAsset;
        string json3 = effectdataTextAsset.text;
        this.dicEffectData = (JsonConvert.DeserializeObject<EffectData[]>(json3)).ToDictionary(x => x.id, x => x);
    }
 
    public Dictionary<int, CharacterData> GetDicCharacterData()
    {
        return this.dicCharacterData;
    }
    public Dictionary<int, WeaponData> GetDicWeaponData()
    {
        return this.dicWeaponData;
    }
    public Dictionary<int, EffectData> GetDicEffectData()
    {
        return this.dicEffectData;
    }
 
    public CharacterData GetCharacterDataById(int id)
    {
        return this.dicCharacterData[id];
    }
 
    public WeaponData GetWeaponDataById(int id)
    {
        return this.dicWeaponData[id];
    }
 
    public EffectData GetEffectDataById(int id)
    {
        return this.dicEffectData[id];
    }
}
 
 
 

ObjectPool.class

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEditor.VersionControl;
using UnityEngine;
 
public class ObjectPool : MonoBehaviour
{
    private static ObjectPool instance;
    private List<string> assetNamesList;
    private List<GameObject> assetList;
 
    public Dictionary<int, CharacterData> dicCharacterData;
    public Dictionary<int, WeaponData> dicWeaponData;
    public Dictionary<int, EffectData> dicEffectData;
 
    private GameObject objectPool;
 
    private void Awake()
    {
        ObjectPool.instance = this;
 
        this.assetNamesList = new List<string>();
        this.assetList = new List<GameObject>();
    }
 
    private void Start()
    {
        this.Init();
    }
 
    public static ObjectPool GetInstance()  //static 잊지말자
    {
        return ObjectPool.instance;
    }
 
    public void Init()
    {
 
        this.dicCharacterData = new Dictionary<int, CharacterData>();
        this.dicWeaponData = new Dictionary<int, WeaponData>();
        this.dicEffectData = new Dictionary<int, EffectData>();
 
        this.dicCharacterData = DataManager.GetInstance().GetDicCharacterData();
        this.dicWeaponData = DataManager.GetInstance().GetDicWeaponData();
        this.dicEffectData = DataManager.GetInstance().GetDicEffectData();
 
        /*
         test용
        Debug.Log(this.dicCharacterData);
        Debug.Log(this.dicWeaponData);
        Debug.Log(this.dicEffectData);
        =잘들어옴
        */
 
        foreach (var pair in this.dicCharacterData)
        {
            this.assetNamesList.Add(pair.Value.res_name);
        }
 
        foreach (var pair in this.dicWeaponData)
        {
            this.assetNamesList.Add(pair.Value.res_name);
        }
 
        foreach (var pair in this.dicEffectData)
        {
            this.assetNamesList.Add(pair.Value.res_name);
        }
 
        
         //테스트용 = 잘들어옴
        //foreach (var element in this.assetNamesList)
        //{
        //    Debug.Log(element);
        //}
        
    }
 
    public void LoadAllAsset()
    {
        this.objectPool = new GameObject();
        objectPool.name = "AllAssets";
 
        foreach (var assetName in this.assetNamesList)
        {
            //데이터를 가져옴
            string path = string.Format("Prefabs/{0}", assetName);
            var prefab = Resources.Load(path);
            var asset = Instantiate(prefab) as GameObject;
 
            //오브젝트풀에 넣음
            this.assetList.Add(asset);
            asset.name = assetName;
            asset.transform.SetParent(this.objectPool.transform);
            asset.SetActive(false);
        }
        this.objectPool.transform.SetParent(this.transform);
    }
    
    public GameObject GetAsset(string name)
    {
        Debug.LogFormat("{0}를 ObjectPool에서 찾습니다.", name);
 
        //람다식 this.assetList의 x는 x.name이고 매개변수 name과 같다면,
        //그값을 asset에 넣어라
        var asset = this.assetList.Find(x => x.name == name);
 
        //asset을 찾았으면 부모에서 떼어내고
        if (asset != null)
        {
            asset.transform.parent = null;
        }
 
        asset.SetActive(true);
        //asset 반환
        return asset;
    }
 
    public void ReleaseAsset(GameObject asset)
    {
        //예외처리 : 만약 매개변수로 받아온 asset이 null이라면 바로 return
        if (asset == null)
        {
            return;
        }
        //받아온 asset 부모에서 떼어냄
        asset.transform.parent = null;
        //포지션값 초기화
        asset.transform.position = Vector3.zero;
        //회전 초기화
        asset.transform.rotation = Quaternion.Euler(Vector3.zero);
 
        //ObjectPool의 자식으로 다시 넣음
        asset.transform.SetParent(GameObject.Find("AllAssets").transform);
        //비활성화
        asset.SetActive(false);
    }
}
 
 
 

 

Character.class

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Character : MonoBehaviour
{
    private void Awake()
    {
        
    }
    // Start is called before the first frame update
    void Start()
    {
 
    }
    public void Init(Vector3 initPos)
    {
        this.transform.position = initPos;
    }
    public virtual void Attack()
    { 
    
    }
 
}
 
 
 

Hero.class

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Hero : Character
{
    private bool isEquiped;
 
    private void Awake()
    {
        
    }
    // Start is called before the first frame update
    void Start()
    {
        
    }
    public void EquipItem(GameObject item)
    {
        var target = GameObject.Find("DummyRHand");
        item.transform.SetParent(target.transform, false);
        item.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
    }
 
    public override void Attack()
    {
        
    }
 
    // Update is called once per frame
    void Update()
    {
        
    }
}
 
 
 

 

 

 

 

참고

'Unity > 과제' 카테고리의 다른 글