클래스 네이밍을 할 때,

~Manager

~Handler

~Controller


이렇게 많이 하는데

얼핏 보면 다 비슷비슷한 뜻 같지만 

조금씩 의미적 차이가 있다고 합니다!


Manager는 관리

Handler는 처리

Controller는 제어


도움이 되었길바랍니다~



ObjectPoolSample.unitypackage


모바일 프로젝트의 필수요소인 오브젝트 풀,

구글링하여 찾은 C# 소스를 기반으로 유니티에서 재사용 가능하도록 제작해보았습니다.

이를 활용한, 총에서 불렛을 발사하는 예제도 함께 첨부했습니다.


( ObjectPool<T>.cs, PoolableObject.cs, ObjectPoolManager.cs, Gun.cs, Bullet.cs )



풀링할 객체는 모두 PoolableObject 클래스를 상속받아서 사용하시면 됩니다.


ObjectPool<T>.cs의

 - objStack : 비활성화 된 object들을 담고있는 Stack (풀)

 - objList : 활성화 된 object들을 담고있는 List (참조용)


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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
// ObjectPool<T>.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
public class ObjectPool<T> where T : PoolableObject
{
    private int allocateCount;
 
    public delegate T Initializer ();
    private Initializer initializer;
 
    private Stack<T> objStack;
    public List<T> objList;
 
    public ObjectPool ()
    {
        // default constructor
    }
 
 
    public ObjectPool (int ac, Initializer fn)
    {
        this.allocateCount = ac;
        this.initializer = fn;
        this.objStack = new Stack<T>();
        this.objList = new List<T>();
    }
 
    public void Allocate ()
    {
        for (int index = 0; index < this.allocateCount; ++index)
        {
            this.objStack.Push(this.initializer());
        }
    }
 
    public T PopObject ()
    {
        if (this.objStack.Count <= 0)
        {
            Allocate();
        }
 
        T obj = this.objStack.Pop();
        this.objList.Add(obj);
 
        obj.gameObject.SetActive(true);
 
        return obj;
    }
 
    public void PushObject (T obj)
    {
        obj.gameObject.SetActive(false);
 
        this.objList.Remove(obj);
        this.objStack.Push(obj);
    }
 
    public void Dispose ()
    {
        if (this.objStack == null || this.objList == null)
            return;
 
        this.objList.ForEach(obj => this.objStack.Push(obj));
 
        while (this.objStack.Count > 0)
        {
            GameObject.Destroy(this.objStack.Pop());
        }
 
        this.objList.Clear();
        this.objStack.Clear();
    }
    
 
 
// PoolableObject.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
public class PoolableObject : MonoBehaviour 
{
    protected ObjectPool<PoolableObject> pPool;
 
    public virtual void Create (ObjectPool<PoolableObject> pool)
    {
        pPool = pool;
 
        gameObject.SetActive(false);
    }
    
    public virtual void Dispose ()
    {
        pPool.PushObject(this);
    }
 
    public virtual void _OnEnableContents ()
    {
        // to do ...
    }
    
    public virtual void _OnDisableContents ()
    {
        // to do ...
    }
 
 
 
// ObjectPoolManager.cs
using UnityEngine;
using System.Collections;
 
public class ObjectPoolManager : MonoBehaviour 
{
    private static ObjectPoolManager singleton;
    public static ObjectPoolManager GetInstance () { return singleton; }
 
    public ObjectPool<PoolableObject> bulletPool = new ObjectPool<PoolableObject>();
    
    public Bullet bulletPrefab;
 
    void Awake ()
    {
        if (singleton != null && singleton != this)
        {
            Destroy(gameObject);
        }
        else 
        {
            singleton = this;
        }
    }
 
    void Start ()
    {
        bulletPool = new ObjectPool<PoolableObject>(5, () => 
        {
            Bullet bullet = Instantiate(bulletPrefab);
            bullet.Create(bulletPool);
            return bullet;
        });
        
        bulletPool.Allocate();
    }
 
    void OnDestroy ()
    {
        bulletPool.Dispose();
        singleton = null;
    }
 
 
 
// Gun.cs
using UnityEngine;
using System.Collections;
 
public class Gun : MonoBehaviour 
{
    [HideInInspector] public Transform tm;
    private Vector3 bulletSpawnPoint;
 
    void Awake ()
    {
        tm = gameObject.GetComponent<Transform>();
        bulletSpawnPoint = transform.FindChild("bulletSpawnPoint").transform.position;
    }
 
    void Update ()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Bullet bullet = ObjectPoolManager.GetInstance().bulletPool.PopObject() as Bullet;
            bullet.Fire(bulletSpawnPoint);
        }
    }
 
 
 
// Bullet.cs
using UnityEngine;
using System.Collections;
 
public class Bullet : PoolableObject
{
    [HideInInspector] public Transform tm;
    [HideInInspector] public Rigidbody2D rb2D;
 
    private float force;
 
    public override void Create (ObjectPool<PoolableObject> pool)
    {
        base.Create (pool);
    }
 
    public override void Dispose ()
    {
        base.Dispose ();
    }
 
    public override void _OnEnableContents ()
    {
        base._OnEnableContents ();
 
        rb2D.Sleep();
    }
 
    public override void _OnDisableContents ()
    {
        base._OnDisableContents ();
    }
 
    void Awake ()
    {
        tm = gameObject.GetComponent<Transform>();
        rb2D = gameObject.GetComponent<Rigidbody2D>();
 
        force = 800.0f;
    }
 
    void OnEnable ()
    {
        _OnEnableContents();
    }
 
    void OnDisable ()
    {
        _OnDisableContents();
    }
 
    void Update ()
    {
        if (tm.position.x > 10.0f)
        {
            Dispose();
        }
    }
 
    public void Fire (Vector3 spawnPoint)
    {
        tm.position = spawnPoint;
 
        rb2D.AddForce(Vector3.right * force);
    }
 
cs



1
2
3
4
5
6
7
8
9
    using UnityEngine;
 
    // return : -180 ~ 180 degree (for unity)
    public static float GetAngle (Vector3 vStart, Vector3 vEnd)
    {
        Vector3 v = vEnd - vStart;
 
        return Mathf.Atan2(v.y, v.x) * Mathf.Rad2Deg;
    }
cs



정렬되지 않은 전체 자료 중에서 해당 위치에 맞는 자료를 선택하여 위치를 교환하는 정렬 방식

같은 값의 인덱스끼리도 교환 연산이 발생하기때문에 안전성을 만족하지 않고 전체적인 알고리즘 효율성을 볼 때 느림

 

 - 시간복잡도 (Big-O notation)  


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
using System.Collections.Generic;
 
    public enum SortType
    {
        Asc,
        Desc
    }
 
    public static void SelectionSort(int[] array, SortType st)
    {
        int length = array.Length;
 
        int key;
        int tmp;
 
        if (st == SortType.Asc)
        {
            // Asc
            for (int i = 0; i < length - 1++i)
            {
                key = i;
 
                for (int j = i + 1; j < length; ++j)
                {
                    if (array[key] > array[j])
                    {
                        tmp = array[j];
                        array[j] = array[key];
                        array[key] = tmp;
                    }
                }
            }
        }
        else
        {
            // Desc
            for (int i = 0; i < length - 1++i)
            {
                key = i;
 
                for (int j = i + 1; j < length; ++j)
                {
                    if (array[key] < array[j])
                    {
                        tmp = array[j];
                        array[j] = array[key];
                        array[key] = tmp;
                    }
                }
            }
        }
    }
cs


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
    public static void ShuffleArray<T>(T[] array)
    {
        int random1;
        int random2;
 
        T tmp;
 
        for (int index = 0; index < array.Length; ++index)
        {
            random1 = UnityEngine.Random.Range(0, array.Length);
            random2 = UnityEngine.Random.Range(0, array.Length);
 
            tmp = array[random1];
            array[random1] = array[random2];
            array[random2] = tmp;
        }
    }
 
 
    public static void ShuffleList<T>(List<T> list)
    {
        int random1;
        int random2;
 
        T tmp;
 
        for (int index = 0; index < list.Count; ++index)
        {
            random1 = UnityEngine.Random.Range(0, list.Count);
            random2 = UnityEngine.Random.Range(0, list.Count);
 
            tmp = list[random1];
            list[random1] = list[random2];
            list[random2] = tmp;
        }
    }
cs



'02.Development > C#' 카테고리의 다른 글

[C#] Convert C# to Java, Java to C# - UTC  (0) 2016.07.07
[C#] 숫자 문자열에 컴마(,) 찍기  (0) 2016.02.12


대학교 4학년 수업시간에

'Switch N Light'라는 입사시험문제를 풀면서 만들었던 BackTracking 알고리즘 관련 ppt자료입니다.















'02.Development > Algorithm' 카테고리의 다른 글

[알고리즘] 선택정렬 (C#)  (0) 2016.02.04

+ Recent posts