티스토리 뷰


http://hyunity3d.tistory.com/195

이곳에서 소스코드를 얻어 수정을 하였습니다.


ObjectPool.cs


오브젝트풀(ObjectPool)을 사용하는 이유는 C#에서는

사용하지않는 메모리를 Garbage Collector가 자동으로 처리해주는데

문제는 이 녀석이 호출될때마다 렉이 발생할수있습니다.

그렇기 때문에 생성한 객체를 삭제하지않고 비활성화만 해두었다가

나중에 활성화를 시켜서 재활용하는것이 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
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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ObjectPool : IEnumerable, System.IDisposable
{
    //-----------------------------------------------------------------------------------------
    // 메모리 풀 클래스
    // 용도 : 특정 게임오브젝트를 실시간으로 생성과 삭제하지 않고,
    //      : 미리 생성해 둔 게임오브젝트를 재활용하는 클래스입니다.
    //-----------------------------------------------------------------------------------------
    //MonoBehaviour 상속 안받음. IEnumerable 상속시 foreach 사용 가능
    //System.IDisposable 관리되지 않는 메모리(리소스)를 해제 함
 
    //-------------------------------------------------------------------------------------
    // 아이템 클래스
    //-------------------------------------------------------------------------------------
    class Item
    {
        public bool active; //사용중인지 여부
        public GameObject gameObject;
    }
    List<Item> table;
    GameObject originalPrefab;
 
    //------------------------------------------------------------------------------------
    // 열거자 기본 재정의
    //------------------------------------------------------------------------------------
    public IEnumerator GetEnumerator()
    {
        if (table == null)
            yield break;
 
        int count = table.Count;
 
        for (int i = 0; i < count; i++)
        {
            Item item = table[i];
            if (item.active)
                yield return item.gameObject;
        }
    }
    //-------------------------------------------------------------------------------------
    // 메모리 풀 생성
    // original : 미리 생성해 둘 원본소스
    // count : 최초갯수
    //-------------------------------------------------------------------------------------
    public void Create(GameObject original, int count)
    {
        Dispose();
 
        table = new List<Item>();
        originalPrefab = original;
 
        for (int i = 0; i < count; i++)
        {
            Item item = new Item();
            item.active = false;
            item.gameObject = GameObject.Instantiate(original);
            item.gameObject.SetActive(false);
            table.Add(item);
        }
    }
    //-------------------------------------------------------------------------------------
    // 새 아이템 요청 - 쉬고 있는 객체를 반납한다.
    //-------------------------------------------------------------------------------------
    public GameObject NewItem()
    {
        if (table == null)
            return null;
 
        int count = table.Count;
 
        for (int i = 0; i < count; i++)
        {
            Item item = table[i];
            if (item.active == false)
            {
                item.active = true;
                item.gameObject.SetActive(true);
                return item.gameObject;
            }
        }
 
        Item n_item = new Item();
        n_item.active = false;
        n_item.gameObject = GameObject.Instantiate(originalPrefab);
        n_item.gameObject.SetActive(n_item.active);
        table.Add(n_item);
 
        return n_item.gameObject;
    }
 
    //--------------------------------------------------------------------------------------
    // 아이템 사용종료 - 사용하던 객체를 쉬게한다.
    // gameOBject : NewItem으로 얻었던 객체
    //--------------------------------------------------------------------------------------
    public void RemoveItem(GameObject gameObject)
    {
        if (table == null || gameObject == null)
            return;
        int count = table.Count;
 
        for (int i = 0; i < count; i++)
        {
            Item item = table[i];
            if (item.gameObject == gameObject)
            {
                item.active = false;
                item.gameObject.SetActive(false);
                break;
            }
        }
    }
    //--------------------------------------------------------------------------------------
    // 모든 아이템 사용종료 - 모든 객체를 쉬게한다.
    //--------------------------------------------------------------------------------------
    public void ClearItem()
    {
        if (table == null)
            return;
        int count = table.Count;
 
        for (int i = 0; i < count; i++)
        {
            Item item = table[i];
            if (item != null && item.active)
            {
                item.active = false;
                item.gameObject.SetActive(false);
            }
        }
    }
    //--------------------------------------------------------------------------------------
    // 메모리 풀 삭제
    //--------------------------------------------------------------------------------------
    public void Dispose()
    {
        if (table == null)
            return;
        int count = table.Count;
 
        for (int i = 0; i < count; i++)
        {
            Item item = table[i];
            GameObject.Destroy(item.gameObject);
        }
        table = null;
    }
}
 
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
    private void Update()
    {
        for (int i = 0; i < bulletList.Count; i++)
        {
            if (!bulletList[i].activeInHierarchy)
            {
                playerBulletPool.RemoveItem(bulletList[i]);
            }
        }
    }
 
    public void PlayerBulletFire(int level, Vector3 position)
    {
        if (level >= 1)
        {
            SpriteRenderer[] childComponent;
            GameObject p_bullet = playerBulletPool.NewItem();
 
            bulletList.Add(p_bullet);
            childComponent = p_bullet.GetComponentsInChildren<SpriteRenderer>();
 
            foreach (SpriteRenderer child in childComponent)
            {
                child.enabled = false;
                if (child.name == "Player_Bullet") { child.enabled = true; }
            }
 
            p_bullet.transform.position = new Vector3(position.x, position.y + 0.5f);
            p_bullet.SetActive(true);
        }
    }
cs


제작중인 탄막슈팅게임 소스 일부입니다.


※코딩지적및비판은 저에게 많은 도움이됩니다.

※코딩질문 또한 많은 도움이 됩니다.


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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
글 보관함