2020년 2월 13일 목요일

Object Pool 기법(Unity Gameobject) #오브젝트 풀



instantiate 와 destroy를 많이 하면 성능에 영향을 준다



objPool에다가 Gameobject를 담고
필요한 오브젝트의 gameobject setactive를 true와 false로 변경하면서 사용


ObjectPoolManager


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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectPoolManager : MonoBehaviour {
    public static ObjectPoolManager current;
    private int offset = 1;
    public static Dictionary<stringList<GameObject>> PoolObjs;
    private void Awake()
    {
        current = this;
        PoolObjs = new Dictionary<stringList<GameObject>>();
    }
    public static GameObject CreateObj(GameObject _Prefab)
    {
        GameObject goQ = ObjectPoolManager.GetPooledObject(_Prefab);
        goQ.transform.parent = null;
        goQ.SetActive(true);
        return goQ;
    }
    public static GameObject CreateObj(GameObject _Prefab, Transform _Parent)
    {
        GameObject goQ = ObjectPoolManager.GetPooledObject(_Prefab, _Parent);
        goQ.SetActive(true);
        return goQ;
    }
    public static GameObject CreateObj(GameObject _Prefab, Vector3 pos, Quaternion rot)
    {
        GameObject goQ = ObjectPoolManager.GetPooledObject(_Prefab, pos, rot);
        goQ.transform.parent = null;
        goQ.SetActive(true);
        return goQ;
    }
    static void InitCreateObj(GameObject goType)
    {
        //이름이 중복되는 프리팹이 있다면 에러임 근데 그렇게 프리팹을 만든사람이 에러임 ㅇㅋ?
        PoolObjs.Add(goType.name, new List<GameObject>());
        for (int i = 0; i < 1; i++)
        {
            GameObject go = (GameObject)Instantiate(goType);
            go.name = goType.name;
            go.transform.parent = current.transform;
            go.GetComponent<PoolObj>().Original_Parent = current.transform;
            go.SetActive(false);
            PoolObjs[goType.name].Add(go);
        }
    }
    public static GameObject GetPooledObject(GameObject prefab)
    {
        if (!PoolObjs.ContainsKey(prefab.name))
        {
            InitCreateObj(prefab);
        }
        List<GameObject> PoolType = PoolObjs[prefab.name];
        for (int i = 0; i < PoolType.Count; i++)
        {
            if (!PoolType[i].activeInHierarchy)
            {
                return PoolType[i];
            }
        }
        AutoSizeUp(PoolType);
        return PoolType[PoolType.Count-1];
    }
    public static GameObject GetPooledObject(GameObject prefab,Transform parent)
    {
        if (!PoolObjs.ContainsKey(prefab.name))
        {
            InitCreateObj(prefab);
        }
        List<GameObject> PoolType = PoolObjs[prefab.name];
        for (int i = 0; i < PoolType.Count; i++)
        {
            if (!PoolType[i].activeInHierarchy)
            {
                PoolType[i].transform.parent = parent;
                return PoolType[i];
            }
        }
        AutoSizeUp(PoolType,parent);
        return PoolType[PoolType.Count - 1];
    }
    public static GameObject GetPooledObject(GameObject prefab,Vector3 pos,Quaternion rot)
    {
        if (!PoolObjs.ContainsKey(prefab.name))
        {
            InitCreateObj(prefab);
        }
        List<GameObject> PoolType = PoolObjs[prefab.name];
        for (int i = 0; i < PoolType.Count; i++)
        {
            if (!PoolType[i].activeInHierarchy)
            {
                PoolType[i].transform.position = pos;
                PoolType[i].transform.rotation = rot;
                PoolType[i].SetActive(true);
                return PoolType[i];
            }
        }
        AutoSizeUp(PoolType,pos,rot);
        PoolType[PoolType.Count - 1].SetActive(true);
        return PoolType[PoolType.Count - 1];
    }
    static void AutoSizeUp(List<GameObject> PoolType)
    {
        GameObject go = (GameObject)Instantiate(PoolType[0]);
        go.transform.parent = PoolType[0].GetComponent<PoolObj>().Original_Parent;
        go.name = PoolType[0].name;
        go.GetComponent<PoolObj>().Original_Parent = PoolType[0].GetComponent<PoolObj>().Original_Parent;
        PoolType.Add(go);
    }
    static void AutoSizeUp(List<GameObject> PoolType,Transform parent)
    {
        GameObject go = (GameObject)Instantiate(PoolType[0]);
        go.transform.parent = PoolType[0].GetComponent<PoolObj>().Original_Parent;
        go.name = PoolType[0].name;
        go.GetComponent<PoolObj>().Original_Parent = PoolType[0].GetComponent<PoolObj>().Original_Parent;
        go.transform.parent = parent;
        PoolType.Add(go);
    }
    static void  AutoSizeUp(List<GameObject> PoolType,Vector3 pos, Quaternion rot)
    {
        GameObject go = (GameObject)Instantiate(PoolType[0]);
        go.transform.parent = PoolType[0].GetComponent<PoolObj>().Original_Parent;
        go.name = PoolType[0].name;
        go.GetComponent<PoolObj>().Original_Parent = PoolType[0].GetComponent<PoolObj>().Original_Parent;
        go.transform.position = pos;
        go.transform.rotation = rot;
        PoolType.Add(go);
    }
}
cs

PoolObj


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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PoolObj : MonoBehaviour {
    public Transform Original_Parent;
    // Use this for initialization
    void Start () {
        
        
    }
    
    // Update is called once per frame
    void Update () {
        
    }
    public void UnActive()
    {
        this.transform.parent = Original_Parent;
        this.gameObject.SetActive(false);
    }
    public void UnActive_UI()
    {
        this.gameObject.SetActive(false);
    }
}
cs


사용 예제

PoolObj를 사용할 GameObj에 붙이고 해당 스크립트로

생성
GameObject go_PopUpBox = ObjectPoolManager.CreateObj(obj);

삭제
go_PopUpBox.GetComponent<PoolObj>().UnActive_UI();




댓글 없음:

댓글 쓰기

git rejected error(feat. cherry-pick)

 문제 아무 생각 없이 pull을 받지않고 로컬에서 작업! 커밋, 푸시 진행을 해버렷다. push에선 remote와 다르니 당연히 pull을 진행해라고 하지만 로컬에서 작업한 내용을 백업하지 않고 진행하기에는 부담스럽다(로컬작업 유실 가능성) 해결하려...