Unity’de Sahne Geçişleri: SceneManager.LoadScene() Kılavuzu
Oyun geliştirirken, farklı seviyeler, menüler veya oyun içi mekanlar arasında geçiş yapmak temel bir gerekliliktir. Unity’de bu geçişler genellikle sahneler (scenes) arasında yapılır ve bunun için kullanılan ana araçlardan biri UnityEngine.SceneManagement namespace’i içindeki SceneManager.LoadScene() metodudur. Bu makalede, Unity Sahne Yükleme işleminin temellerini, gelişmiş kullanımlarını, pratik ipuçlarını ve sıkça yapılan hataları ele alacağız.
Unity’de Sahne Yönetimi Neden Önemli?
Unity’de sahneler, oyununuzun farklı bölümlerini veya durumlarını temsil eden ayrı dosyalardır. Örneğin, ana menü, oyun seviyesi 1, oyun seviyesi 2, ayarlar menüsü gibi her biri ayrı bir sahne olabilir. Bu yapının kullanılması, projenin düzenli kalmasını, kaynakların daha iyi yönetilmesini ve geliştirme sürecinin hızlanmasını sağlar. Oyuncuyu bir sahneden diğerine sorunsuz bir şekilde taşımak, akıcı bir kullanıcı deneyimi için kritik öneme sahiptir.
SceneManager.LoadScene() Temelleri
SceneManager.LoadScene() metodu, adından da anlaşılacağı gibi, belirtilen bir sahneyi yüklemek için kullanılır. Bu metodu kullanmadan önce projenize UnityEngine.SceneManagement namespace’ini dahil etmeniz gerekir:
using UnityEngine.SceneManagement;
public class SceneSwitcher : MonoBehaviour
{
public void GoToNextScene()
{
// Sahne adıyla yükleme
SceneManager.LoadScene("OyunSeviyesi1");
// Veya sahne index'i ile yükleme (Build Settings'teki sırası)
// SceneManager.LoadScene(1);
}
}
LoadScene() metodunu kullanırken iki temel yöntem vardır:
- Sahne Adı ile Yükleme:
SceneManager.LoadScene("SahneAdı"). Bu yöntem daha okunabilir olsa da, sahne adını yanlış yazma riskini taşır. - Sahne Index’i ile Yükleme:
SceneManager.LoadScene(sahneIndex). Her sahnenin Build Settings’te bir index’i bulunur. Bu yöntem daha az hata payı bırakır ancak sahne sıralaması değiştiğinde index’lerin güncellenmesi gerekir.
Önemli Not: Yüklemek istediğiniz tüm sahnelerin File > Build Settings… menüsündeki “Scenes In Build” listesine eklenmiş olması zorunludur. Aksi takdirde, Unity sahneyi bulamaz ve bir hata fırlatır.
Yükleme Modları: LoadSceneMode
LoadScene() metodunun aşırı yüklenmiş versiyonları, sahne yükleme modunu belirlemenize olanak tanır. İki ana mod vardır:
LoadSceneMode.Single: Bu varsayılan moddur. Yeni sahne yüklendiğinde mevcut sahne ve tüm içeriği (oyun objeleri, bileşenler vb.) bellekten kaldırılır. Çoğu sahne geçişi için bu mod kullanılır.LoadSceneMode.Additive: Bu mod, yeni sahneyi mevcut sahnenin üzerine ekler. Bu, birden fazla sahneyi aynı anda aktif tutmak istediğinizde kullanışlıdır (örneğin, kalıcı bir UI sahnesi veya seviye parçalarını dinamik olarak yüklemek için).
// Mevcut sahneyi kapatıp "OyunSeviyesi1" sahnesini yükle
SceneManager.LoadScene("OyunSeviyesi1", LoadSceneMode.Single);
// Mevcut sahnenin üzerine "UI_Sahnesi" sahnesini ekle
SceneManager.LoadScene("UI_Sahnesi", LoadSceneMode.Additive);
Asenkron Yükleme: LoadSceneAsync()
Büyük ve karmaşık sahnelerin yüklenmesi zaman alabilir ve bu süre zarfında oyun donmuş gibi görünebilir. Bu durum, oyuncu deneyimini olumsuz etkiler. SceneManager.LoadSceneAsync() metodu, sahne yükleme işlemini arka planda, asenkron olarak gerçekleştirerek bu donmaları engeller. Bu sayede, yükleme ekranları gösterebilir, animasyonlar oynatabilir veya diğer işlemleri yapmaya devam edebilirsiniz.
using UnityEngine.SceneManagement;
using System.Collections;
using UnityEngine.UI;
public class AsyncSceneLoader : MonoBehaviour
{
public Slider loadingSlider;
public GameObject loadingPanel;
public void LoadAsyncScene(string sceneName)
{
loadingPanel.SetActive(true);
StartCoroutine(LoadYourAsyncScene(sceneName));
}
IEnumerator LoadYourAsyncScene(string sceneName)
{
AsyncOperation operation = SceneManager.LoadSceneAsync(sceneName);
operation.allowSceneActivation = false; // Sahne tamamen yüklense bile hemen geçiş yapma
while (!operation.isDone)
{
float progress = Mathf.Clamp01(operation.progress / 0.9f);
loadingSlider.value = progress;
// Yükleme %90'a ulaştığında (Unity'nin dahili sahne aktivasyonu için ayırdığı kısım)
if (operation.progress >= 0.9f)
{
// İsteğe bağlı: Burada 'Devam Et' butonu gösterebiliriz
// veya belirli bir süre bekleyip otomatik geçiş yapabiliriz.
// Örneğin, bir tuşa basılana kadar beklemek:
// if (Input.GetKeyDown(KeyCode.Space))
// {
// operation.allowSceneActivation = true;
// }
// Veya otomatik geçiş:
operation.allowSceneActivation = true;
}
yield return null;
}
}
}
Yukarıdaki örnekte, operation.allowSceneActivation = false; ile sahnenin %90 yüklendikten sonra bile hemen aktifleşmesini engelliyoruz. Bu, oyuncuya son bir ‘Devam Et’ butonu göstermek veya son kontrolleri yapmak için zaman tanır. operation.progress değeri, yüklemenin ne kadarının tamamlandığını gösterir (0.0 ile 0.9 arasında değişir, son %10 Unity’nin sahne aktivasyonu için ayrılmıştır).
Pratik İpuçları
1. Yükleme Ekranı Oluşturma: Büyük sahneler yüklerken oyuncuya geri bildirim sağlamak için LoadSceneAsync() metodunu ve bir UI Slider’ı kullanarak bir yükleme ekranı oluşturun. Bu, oyuncunun oyunun donduğunu düşünmesini engeller ve bekleme süresini daha katlanabilir hale getirir. Yukarıdaki kod bloğu bunun güzel bir örneğidir. Bu yöntem, Unity Sahne Yükleme deneyimini önemli ölçüde iyileştirir.
2. Sahneler Arası Veri Aktarımı: Sahneler arasında veri aktarımı yapmak için birkaç yöntem vardır:
DontDestroyOnLoad(): Bir oyun objesini bir sahneden diğerine taşımak için kullanılır. Genellikle oyun yöneticileri, ses yöneticileri veya oyuncu verilerini tutan objeler için tercih edilir.- Statik Değişkenler: En basit yöntemlerden biridir. Bir C# sınıfında statik değişkenler tanımlayarak, bu değişkenlere herhangi bir sahneden erişebilir ve değerlerini değiştirebilirsiniz. Ancak, statik değişkenlerin yaşam döngüsü iyi yönetilmelidir.
- Scriptable Objects: Daha karmaşık veri yapıları için Scriptable Objects kullanmak, verileri kalıcı olarak saklamak ve sahneler arası paylaşmak için harika bir yoldur.
// DontDestroyOnLoad kullanımı
public class GameManager : MonoBehaviour
{
void Awake()
{
// Bu objenin sahne geçişlerinde yok olmamasını sağla
DontDestroyOnLoad(this.gameObject);
}
public void LoadNextScene()
{
SceneManager.LoadScene("OyunSeviyesi2");
}
}
3. Sahne Sıralaması ve Build Settings: Her zaman Build Settings’teki sahne sıralamasının ve adlarının doğru olduğundan emin olun. Özellikle sahne index’leri ile yükleme yapıyorsanız, sıralamanın değişmesi yanlış sahnenin yüklenmesine neden olabilir. Sahne adıyla yükleme yaparken de yazım hatalarına dikkat edin. Unity Sahne Yükleme işlemlerinin doğru çalışması için bu adım hayati önem taşır.
Yaygın Hatalar ve Çözümleri
-
Hata 1: “Scene ‘X’ couldn’t be loaded because it has not been added to the build settings…” Hatası:
Çözüm: Yüklemek istediğiniz sahneyi File > Build Settings… menüsündeki “Scenes In Build” listesine sürükleyip bırakın.
-
Hata 2: Oyun Objem Sahne Geçişinde Kayboldu:
Çözüm: Eğer bir oyun objesinin sahne geçişlerinde varlığını sürdürmesini istiyorsanız,
DontDestroyOnLoad(gameObject)metodunu kullanın. Bu genellikle oyun yöneticileri, müzik çalarlar veya oyuncu verilerini tutan objeler için geçerlidir. -
Hata 3: Oyun Sahne Yüklenirken Donuyor/Takılıyor:
Çözüm: Büyük sahneler için
SceneManager.LoadScene()yerineSceneManager.LoadSceneAsync()kullanın ve yükleme ilerlemesini bir yükleme ekranında gösterin. Bu, oyuncu deneyimini çok daha akıcı hale getirecektir. -
Hata 4: Yanlış Sahne Yükleniyor:
Çözüm: Sahne adını veya index’ini iki kez kontrol edin. Özellikle sahne adlarında büyük/küçük harf duyarlılığına dikkat edin veya Build Settings’teki index’lerin doğru sahneyi işaret ettiğinden emin olun.
Performans ve Optimizasyon Notları
Unity Sahne Yükleme performansını artırmak için:
LoadSceneAsync()Kullanımı: Büyük sahneleri yüklerken her zaman asenkron yüklemeyi tercih edin. Bu, ana iş parçacığının (main thread) bloke olmasını engelleyerek oyunun donmasını önler.- Gereksiz Kaynakları Boşaltma: Sahne geçişlerinden sonra, önceki sahnede kalan ve artık kullanılmayan kaynakları (dokular, sesler vb.) bellekten temizlemek için
Resources.UnloadUnusedAssets()metodunu çağırabilirsiniz. Bu özellikle mobil platformlarda veya bellek kısıtlı ortamlarda önemlidir. Ancak bu işlem de biraz zaman alabilir, bu yüzden dikkatli kullanılmalıdır. - Küçük Sahneler Halinde Tasarım: Mümkünse, çok büyük ve karmaşık tek bir sahne yerine, oyununuzu daha küçük, yönetilebilir parçalara bölün. Bu, her bir sahnenin daha hızlı yüklenmesini sağlar ve
LoadScene()çağrılarının daha verimli olmasını sağlar.
Sonuç
SceneManager.LoadScene() ve ilgili metotlar, Unity’de oyun akışını yönetmek için vazgeçilmez araçlardır. Senkron ve asenkron yükleme arasındaki farkları anlamak, LoadSceneMode‘ları doğru kullanmak ve yaygın hatalardan kaçınmak, hem geliştirme sürecinizi kolaylaştıracak hem de oyuncularınıza daha iyi bir deneyim sunacaktır. Bu kılavuzdaki ipuçlarını ve yöntemleri uygulayarak, Unity projelerinizde profesyonel düzeyde Unity Sahne Yükleme işlemleri gerçekleştirebilirsiniz.



