1.01 ^ 365 = 37.78

[Unity] 유니티 오브젝트 풀 본문

프로그래밍/Unity

[Unity] 유니티 오브젝트 풀

Youngchangoon 2017. 2. 16. 17:37

오브젝트풀(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
using UnityEngine;
using System.Collections.Generic;
using System.Collections;
 
public class ObjectPool<T> where T : Component {
 
  private Stack<T> objectPool;
  private int overAllocateCount;
  private T oriObject;
  private Transform parent;
  private string objName;
 
  public ObjectPool2(T oriObject, string objName, Transform parent, int count, int overAllocateCount) {
    this.overAllocateCount = overAllocateCount;
    this.oriObject = oriObject;
    this.parent = parent;
    this.objName = objName;
    this.objectPool = new Stack<T>(count);
    Allocate(count);
  }
 
  public void Allocate(int alloCount) {
    for(int i = 0; i < alloCount; ++i) {
      T obj = GameObject.Instantiate<T>(oriObject);
      obj.transform.SetParent(parent);
      obj.name = objName + i.ToString();
      obj.gameObject.SetActive(false);
      objectPool.Push(obj);
    }
  }
 
 
  public T Pop(bool setActive = true) {
    if (objectPool.Count <= 0) {
      Debug.Log("ObjPool : Over Count Object Pop");
      Allocate(overAllocateCount);
    }
    T retObj = objectPool.Pop();
    retObj.gameObject.SetActive(setActive);
    return retObj;
  }
 
  public void Push(T obj) {
    obj.gameObject.SetActive(false);
    objectPool.Push(obj);
  }
}
cs


코드를 설명하자면

1. <T> 의 선언

먼저 <T>는 C#의 generic 문법을 사용했습니다. <T>에는 어떠한 타입도 들어올 수 있다는 뜻입니다.

그런데 오른쪽에 where T : Component 가 있죠? 

이 뜻은 T가 올 수 있는 범위를 제한 한다는 뜻입니다, 저는 Component로 한정자를 지었습니다. 

왜냐하면 Component는 MonoBehaviour과 Transform의 부모 클래스로, 간단한 Object들도 Transform으로 Pooling할 수 있게 하고 싶었기 때문입니다.

<T>에  대한 제한은 자신이 필요에 따라서 바꿔도 상관 없습니다. ㅋㅋ


2. Stack

Stack이라는 자료구조를 사용했는데요, Stack을 사용함으로써, 객체들을 쉽게 관리 할 수 있게 했습니다.

3. 생성자 Parameter


- oriObject    : 복사될 Prefab

- objName    : 하이어라키에서 볼 오브젝트 이름

- parent        : 오브젝트들이 생성될 부모 오브젝트

- count         : 처음에 생성할 Prefab 갯수

- overAllocateCount : 오브젝트의 갯수보다 초과할시, 오브젝트를 추가할 갯수

4. 기타 함수들

- Allocate() : 객체들을 생성하는  함수입니다.
저는 객체 Pool을 생성하고 바로 사용하지 않으므로 gameObject를 꺼두었습니다.

- Pop() : 객체를 Get하는 함수입니다.
객체를 Pop할때 gameObject를 킬것인가를 인자로 받아서 사용했습니다.

- Push(): 객체를 다시 Pool로 넣는 함수
객체를 Push할때, 무조건 gameObject를 꺼버렸습니다..

5. 개선점 및 주의사항

위의 클래스를 사용하면서 주의해야할 점이 있었다면 Pool을 사용할때, Pop하는 순간 그 객체를 담아둘 자료구조가 무조건 필요하다는 점입니다.
만약 그 객체를 담아두지 않는다면 다시 Push할 수가 없으므로 그 객체는 미아가 되버리고 맙니다.



위의 클래스는 자유롭게 사용하셔도 무방합니다 ㅋㅋ 즐거운 개발 하세요~