Unity de birden çok sahne ile çalışma

ScriptableObjects ile daha iyi Sahne iş akışı elde edin.

Unity’de birden fazla Sahneyi yönetmek zor olabilir ve bu iş akışını iyileştirmek hem oyununuzun performansı hem de ekibinizin verimliliği için çok önemlidir. Burada, Sahne iş akışlarınızı daha büyük projeler için ölçeklendirilecek şekilde ayarlamak için bazı ipuçlarını paylaşıyoruz.

Çoğu oyun birden fazla seviye içerir ve seviyeler genellikle birden fazla Sahne içerir. Sahnelerin nispeten küçük olduğu oyunlarda, Prefabrileri kullanarak bunları farklı bölümlere ayırabilirsiniz. Ancak, bunları oyun sırasında etkinleştirmek veya başlatmak için tüm bu Prefabrilere başvurmanız gerekir. Bu, oyununuz büyüdükçe ve bu referanslar bellekte daha fazla yer kapladıkça Scenes’i kullanmak daha verimli hale gelir.

Seviyelerinizi bir veya daha fazla Birlik Sahnesine ayırabilirsiniz. Hepsini yönetmek için en uygun yolu bulmak anahtar olur. Çoklu Sahne düzenlemesini kullanarak Editör’de ve çalışma zamanında birden fazla Sahne açabilirsiniz . Seviyeleri birden çok Sahneye bölmek, Git, SVN, Unity Collaborate ve benzerleri gibi işbirliği araçlarındaki birleşme çatışmalarını önlediğinden ekip çalışmasını kolaylaştırma avantajına da sahiptir .

Seviye oluşturmak için birden fazla Sahneyi yönetme

Aşağıdaki videoda, oyun mantığını ve seviyenin farklı bölümlerini birkaç farklı Birlik Sahnesine ayırarak bir seviyenin nasıl daha verimli yükleneceğini gösteriyoruz. Ardından, bu Sahneleri yüklerken Eklemeli Sahne yükleme modunu kullanarak , oyun mantığının yanında gerekli olan parçaları kalıcı olarak yükler ve boşaltırız. Prefabrları, bir takımda çalışırken aynı zamanda çok fazla esneklik sunan Sahneler için “çapa” görevi görmek için kullanırız, çünkü her Sahne seviyenin bir bölümünü temsil eder ve ayrı olarak düzenlenebilir.

Düzenleme Modundayken bu Sahneleri yine de yükleyebilir ve istediğiniz zaman Oynat’a basabilirsiniz, böylece seviye tasarımı oluştururken hepsini birlikte görselleştirebilirsiniz.

Bu Sahneleri yüklemek için iki farklı yöntem gösteriyoruz. Birincisi, açık bir dünya gibi iç mekan dışı seviyelere uygun olan mesafeye dayalıdır. Bu teknik aynı zamanda yükleme ve boşaltma işlemini gizlemek için bazı görsel efektlerin (örneğin sis gibi) de yararlıdır.

İkinci teknik, hangi Sahnelerin yükleneceğini kontrol etmek için bir Tetik kullanır , bu da iç mekanlarla çalışırken daha etkilidir.

Artık her şey seviyenin içinde yönetildiğine göre, seviyeleri daha iyi yönetmek için üstüne bir katman ekleyebilirsiniz.

ScriptableObjects kullanarak oyun içinde birden fazla seviyeyi yönetme

Oyunun tüm süresi boyunca her seviye için farklı Sahneleri ve tüm seviyeleri takip etmek istiyoruz. Bunu yapmanın olası bir yolu, MonoBehaviour komut dosyalarınızda statik değişkenler ve tekli şablon kullanmaktır, ancak bu çözümle ilgili birkaç sorun vardır. Tekli kalıbı kullanmak, sistemleriniz arasında sağlam bağlantılara izin verir, bu yüzden kesinlikle modüler değildir. Sistemler ayrı ayrı var olamaz ve her zaman birbirine bağlıdır.

Diğer bir konu statik değişkenlerin kullanımını içerir. Onları Müfettiş’te göremediğiniz için, onları ayarlamak için kodu değiştirmeniz gerekir, bu da sanatçıların veya seviye tasarımcılarının oyunu kolayca test etmesini zorlaştırır. Farklı Sahneler arasında paylaşılacak verilere ihtiyaç duyduğunuzda, DontDestroyOnLoad ile birleştirilmiş statik değişkenler kullanırsınız, ancak mümkün olduğunda bunlardan kaçınılmalıdır.

Farklı Sahneler hakkında bilgi depolamak için, çoğunlukla veri depolamak için kullanılan serileştirilebilir bir sınıf olan ScriptableObject kullanabilirsiniz . GameObjects’e bağlı bileşenler olarak kullanılan MonoBehaviour komut dosyalarının aksine, ScriptableObjects herhangi bir GameObjects’e eklenmez ve böylece tüm projenin farklı Sahneleri arasında paylaşılabilir.

Bu yapıyı seviyeler için değil, aynı zamanda oyununuzdaki Sahneler menüsü için de kullanabilirsiniz. Bunu yapmak için, düzeyler ve menüler arasındaki farklı ortak özellikleri içeren bir GameScene sınıfı oluşturun.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class GameScene : ScriptableObject
{
    [Header(“Information”)]
    public string sceneName;
    public string shortDescription;
    [Header(“Sounds”)]
    public AudioClip music;
    [Range(0.0f, 1.0f)]
    public float musicVolume;
    [Header(“Visuals”)]
    public PostProcessProfile postprocess;
}

Sınıfın MonoBehaviour’dan değil ScriptableObject öğesinden miras aldığına dikkat edin. Oyununuz için ihtiyaç duyduğunuz sayıda özellik ekleyebilirsiniz. Bu adımdan sonra, yeni oluşturulan GameScene sınıfından miras alan Düzey ve Menü sınıfları oluşturabilirsiniz; böylece bunlar aynı zamanda ScriptableObjects olur.

1
2
3
4
5
6
7
[CreateAssetMenu(fileName = “NewLevel”, menuName = “Scene Data/Level”)]
public class Level : GameScene
{
    //Settings specific to level only
    [Header(“Level specific”)]
    public int enemiesCount;
}

Üstüne CreateAssetMenu özniteliği eklemek, Unity’deki Varlıklar menüsünden yeni bir düzey oluşturmanıza olanak tanır. Aynı şeyi Menu sınıfı için de yapabilirsiniz. Müfettiş’ten menü türünü seçebilmek için bir numaralandırma da ekleyebilirsiniz.

1
2
3
4
5
6
7
8
9
10
11
12
13
public enum Type
{
    Main_Menu,
    Pause_Menu
}
[CreateAssetMenu(fileName = “NewMenu”, menuName = “Scene Data/Menu”)]
public class Menu : GameScene
{
    //Settings specific to menu only
    [Header(“Menu specific”)]
    public Type type;
}

Artık seviyeler ve menüler oluşturabileceğinize göre, kolay başvuru için seviyeleri ve menüleri listeleyen bir veritabanı ekleyelim. Ayrıca oynatıcının geçerli seviyesini izlemek için bir dizin de ekleyebilirsiniz. Ardından, yeni bir oyun yüklemek için (bu durumda ilk seviye yüklenecektir), geçerli seviyeyi tekrar oynatmak ve bir sonraki seviyeye geçmek için yöntemler ekleyebilirsiniz. Bu üç yöntem arasında yalnızca dizinin değiştiğini unutmayın, böylece düzeyi birden çok kez kullanmak için dizine yükleyen bir yöntem oluşturabilirsiniz.

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
[CreateAssetMenu(fileName = “sceneDB”, menuName = “Scene Data/Database”)]
public class ScenesData : ScriptableObject
{
    public List<Level> levels = new List<Level>();
    public List<Menu> menus = new List<Menu>();
    public int CurrentLevelIndex=1;
    /*
     * Levels
     */
    //Load a scene with a given index
    public void LoadLevelWithIndex(int index)
    {
        if (index <= levels.Count)
        {
            //Load Gameplay scene for the level
            SceneManager.LoadSceneAsync(“Gameplay” + index.ToString());
            //Load first part of the level in additive mode
            SceneManager.LoadSceneAsync(“Level” + index.ToString() + “Part1”, LoadSceneMode.Additive);
        }
        //reset the index if we have no more levels
        else CurrentLevelIndex =1;
    }
    //Start next level
    public void NextLevel()
    {
        CurrentLevelIndex++;
        LoadLevelWithIndex(CurrentLevelIndex);
    }
    //Restart current level
    public void RestartLevel()
    {
        LoadLevelWithIndex(CurrentLevelIndex);
    }
    //New game, load level 1
    public void NewGame()
    {
        LoadLevelWithIndex(1);
    }
  
    /*
     * Menus
     */
    //Load main Menu
    public void LoadMainMenu()
    {
        SceneManager.LoadSceneAsync(menus[(int)Type.Main_Menu].sceneName);
    }
    //Load Pause Menu
    public void LoadPauseMenu()
    {
        SceneManager.LoadSceneAsync(menus[(int)Type.Pause_Menu].sceneName);
    }

Menüler için yöntemler de vardır ve daha önce istediğiniz belirli menüyü yüklemek için oluşturduğunuz numaralandırma türünü kullanabilirsiniz – yalnızca numaralandırmadaki ve menüler listesindeki sıralamanın aynı olduğundan emin olun.

Son olarak, Proje penceresinde sağ tıklayarak Varlıklar menüsünden bir seviye, menü veya veritabanı ScriptableObject oluşturabilirsiniz.

Oradan, ihtiyacınız olan seviyeleri ve menüleri eklemeye, ayarları değiştirmeye ve sonra bunları Scenes veritabanına eklemeye devam edin. Aşağıdaki örnekte Level1, MainMenu ve Scenes Verilerinin nasıl göründüğü gösterilmektedir.

Bu yöntemleri çağırmanın zamanı geldi. Bu örnekte, bir oyuncu seviyenin sonuna ulaştığında görünen kullanıcı arabirimindeki (UI) Sonraki Düzey Düğmesi NextLevel yöntemini çağırır. Yöntemi düğmeye eklemek için, yeni bir etkinlik eklemek üzere Button bileşeninin Tıklandığında olayının artı düğmesini tıklatın, sonra Scenes Data ScriptableObject öğesini nesne alanına sürükleyip bırakın ve aşağıda gösterildiği gibi ScenesData’dan NextLevel yöntemini seçin.

Şimdi diğer düğmeler için aynı işlemi uygulayabilirsiniz – seviyeyi tekrar oynatmak veya ana menüye gitmek vb. Arka plan müziği veya işlem sonrası profili için AudioClip gibi farklı özelliklere erişmek ve bunları düzeyde kullanmak için ScriptableObject öğesine başka herhangi bir komut dosyasından da başvurabilirsiniz.

şlemlerinizi hata geçirmez hale getirmeye yönelik ipuçları

  • Yükleme / boşaltma işlemlerini en aza indirme

Videoda gösterilen ScenePartLoader komut dosyasında, bir oynatıcının çarpıştırıcıya birden çok kez girip çıkabileceğini ve bir Sahnenin tekrar tekrar yüklenmesini ve boşaltılmasını tetikleyebildiğini görebilirsiniz. Bundan kaçınmak için, sahnede kod yükleme ve boşaltma yöntemlerini çağırmadan önce bir koroutin ekleyebilir ve oyuncu tetikleyiciden ayrılırsa koroutini durdurabilirsiniz.

  • Adlandırma kuralları

Diğer bir genel ipucu da projede katı adlandırma kuralları kullanmaktır. Ekip, senaryolardan ve Sahneler’den projedeki materyallere ve diğer şeylere kadar farklı varlık türlerinin nasıl adlandırılacağı konusunda önceden anlaşmalıdır. Bu sadece sizin için değil, aynı zamanda ekip arkadaşlarınızın proje üzerinde çalışmasını ve bakımını yapmasını da kolaylaştıracaktır. Bu her zaman iyi bir fikirdir, ancak bu özel durumda ScriptableObjects ile Sahne yönetimi için çok önemlidir. Örneğimizde Sahne adına dayalı basit bir yaklaşım kullanıldı, ancak sahne adına daha az dayanan birçok farklı çözüm var. Dize tabanlı yaklaşımdan kaçınmalısınız çünkü bir Birlik Sahne Alanı’nı belirli bir bağlamda yeniden adlandırırsanız, oyunun başka bir bölümünde Sahne’nin yüklenmeyeceği anlamına gelir.

  • Özel takımlar

Oyun genelinde isim bağımlılığından kaçınmanın bir yolu, komut dosyanızı Sahneleri Nesne türü olarak referans gösterecek şekilde ayarlamaktır . Bu, bir Sahne öğesini bir Denetçide sürükleyip bırakmanıza ve ardından adını komut dosyasında güvenle almanıza olanak tanır. Ancak, bir Editör sınıfı olduğundan, çalışma zamanında AssetDatabase sınıfına erişiminiz yoktur , bu nedenle Editör’de çalışan, insan hatasını önleyen ve yine de çalışma zamanında çalışan bir çözüm için her iki veri parçasını birleştirmeniz gerekir. Serileştirme sonrasında dize yolunu Scene öğesinden ayıklayabilen ve çalışma zamanında kullanılmak üzere saklayabilen bir nesnenin nasıl uygulanacağına ilişkin bir örnek için ISerializationCallbackReceiver arabirimine başvurabilirsiniz .

Buna ek olarak, bu menüden manuel olarak eklemek ve senkronize tutmak zorunda kalmak yerine, düğmeleri kullanarak Oluşturma Ayarlarına hızlı bir şekilde Sahne eklemeyi kolaylaştırmak için özel bir Denetçi de oluşturabilirsiniz .

Bu tür araçlara örnek olarak, geliştirici JohannesMP’nin bu büyük açık kaynak uygulamasına göz atın (bu resmi bir Unity kaynağı değildir).

Haydi ne düşündüğünü söyle

Bu yazı, ScriptableObjects’in Prefabs ile birleştirilmiş birden fazla Sahneyle çalışırken iş akışınızı geliştirebilmesinin yalnızca bir yolunu gösterir. Farklı oyunların Sahneleri yönetmenin çok farklı yolları vardır – tüm oyun yapıları için tek bir çözüm işe yaramaz. Projenizin organizasyonuna uyacak şekilde kendi özel aletlerinizi uygulamak çok mantıklıdır.

Bu bilgilerin projenizde size yardımcı olabileceğini veya kendi Sahne yönetimi araçlarınızı oluşturmanıza ilham verebileceğini umuyoruz.

Herhangi bir sorunuz varsa yorumlarda bize bildirin. Oyununuzdaki Sahneleri yönetmek için hangi yöntemleri kullandığınızı duymak isteriz. Gelecekteki blog yayınlarında yer almamızı istediğiniz diğer kullanım durumlarını önermekten çekinmeyin.

Oyun Motorları hakkında güncel bilgi için Tıklayınız.

Unity3D den incelemek için Tıklayınız.

One thought on “Unity de birden çok sahne ile çalışma

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir