Obje Havuzu (Object Pool)

Gelin geçmişe gidelim ve ekranda 3 mermiden fazla bulunmasına izin vermeyen Space Shooter’ları hatırlayalım. Neden 3 mermi kısıtlaması getirmiş olabilirler? Elbette cevap gün gibi ortada. Donanım sahnede 3 mermiden fazlasının hareketine izin vermiyordu.

Oyun dünyası, donanım dünyasıyla doğru orantılı olarak büyüdü. Ancak bu şu demek değil, “zaten kasmaz, performassız kod yazsak da olur!”. Bu düşülebilecek en büyük yanlış. Kasmayacak diye savurganca kod yazamayız.

Savurganca kod yazmamanın en temel kurallarından birine değineceğim bugün. Object Pooling. Yani obje havuzu… Yaklaşım bize şöyle der;

  • Eğer bir objeyi kullanacaksan, onu havuzdan al. Kullan ve objeyi yıkmak yerine inaktif ettikten sonra havuza yeniden ekle.

Object Pooling yaklaşımını uygulamak bizlere, bir objeyi yaratmak ve yıkmak döngüsündeki ağır yükten kurtarır. Şöyle bir senaryo yazalım;

  • Sahnede bir silah var.
  • Silah belli aralıklarla sürekli ateş ediyor.

Bu senaryoda program bir saat açık tutulsa, kaç tane obje yaratıp yıkmış olursunuz, bir düşünsenize! Ama object pooling yaklaşımını uygularsanız, 20 kadar mermi ile günü kurtarabilirsiniz. Evet günü! 24 saati!

O halde başlayalım. Şimdi sahneye bir Capsule objesi ekleyin ve Gun scriptini bu objeye tutuşturun. Objeniz tam da aşağıdaki gibi görünmeli. Gun scriptini de hemen altına paylaşıyorum.

  • BulletPool : Kullanılacak olan mermilerin alınacağı ve kullanılmış olan mermilerin ekleneceği havuz.
  • _transform : Gun objesinin Transform’unu sakladık.
  • _firedBullets : Ateşlenen bütün mermileri tutar.
  • _bulletXLimit : mermilerin ekranda gidebileceği en uç nokta.
  • MoveBullets() : _firedBullets listesi içindeki mermilerin Move() metodlarını çalıştırır.
  • CheckBulletLifeTimes(): _firedBullets listesi içindeki mermilerin ekranda ulaşabilecekleri en son noktaya ulaşıp ulaşmadıklarını kontrol eder ve onları kullanımdan kaldırır.

Şimdi de boş bir GameObject yaratın ve BulletPool scriptini bu objeye ekleyin. Bu işlemin ardından da Gun objenize tıklayın ve Gun scriptinde boş görünen BulletPool’a, henüz yaratmış olduğunuz BulletPool objesini sürükleyip bırakın. BulletPool scriptini de paylaşıyorum.

  • BulletPrefab : Yaratılacak her yeni Bullet objesi bu Prefab’den türetilir.
  • _bullets : Havuzdaki, kullanıma hazır mermileri tutar.
  • Init() : _bullets listesini başlatır.
  • Init(int bulletCount) : _bullets listesini başlatır ve içine bulletCount kadar mermi ekler. Böylece oyun başlarken hali hazırda içi dolu bir havuzumuz olur. Havuzu böyle başlatmak kullanıcının ortalama ne kadar mermi kullanabileceği bilindiğinde avantajlı bir yaklaşım olacaktır.
  • AddBulletToPool() : Havuza bullet ekler.
  • CreateBullet() : Yeni mermi yaratır ve yaratılan mermiyi döndürür.
  • GetBullet() : Havuzdan mermi alır. Bu işlem yapılırken, havuz listesinden mermi çıkarılır ve return edilir.

Son adımda ise bir GameObject yaratın ve adını Bullet olarak değiştirdikten sonra Bullet Scriptini bu objeye ekleyin. Bullet objesi şöyle görünmeli. Kodu da hemen altına paylaşıyorum.

  • _transform : Bir objenin Transform’una “transform.gameobject…..” diye her frame’de ulaşmak yerine, Transformu bir kere saklayıp (Cachelemek) öyle kullanmak çok daha akıllıca bir yöntemdir.
  • _speed : Merminin hızı.
  • Move() : Merninin, +X koordinatında her frame’de _speed hızı kadar pozisyonunu öteler.
  • GetPosition() : Merminin pozisyonunu alır.
  • SetPosition() Mermiye poziston ataması yapar.

Artık play diyebilir ve neler olduğunu gözlemleyebilirsiniz. Eğer anlamadığınız yer olursa, bana email atmanız yeterli. Şunu şöyle yapsan daha iyi olur diye bir öneriniz varsa, onu dinlemekten de büyük keyif alırım. Saygılar, sevgiler.

Proje Linki

Leave a Reply

Your email address will not be published. Required fields are marked *