Unity Async Sahne Yükleme ve Akıcı Geçiş Ekranları

Unity'de sahneler arası geçişlerde donmaları önlemek için Async Sahne Yükleme yöntemini ve akıcı, profesyonel yükleme ekranları oluşturmayı öğrenin. Performansı artırın.

Oyun geliştirme süreçlerinde, özellikle Unity gibi güçlü bir motorla çalışırken, oyununuzun akıcılığı kullanıcı deneyimi için kritik öneme sahiptir. Büyük ve karmaşık sahneler arasında geçiş yaparken yaşanan donmalar veya uzun yükleme süreleri, oyuncuları sıkabilir ve oyun deneyimini olumsuz etkileyebilir. İşte tam da bu noktada, Unity’nin Async Sahne Yükleme özelliği ve beraberinde gelen geçiş ekranları devreye giriyor. Bu makalede, Unity’de sahneleri asenkron olarak nasıl yükleyeceğinizi, akıcı yükleme ekranları oluşturmayı ve sıkça yapılan hatalardan kaçınmayı detaylı bir şekilde inceleyeceğiz.

Unity’de Senkron ve Asenkron Sahne Yükleme Farkı

Unity’de bir sahneyi yüklemenin iki temel yolu vardır: senkron (eşzamanlı) ve asenkron (eşzamansız).

Senkron Sahne Yükleme: Sorunlar ve Kısıtlamalar

Geleneksel olarak, sahneleri yüklemek için SceneManager.LoadScene(string sceneName) metodunu kullanırız. Bu metod, sahneyi tamamen belleğe yükleyene kadar oyunun ana iş parçacığını (main thread) bloke eder. Yani, sahne yüklenene kadar oyun donar, ekran tepki vermez ve kullanıcı arayüzü kilitlenir. Küçük sahneler için bu kabul edilebilir olsa da, büyük modeller, dokular, sesler ve diğer varlıklarla dolu karmaşık sahnelerde bu durum saniyeler süren donmalara yol açabilir. Bu da oyuncu için oldukça rahatsız edici bir deneyim demektir.

Async Sahne Yükleme: Akıcı Geçişlerin Anahtarı

Async Sahne Yükleme, yani SceneManager.LoadSceneAsync(string sceneName) metodu, bu sorunu çözmek için tasarlanmıştır. Bu metod, sahneyi arka planda, ana iş parçacığını bloke etmeden yüklemeye başlar. Bu sayede, sahne yüklenirken oyununuzun diğer kısımları (UI animasyonları, yükleme ekranı grafikleri vb.) çalışmaya devam edebilir. LoadSceneAsync metodu bir AsyncOperation nesnesi döndürür. Bu nesne aracılığıyla yükleme sürecini takip edebilir, ilerlemeyi bir yükleme çubuğunda gösterebilir ve sahnenin ne zaman aktive edileceğine karar verebiliriz.

Async Sahne Yükleme Nasıl Yapılır?

Async Sahne Yükleme işlemini genellikle bir Coroutine içinde yaparız. Bu sayede, yükleme sürecini adım adım yönetebilir ve her karede ilerlemeyi güncelleyebiliriz.

Temel Yapı ve Kod Örneği

Öncelikle, sahne yükleme işlemini yönetecek bir ‘LoadingScreenController’ script’ine ihtiyacımız var. Bu script’i genellikle ayrı ve hafif bir ‘Loading’ sahnesine yerleştiririz.


using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using System.Collections;

public class LoadingScreenController : MonoBehaviour
{
    [SerializeField] private GameObject loadingPanel; // Yükleme panelini gizlemek/göstermek için
    [SerializeField] private Slider progressBar;       // Yükleme çubuğu
    [SerializeField] private Text progressText;        // Yükleme yüzdesi metni

    // Sahne yükleme işlemini başlatan public metod
    public void LoadLevel(string sceneName)
    {
        loadingPanel.SetActive(true); // Yükleme panelini görünür yap
        StartCoroutine(LoadAsynchronously(sceneName));
    }

    // Asenkron yükleme işlemini yöneten Coroutine
    IEnumerator LoadAsynchronously(string sceneName)
    {
        // Sahneyi asenkron olarak yüklemeye başla
        AsyncOperation operation = SceneManager.LoadSceneAsync(sceneName);

        // Sahne yüklendiğinde otomatik olarak aktive olmasını engelle
        // Bu, yükleme ekranının tamamen görünür kalmasını ve
        // bizim karar verdiğimiz zaman geçiş yapılmasını sağlar.
        operation.allowSceneActivation = false;

        // Yükleme işlemi tamamlanana kadar döngüyü sürdür
        while (!operation.isDone)
        {
            // Yükleme ilerlemesini al. operation.progress 0.9'a kadar yüklemeyi gösterir.
            // 0.9'dan sonrası sahnenin hazır olduğunu ancak henüz aktive edilmediğini ifade eder.
            float progress = Mathf.Clamp01(operation.progress / 0.9f);

            // UI elemanlarını güncelle
            if (progressBar != null) progressBar.value = progress;
            if (progressText != null) progressText.text = (progress * 100f).ToString("F0") + "%";

            // Eğer yükleme %90'a ulaştıysa (yani sahne yüklendi ama henüz aktif değil)
            if (operation.progress >= 0.9f)
            {
                // İsterseniz burada ek bir bekleme süresi, bir animasyonun bitmesini bekleme
                // veya 'Devam etmek için tıklayın' gibi bir kullanıcı inputu ekleyebilirsiniz.
                // Bu örnekte, belirli bir minimum süre geçtikten sonra veya direkt aktive edelim:
                // Örneğin: yield return new WaitForSeconds(2f); // Minimum 2 saniye bekle

                // Sahnenin aktive olmasına izin ver
                operation.allowSceneActivation = true;
            }

            yield return null; // Bir sonraki frame'e kadar bekle
        }

        // Yükleme tamamlandığında yükleme panelini gizle (yeni sahnede)
        // Not: Eğer loadingPanel bu script ile birlikte yeni sahneye geçiyorsa bu çalışır.
        // Genellikle loadingPanel ayrı bir sahnede olup yeni sahne yüklendiğinde yok edilir.
        // Bu durumda bu satır gereksiz olabilir.
        loadingPanel.SetActive(false);
    }
}

Pratik İpuçları ve En İyi Uygulamalar

1. Minimum Yükleme Süresi Ekleme

Bazen küçük sahneler o kadar hızlı yüklenir ki, yükleme ekranı sadece bir an görünüp kaybolur. Bu durum, oyuncuya uygulamanın ‘flash’ yaptığı veya bir hata oluştuğu hissini verebilir. Bu durumu önlemek için, yükleme ekranının belirli bir minimum süre boyunca görünür kalmasını sağlayabilirsiniz. Bunu, operation.allowSceneActivation = true; satırından önce bir yield return new WaitForSeconds(minSure); ekleyerek yapabilirsiniz.

2. Görsel Geribildirim ve Animasyonlar

Yükleme ekranınızın sadece bir ilerleme çubuğundan ibaret olması sıkıcı olabilir. Yükleme simgeleri, dönen logolar veya basit arka plan animasyonları ekleyerek oyuncunun dikkatini dağıtabilir ve yükleme süresini daha az sıkıcı hale getirebilirsiniz. Unutmayın, bu animasyonların çok hafif olması gerekir ki yükleme performansını etkilemesin.

3. Yükleme Ekranı İçin Ayrı Bir Sahne Kullanın

En iyi uygulama, yükleme ekranınız için çok hafif ve minimalist bir sahne oluşturmaktır. Bu sahne sadece Canvas üzerinde bir yükleme çubuğu, metin ve belki bir arka plan görseli içermelidir. Ana menüden veya herhangi bir sahneden bir sonraki büyük sahneye geçiş yapmadan önce bu ‘Loading’ sahnesini senkron olarak yükleyin (küçük olduğu için hızlı olacaktır). Ardından, ‘Loading’ sahnesinden asenkron olarak hedef sahneyi yükleme işlemini başlatın. Bu, yükleme ekranınızın performansını garanti eder ve bellek yönetimini kolaylaştırır.

4. Yükleme Ekranı Nesnesini Kalıcı Yapmak İçin DontDestroyOnLoad

Eğer yükleme ekranı script’iniz ve UI objeleriniz, yükleme işlemi devam ederken yeni sahne yüklendiğinde yok oluyorsa, DontDestroyOnLoad(gameObject); kullanarak yükleme ekranı objenizin bir sonraki sahneye taşınmasını sağlayabilirsiniz. Ancak yukarıdaki ‘ayrı sahne’ yaklaşımı daha yaygın ve yönetimi kolaydır.

Yaygın Hatalar ve Çözümleri

1. allowSceneActivation = false Unutmak

Hata: operation.allowSceneActivation = false; ayarını yapmayı unutmak, sahne yüklenir yüklenmez otomatik olarak aktive olmasına neden olur. Bu durumda yükleme ekranınız ya hiç görünmez ya da çok kısa bir an flash yapar.

Çözüm: Her zaman LoadSceneAsync çağrısından hemen sonra operation.allowSceneActivation = false; satırını ekleyin. Bu, sahnenin yüklenmesini tamamlamasına izin verir ancak aktivasyonunu sizin kontrolünüze bırakır.

2. operation.progress Değerinin 0.9’da Durması

Hata: Yükleme çubuğunuzun %90’a ulaşıp orada takılı kalması. Birçok geliştirici bu durumu bir hata olarak yorumlar.

Çözüm: Bu bir hata değildir. Unity’nin operation.progress değeri, sahnenin yükleme aşamasını 0.0 ile 0.9 arasında gösterir. 0.9 değeri, sahnenin tüm varlıklarının belleğe yüklendiği ancak henüz aktive edilmediği anlamına gelir. Sahne aktive edildiğinde (operation.allowSceneActivation = true; ile veya otomatik olarak), progress değeri 1.0’a ulaşır. Bu nedenle, ilerleme çubuğunuzu güncellerken Mathf.Clamp01(operation.progress / 0.9f) gibi bir normalizasyon kullanmak önemlidir.

3. Yükleme Ekranının Kendisinin Ağır Olması

Hata: Yükleme ekranı sahnesinde yüksek çözünürlüklü görseller, karmaşık shader’lar veya ağır animasyonlar kullanmak.

Çözüm: Yükleme ekranı sahnesi olabildiğince hafif ve basit olmalıdır. Amaç, ana sahne yüklenirken bile akıcı bir deneyim sunmaktır. Düşük çözünürlüklü arka planlar, sade UI elemanları ve minimal animasyonlar kullanın.

Performans ve Optimizasyon Notları

1. Bellek Temizliği (Garbage Collection)

Büyük bir sahneden diğerine geçerken, eski sahnenin varlıkları bellekten otomatik olarak temizlenir. Ancak bu işlem, özellikle eski Unity versiyonlarında, ‘Garbage Collection’ (GC) tetiklemesine ve kısa süreli takılmalara neden olabilir. Resources.UnloadUnusedAssets() metodunu manuel olarak çağırmak, kullanılmayan varlıkları temizleyebilir ancak bu işlemin kendisi de maliyetli olabilir. Genellikle, Async Sahne Yükleme sırasında bu işlemi Unity’ye bırakmak en iyisidir. Eğer büyük bir bellek temizliği gerekiyorsa, bunu yükleme ekranı sırasında, ilerleme çubuğu %90’a ulaştıktan sonra veya yeni sahne aktive olmadan hemen önce yapmayı düşünebilirsiniz.

2. Asset Bundles Kullanımı

Çok büyük oyunlarda, tüm varlıkları tek bir sahneye dahil etmek yerine, varlıkları ‘Asset Bundles’ olarak paketlemek ve ihtiyaç duyulduğunda dinamik olarak yüklemek, hem ilk yükleme sürelerini kısaltır hem de bellek yönetimini optimize eder. Async Sahne Yükleme, Asset Bundles ile mükemmel bir uyum içindedir, çünkü bundle’ları da asenkron olarak yükleyebilirsiniz.

3. Yükleme Ekranı Optimizasyonu

Yükleme ekranınızın kendisi optimize edilmiş olmalıdır. Yükleme ekranınızın kendi içindeki her şeyin (görseller, scriptler, shaderlar) olabildiğince basit ve performans dostu olduğundan emin olun. Bu, ana sahnelerin yüklenmesi sırasında bile akıcı bir deneyim sunmanızı sağlar.

Unity’de Async Sahne Yükleme, oyunlarınızın profesyonelliğini ve oyuncu deneyimini bir üst seviyeye taşıyan güçlü bir özelliktir. Bu teknikleri doğru bir şekilde uygulayarak, oyuncularınıza akıcı, kesintisiz ve keyifli bir oyun deneyimi sunabilirsiniz.

Leave a Reply

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir