본문 바로가기

Unity

Unity - 오브젝트풀(ObjectPool Pattern) 구현하기 (일반)

오브젝트풀(ObjectPool)이란?

위키

위에서 설명하는 것 처럼 생성 디자인 패턴

 

생성된 오브젝트의 집합을 사용하는 것임

 

필요할 때 마다 생성하고 파괴하기보다는 미리 생성해놓고 사용하는 것

 

또한 계속 생성(Instatiate)하고 파괴(Destroy)하면 오버헤드가 생기는데 오브젝트풀을 사용해서 방지할 수 있음

 

생성과 파괴를 자주하는 것일 수록 오브젝트풀은 효과적

ex) 총알, 파티클, 적들...

 

 

 

 

 

 

구현방법

1) 어디서든 접근가능 해야하므로 싱글톤으로 작성

2) 어떠한 오브젝트를 미리 생성 후 활성화를 꺼줌

3) 그 오브젝트를 List같은 집합군에 넣어줌

4) 그 오브젝트를 다른 스크립트에서 필요하면 사용하게끔 Get 함수를 만들어줌

5) 필요한 곳에서 사용

 

 

 

 

구현

1) 어디서든 접근가능 해야하므로 싱글톤으로 작성

 

2) 어떠한 오브젝트를 미리 생성 후 활성화를 꺼줌

3) 그 오브젝트를 List같은 집합군에 넣어줌

 

4) 그 오브젝트를 다른 스크립트에서 필요하면 사용하게끔 Get 함수를 만들어줌

 

5) 필요한 곳에서 사용 (다른스크립트)

 

 

코드전체보기

ObjectPooler의 스크립트 코드임

+ Spawn()을 사용하는 코드는 임의로 필요한 곳에서 사용하면 됨

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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ObjectPooler : MonoBehaviour
{
    public bool more = true;
    public static ObjectPooler instance;
 
    private void Awake()
    {
        if (instance == null)
        {
            instance = this;
        }
        else if(instance != this)
        {
            Destroy(this.gameObject);
        }
    }
 
 
    private void Start()
    {
        CreateBullet();
    }
 
    public GameObject bullet;
    private List<GameObject> bulletPool;
    public int bulletCreateCount;
    private void CreateBullet()
    {
        bulletPool = new List<GameObject>();
        for (int i = 0; i < bulletCreateCount; i++)
        {
            GameObject obj = Instantiate(bullet);
            obj.SetActive(false);
            bulletPool.Add(obj);
        }
    }
 
 
    public GameObject GetBullet()
    {
        foreach (GameObject obj in bulletPool)
        {
            if (!obj.activeInHierarchy) { return obj; }
        }
 
        //오브젝트가 모두 활성화일 때
        if (more)
        {
            GameObject obj = Instantiate(bullet);
            obj.SetActive(false);
            bulletPool.Add(obj);
            return obj;
        }
        else
        {
            return null;
        }
    }
}
cs

 

 

 

=== 참고 ===

오브젝트 풀링하면 SetActive(true/false)를 매우많이 사용할 것

그에 따른 예외 생각을 많이 해야 함

 

SetActive(false)였다가 SetActive(true)가 되면 오브젝트의 Start() 함수는 실행이 되지 않음

OnEnable()가 실행될 것

그에 따른 초기화도 잘해줘야함

ex) 페이드아웃된 오브젝트를 Start에서만 초기화하면 안됨 !!!