C#/과제

2020.05.14. 과제 - ObjectPool 이용해서 무기선택 이펙트 바꾸기

dev_sr 2020. 5. 14. 01:39

 

static ObjectPool (싱글톤)

Asset 인스턴스를 Load 시에 한번만 생성한 뒤 더 이상 생성하지 않고(Instantiate X)

활성/비활성으로 모든 오브젝트를 관리한다.

 

사용한 엑셀데이터

1.weapon_data

 

2. effect_data

 

 

 

1. App

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
using System.Collections;
using System.Collections.Generic;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.UI;
 
public class App : MonoBehaviour
{
    public enum eWeaponType
    {
        machete, hammer, axe
    }
 
    public Button[] btn;
    public Image weaponIconImage;
    public Sprite[] arrSprite;
    public Button attackBtn;
 
    private GameObject weaponAsset;
    private GameObject effectAsset;
 
    void Start()
    {
        ObjectPool.GetInstance().Load();
        Hero hero = ObjectPool.GetInstance().CreateHero();
 
 
        int lastIndex = 0;
 
        for (int i = 0; i < this.btn.Length; i++)
        {
            int capturedIndex = i;
            this.btn[capturedIndex].onClick.AddListener(() =>
            {
                this.weaponIconImage.gameObject.GetComponent<Image>().sprite = this.arrSprite[capturedIndex];
 
                if(capturedIndex!=lastIndex)
                {
                    hero.ReleaseWeapon(this.weaponAsset, this.effectAsset);
                   
                }
 
                this.weaponAsset = ObjectPool.GetInstance().GetWeaponAsset((eWeaponType)capturedIndex);
 
                hero.GetWeapon(this.weaponAsset);
 
                this.effectAsset = ObjectPool.GetInstance().GetEffectAsset(capturedIndex);
 
                lastIndex = capturedIndex;
               
            });
 
        }
 
        this.attackBtn.onClick.AddListener(() =>
        {
            hero.Attack();
        });
    }
}
 

 

 

2. ObjectPool 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ObjectPool : MonoBehaviour
{
    private static ObjectPool instance;
    private List<GameObject> weaponAssetList;
    private List<GameObject> effectAssetList;
    private List<GameObject> characterList;
 
    private void Awake()
    {
        ObjectPool.instance = this;
        this.weaponAssetList = new List<GameObject>();
        this.effectAssetList = new List<GameObject>();
        this.characterList = new List<GameObject>();
    }
 
    public static ObjectPool GetInstance()
    {
        return ObjectPool.instance;
    }
 
    public void Load()
    {
        DataManager.GetInstance().Load();
 
        List<WeaponData> weaponDataList = DataManager.GetInstance().GetWeaponData();
 
        foreach (WeaponData data in weaponDataList)
        {
            string weaponPath = string.Format("Prefabs/{0}", data.weapon_res_name);
            GameObject weapon = Resources.Load(weaponPath) as GameObject;
            weapon.name = data.name;
            GameObject weaponGo = Instantiate(weapon) as GameObject;
            this.weaponAssetList.Add(weaponGo);
 
            EffectData effectData = DataManager.GetInstance().GetEffectDataById(data.effect_id);
            string effectPath = string.Format("Effect/{0}", effectData.effect_res_name);
            GameObject effect = Resources.Load(effectPath) as GameObject;
            effect.name = effectData.name;
            GameObject effectGo = Instantiate(effect) as GameObject;
 
            effectGo.transform.position = this.transform.position;
 
            this.effectAssetList.Add(effectGo);
 
            weaponGo.transform.SetParent(this.transform);
            effectGo.transform.SetParent(this.transform);
 
            weaponGo.SetActive(false);
            effectGo.SetActive(false);
 
        }
 
    }
 
    public Hero CreateHero()
    {
        GameObject heroShell = new GameObject();
        heroShell.name = "Hero";
        Hero hero = heroShell.AddComponent<Hero>();
        GameObject heroLoad = Resources.Load("Prefabs/ch_02_01"as GameObject;
        GameObject heroGo = Instantiate(heroLoad) as GameObject;
 
        heroGo.transform.SetParent(heroShell.transform);
        heroShell.transform.SetParent(this.transform);
 
        hero.Init(heroGo);
 
        this.characterList.Add(heroGo);
 
        return hero;
    }
 
    public GameObject GetWeaponAsset(App.eWeaponType weaponType)
    {
        string name = string.Format("{0}(Clone)", weaponType);
 
        GameObject foundAsset = null;
 
        foreach(var data in this.weaponAssetList)
        {
            if (name == data.name)
            {
                foundAsset = data;
            }
        }
 
        return foundAsset;
    }
 
    public GameObject GetEffectAsset(int index)
    {
        this.effectAssetList[index].SetActive(true);
        return this.effectAssetList[index];
    }
 
    public void ReleaseAsset(GameObject weaponGo,GameObject effectGo)
    {
        weaponGo.transform.SetParent(this.transform);
        weaponGo.transform.position = this.transform.position;
        weaponGo.transform.localRotation= Quaternion.Euler(Vector3.zero);
        weaponGo.SetActive(false);
 
        effectGo.transform.SetParent(this.transform);
        effectGo.SetActive(false);
    }
}

 

 

3.  Hero 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Hero : MonoBehaviour
{
    private Animation anim;
    private string animName;
    private float animAttackLength;
    private bool isAttack;
    private float elapsedTimeCompareAttackEnd;
    private GameObject model;
    private Transform dummyRHand;
 
    void Start()
    {
        Debug.Log("hi");
 
    }
 
    public void Init(GameObject model)
    {
        this.model = model;
 
        this.anim = model.GetComponent<Animation>();
        this.animName = "attack_sword_01";
        this.animAttackLength = this.anim[animName].length;
 
        Debug.Log(this.model);
    }
    public void GetWeapon(GameObject weaponGo)
    {
        this.dummyRHand = this.model.GetComponent<HeroModel>().dummyRHand;
        weaponGo.transform.SetParent(dummyRHand, false);
 
        if(weaponGo.transform.rotation.y!=180)
        {
            weaponGo.transform.Rotate(new Vector3(01800));
        }
        weaponGo.transform.localScale=new Vector3(0.2f, 0.2f, 0.2f);
        weaponGo.SetActive(true);
 
    }
 
    public void ReleaseWeapon(GameObject weaponGo, GameObject effectGo)
    {
        ObjectPool.GetInstance().ReleaseAsset(weaponGo,effectGo);
    }
 
 
    public void Attack()
    {
        this.anim.Play(animName);
        this.isAttack = true;
    }
 
    private void Stop()
    {
        this.anim.Play("idle@loop");
        this.isAttack = false;
    }
 
    void Update()
    {
        if (this.isAttack)
        {
            this.elapsedTimeCompareAttackEnd += Time.deltaTime;
 
            if (this.elapsedTimeCompareAttackEnd >= this.animAttackLength)
            {
                this.Stop();
                this.elapsedTimeCompareAttackEnd = 0;
            }
        }
    }
}

 

 

4. WeaponData

 

1
2
3
4
5
6
7
8
9
10
11
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class WeaponData
{
    public int id;
    public string name;
    public string weapon_res_name;
    public int effect_id;
}

 

5. EffectData

 

1
2
3
4
5
6
7
8
9
10
11
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class EffectData
{
    public int id;
    public string name;
    public string effect_res_name;
 
}

 

 

6. DataManager 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
using Newtonsoft.Json;
using System.Linq;
 
public class DataManager
{
 
    private static DataManager Instance;
    private Dictionary<int, WeaponData> dicWeaponDatas;
    private Dictionary<int, EffectData> dicEffectDatas;
 
    private DataManager()
    {
        this.dicWeaponDatas = new Dictionary<int, WeaponData>();
        this.dicEffectDatas = new Dictionary<int, EffectData>();
    }
 
    public static DataManager GetInstance()
    {
        if (DataManager.Instance == null)
        {
            DataManager.Instance = new DataManager();
            return DataManager.Instance;
        }
        return DataManager.Instance;
    }
 
    public void Load()
    {
        TextAsset weaponText = Resources.Load("Data/weapon_data"as TextAsset;
        string weaponJson = weaponText.text;
 
        TextAsset effectText = Resources.Load("Data/effect_data"as TextAsset;
        string effectJson = effectText.text;
 
        this.dicWeaponDatas = JsonConvert.DeserializeObject<WeaponData[]>(weaponJson).ToDictionary(x => x.id, x => x);
        this.dicEffectDatas = JsonConvert.DeserializeObject<EffectData[]>(effectJson).ToDictionary(x => x.id, x => x);
 
    }
 
    public List<WeaponData> GetWeaponData()
    {
        List<WeaponData> weaponDatasList = new List<WeaponData>();
 
        foreach (var pair in this.dicWeaponDatas)
        {
            weaponDatasList.Add(pair.Value);
        }
 
        return weaponDatasList;
    }
 
    public EffectData GetEffectDataById(int id)
    {
        return this.dicEffectDatas[id];
    }
}