Unity'de Performans İpuçları

Unity'de Performans İpuçları

Mobil oyun pazarında FPS (Frames Per Second) yalnızca teknik bir metrik değil, doğrudan oyuncu deneyiminin kalbidir. Ekranda saniyede kaç kare işlediğiniz, oyuncunun oyuna ne kadar akıcı ve doğal bir şekilde tepki verebildiğini belirler. Özellikle hızlı refleks gerektiren oyun türlerinde, düşük FPS sadece görsel bir problem değil; aynı zamanda oynanışın keyfini baltalayan bir engeldir. Bir oyuncunun en çok hatırladığı şey çoğu zaman grafik kalitesi değil, oynarken hissettiği akıcılıktır.

Unity tarafında performans optimizasyonuna başlarken yapılması gereken ilk şey, sahne düzenini ve object pooling yaklaşımını doğru kurgulamaktır. Örneğin her düşman dalgasında Instantiate ile yeni düşman nesneleri üretip, iş bittiğinde Destroy etmek kısa vadede işlevsel görünse de uzun vadede ciddi bir performans kaybına yol açar. Çünkü her Instantiate çağrısı bellek tahsisi yapar, her Destroy ise bu belleğin çöp toplayıcıya (Garbage Collector - GC) bırakılmasına sebep olur. Oyuncular çoğu zaman “oyunda bir anda küçük takılmalar” hisseder, ama bunun adını koymaz. İşte bu küçük takılmaların arkasında çoğu kez GC spike dediğimiz ani çöp toplama süreçleri vardır.

Bunu engellemek için, örneğin mermiler, düşman karakterleri veya parçacık efektleri gibi sık tekrar eden nesneler için Object Pooling kullanmak kritik önem taşır. Yani nesneleri yok etmek yerine devre dışı bırakıp, ihtiyaç olduğunda yeniden aktifleştirmek çok daha sağlıklı bir yöntemdir. Diyelim ki bir mobil FPS oyunu geliştiriyorsunuz ve saniyede onlarca mermi ekrana çıkıyor. Eğer her mermiyi yeniden yaratıp yok ederseniz, birkaç dakika içinde cihazın belleği gereksiz yere yorulmaya başlar. Oysa 50–100 mermilik bir “havuz” oluşturur ve tüm mermileri bu havuzdan çekerseniz, hem FPS stabil kalır hem de bellek kullanımı kontrol altında tutulur.

Unity’nin Profiler aracını aktif kullanmak bu noktada büyük bir fark yaratır. Profiler üzerinden CPU, GPU ve Memory sekmelerini takip ederek, özellikle “GC Alloc” kısımlarına dikkat edin. Buradaki küçük tahsisler bile zamanla büyük sorunlara dönüşebilir. Örneğin UI tarafında yanlış kullanılan String.Format ya da sürekli güncellenen Text elementleri fark etmeden yüzlerce byte’lık GC tahsisi yapabilir. Bunun çözümü çoğu zaman çok basittir: StringBuilder kullanmak veya gereksiz update çağrılarını azaltmak gibi.

Kendi deneyimlerimden örnek verecek olursam, üzerinde çalıştığım bir arcade türü mobil oyunda, oyuncular her 30 saniyede bir “mikro takılma” rapor ediyordu. Profiler’da incelediğimde bunun sebebinin her düşman öldüğünde yeni bir patlama efektinin Instantiate edilmesi olduğunu gördüm. Bunu Object Pooling ile çözdüğümde, sadece FPS istikrarı sağlanmakla kalmadı; oyunun enerji tüketimi de düştü. Çünkü cihaz, sürekli bellek tahsis ve serbest bırakma işlemi yapmadığından daha az zorlanıyordu.

Özetle, mobil oyun geliştirme sürecinde performans optimizasyonu sadece “teknik bir iyileştirme” değil, doğrudan kullanıcı deneyimine yapılan bir yatırımdır. Sahne düzeninizi sade tutmak, Object Pooling uygulamak ve Profiler ile GC takibini düzenli yapmak, oyunlarınızın akıcı, keyifli ve uzun vadede sürdürülebilir bir deneyim sunmasını sağlar.