e
sv

Daha temiz Unity kodu için 6 modern C# özelliği

avatar

Yazılım Method

  • e 0

    Mutlu

  • e 0

    Eğlenmiş

  • e 0

    Şaşırmış

  • e 0

    Kızgın

  • e 0

    Üzgün

C# 7.0'dan bu yana dile daha az kod yazmamıza yardımcı olan birçok kod geliştirmesi eklendi. Bu öğretici, daha kısa ve okunabilir kod yazmamıza yardımcı olabilecek altı yeni özelliğe ve bu özellikleri Unity için C#'ta nasıl kullanabileceğimize odaklanacaktır.

Bunlar öğretici bölümlerdir:

Önkoşullar

Bu eğitimle birlikte takip etmek için aşağıdaki önkoşullar gereklidir:

  • Unity hakkında temel bilgiler
  • Unity'de C# betikleri yazma deneyimi

Unity projemizi kurmak

Öncelikle Unity projemizi oluşturmamız gerekiyor. Bu eğitim için, şu anda yazdığım en yeni LTS Unity sürümü olan 2021.3.4f1 sürümünü kullanacağız.

Proje şablonları listesinde, 2B(çekirdek) (en basiti) seçin, buna bir isim verin ve Proje oluştur düğmesine tıklayın.

Proje Ekran Görüntüsü Oluştur

Proje başlatıldığında, Assets klasörünün içinde Scripts adlı bir klasör oluşturun. Eğitim sırasında projemizi düzenli tutmak için bunları kullanacağız.

Varlıklar Proje Klasörü

öğretici yapı

Yeni C# özelliğinin nasıl kullanılacağına dair her örnek için önce bunun daha önce nasıl yapıldığına ve ardından yeni özellikle nasıl daha az okunabilir kod yazabileceğimize bakacağız.

Aşağıdaki sınıflar, eğitim boyunca tüm örneklerde kullanılan taslaklardır. Bunları Scripts klasörü içindeki bir komut dosyasına ekleyebilirsiniz:

 // OYUN MODU.
genel numaralandırma GameMode
{
    zamanSaldırı,
    Hayatta kalmak,
    Puan
}

// DÜŞMANLAR.
genel soyut sınıf Düşman
{
    public bool IsVisible { get; Ayarlamak; }
    public bool HasArmor { get; Ayarlamak; }
}
 
public class Minyon : Düşman { }
public class Troll : Düşman { }
public class Vampire : Enemy { }

public class Zombie : Enemy { }


// SİLAHLAR.
genel soyut sınıf Silah { }
public class Bahis : Silah { }
public class Av Tüfeği : Silah { }

Unity'de C# özellikleri desteği

C# sürüm 8 ve 9'da dile birçok yeni özellik eklendi. Her sürüm için tam özellik listesini aşağıdaki bağlantılardan okuyabilirsiniz:

Unity'deki C# 8 ve 9 özellikleri: Eksik olan ne?

C# 8 için Unity desteği 2020.2 sürümünde, C# 9 ise 2021.2 sürümünde başlamıştır.

Her C# 8 ve 9 özelliğinin Unity tarafından desteklenmediğini unutmayın, örneğin:

  • varsayılan arayüz yöntemleri
  • indeksler ve aralıklar
  • asenkron akışlar
  • asenkron tek kullanımlık
  • yayan yerelleri bastır başlat bayrağı
  • kovaryant dönüş türleri
  • modül başlatıcılar
  • yönetilmeyen işlev işaretçileri için genişletilebilir çağrı kuralları
  • init sadece ayarlayıcılar

Bu desteklenmeyen özelliklerin çoğu, yönetilmeyen işlev işaretçileri için genişletilebilir çağrı kuralları gibi çok özel senaryolarda kullanılır ve dizinler ve aralıklar gibi bazıları kullanılmaz.

Bu nedenle, indeksler ve aralıklar ve yalnızca init ayarlayıcılar gibi özellikler, Unity'nin gelecekteki sürümlerinde büyük olasılıkla desteklenecektir. Ancak, çok özel bir senaryo için desteklenmeyen bir özelliğin gelecekte Unity desteği kazanma şansı, dizinler ve aralıklar gibi bir özellikten daha küçüktür.

Belki Unity'de bu desteklenmeyen özellikleri kullanmak için bazı geçici çözümler bulabilirsiniz, ancak Unity platformlar arası bir oyun motoru olduğu için bunu yapmanızı önermiyorum. Yeni bir özellikteki bir geçici çözüm, sizi anlaması, hata ayıklaması ve çözmesi oldukça zor sorunlara yol açabilir.

Neyse ki Unity, C# 8 ve 9'daki daha yaygın bazı kalıpları ve ifadeleri destekler. Aşağıdaki en yararlı olanlardan bazılarını inceleyelim ve daha temiz kod yazmamızı nasıl sağlayabileceklerini görelim.

İfadeyi değiştir

switch ifadesi, bir switch yapmak için LOC'yi (Kod Satırları) önemli ölçüde basitleştirebilir ve azaltabilir, çünkü case ve return ifadeleri gibi bir sürü ortak koddan kaçınabiliriz.

Doküman ipucu : switch ifadesi, bir ifade bağlamında anahtara benzer anlambilim sağlar. Anahtar kolları bir değer ürettiğinde kısa bir sözdizimi sağlar.

Çoğu zaman, bir switch ifadesi, kendi case bloklarının her birinde bir değer üretir. İfadeleri değiştir, daha özlü ifade sözdizimi kullanmanıza olanak tanır. Daha az tekrarlayan büyük/küçük harf ve anahtar kelimeler ve daha az kaşlı ayraç vardır.

Önceki

 genel dize GetModeTitleOld(GameMode modu)
{
    geçiş (mod)
    {
        durum GameMode.Points:
            "Puan modu"na geri dön;

        durumda GameMode.Survive:
            "Hayatta kalma modu"na geri dön;

        durum GameMode.TimeAttack:
            "Zaman Saldırısı modu"na geri dön;

        varsayılan:
            "Desteklenmeyen oyun modu"na geri dön;
    }
}

Sonrasında

 genel dize GetModeTitleNew(GameMode modu)
{
    dönüş modu anahtarı
    {
        GameMode.Points => "Puan modu",
        GameMode.Survive => "Hayatta kalma modu",
        GameMode.TimeAttack => "Zaman Saldırı modu",
        _ => "Desteklenmeyen oyun modu",
    };
}

Özellik deseni

Özellik deseni, bir switch ifadesinde incelenen nesnenin özellikleriyle eşleşmenizi sağlar.

Aşağıdaki örnekte görebileceğiniz gibi, bir özellik kalıbı kullanarak, bir dizi if ifadesini, switch ifadesindeki nesnenin eşleşmesi gereken basit bir özellik listesine dönüştürebiliriz.

_ => , klasik bir switch default aynı anlama sahiptir.

Belge ipucu : bir ifade sonucu boş olmadığında ve her iç içe desen, ifade sonucunun karşılık gelen özelliği veya alanıyla eşleştiğinde bir özellik kalıbı bir ifadeyle eşleşir.

Önceki

 public float CalculateDamageOld(Düşman düşmanı)
{
    if (düşman.IsVisible)
        geri dön düşman.HasArmor ? 1: 2;

    0 döndür;
}

Sonrasında

 genel statik şamandıra CalculateDamageNew(Düşman düşmanı) => düşman anahtarı
{
    { IsVisible: true, HasArmor: true } => 1,
    { IsVisible: true, HasArmor: false } => 2,
    _ => 0
};

Tip deseni

Bir ifadenin çalışma zamanı türünün belirli bir türle uyumlu olup olmadığını kontrol etmek için tür kalıplarını kullanabiliriz.

Tip kalıbı, bir özellik kalıbıyla hemen hemen aynı mantıktır, ancak şimdi bir nesne tipi bağlamında kullanılmaktadır. Bir nesne türünü kontrol eden bir dizi if ifadesini, switch ifadesindeki nesnenin eşleşmesi gereken bir tür listesine dönüştürebiliriz.

Önceki

 genel statik şamandıra GetEnemyStrengthOld(Düşman düşmanı)
{
    if (düşman Minyon ise)
        dönüş 1;

    if (düşman Troll'dür)
        dönüş 2;

    if (düşman vampirdir)
        dönüş 3;

    if (düşman == boş)
        yeni ArgumentNullException(nameof(düşman));

    yeni ArgumentException("Bilinmeyen düşman", nameof(düşman));
}

Sonrasında

 genel statik şamandıra GetEnemyStrengthNew(Düşman düşmanı) => düşman anahtarı
{
    minyon => 1,
    Trol => 2,
    vampir => 3,
    null => yeni ArgumentNullException(nameof(düşman) atın),
    _ => yeni ArgumentException("Bilinmeyen düşman", nameof(düşman)),
};

Tip modelini kullanarak, 16 kod satırından aynı sonuca sahip olan ve okunması ve anlaşılması oldukça açık olan 8 satıra gidiyoruz.

Sabit model

Bir ifade sonucunun belirtilen bir sabite eşit olup olmadığını test etmek için sabit bir desen kullanılabilir.

Muhtemelen en basit kalıp eşleşmesidir, yalnızca sabit bir değerle (örneğin bir dize) eşleşir ve ardından sonucu döndürür.

Önceki

 public Enemy CreateEnemyByNameOld(dize adı)
{
    if(isim == boş)
        yeni ArgumentNullException(nameof(name));

    if (isim.Eşittir("Minyon"))
        yeni Minyon'u döndür();

    if (isim.Eşittir("Troll"))
        yeni Troll() döndür;

    if (isim.Eşittir("Vampir"))
        yeni Vampire() döndür;

    yeni ArgumentException($"Bilinmeyen düşman: {isim}", nameof(name));
}

Sonrasında

 public Enemy CreateEnemyByNameNew(string name) => isim değiştirme
{
    "Minyon" => yeni Minyon(),
    "Troll" => yeni Trol(),
    "Vampir" => yeni Vampir(),
    null => yeni ArgumentNullException(nameof(name)) atın,
    _ => yeni ArgumentException ($"Bilinmeyen düşman: {isim}", nameof(name)) fırlat
};

Sabit bir kalıp, int , float , char , string , bool ve enum gibi herhangi bir sabit ifadeyle kullanılabilir.

ilişkisel desen

İlişkisel bir model, bir ifade sonucunu bir sabitle karşılaştırır.

Bu, en karmaşık desen eşleşmesi gibi görünebilir, ancak özünde o kadar karmaşık değil. İlişkisel Model ile yapabileceğimiz şey, nesneyi değerlendirmek için doğrudan < , > , <= veya >= gibi mantıksal operatörleri kullanmak ve ardından switch için bir sonuç sağlamaktır.

Doküman ipucu : ilişkisel bir kalıbın sağ tarafı sabit bir ifade olmalıdır.

Önceki

 genel dize GetEnemyEnergyMessageOld(kayan enerji)
{
    if(enerji < 0 || enerji > 1)
        throw new ArgumentException("Enerji 0.0 ile 1.0 arasında olmalıdır", nameof(energy));

    if (enerji >= 1f)
        "Sağlıklı" dönüş;

    if (enerji > .5f)
        "Yaralı" dönüşü;

        dönüş "Çok acıttı";
}

Sonrasında

 public string GetEnemyEnergyMessageNew(float enerji) => enerji anahtarı
{
    < 0 veya > 1 => throw new ArgumentException("Enerji 0.0 ile 1.0 arasında olmalıdır", nameof(energy)),
    >= 1 => "Sağlıklı",
    > .5f => "Yaralı",
    _ => "Çok incindi"
};

İlişkisel bir modelde < , > , <= veya >= ilişki operatörlerinden herhangi biri kullanılabilir.

mantıksal model

Mantıksal ifadeler oluşturmak için not , and , ve or model birleştiricilerini kullanabiliriz.

Bu, daha karmaşık ve ayrıntılı bir model eşleşmesi oluşturmak için not , and , and or mantıksal operatörlerini birleştirebileceğiniz ilişkisel kalıbın bir uzantısı gibidir.

Belge ipucu : aşağıdaki mantıksal kalıpları oluşturmak için not , and , ve or kalıp birleştiricilerini kullanırsınız:

  • Olumsuzluk, bir ifadeyle eşleşen kalıp not , olumsuzlanan kalıp ifadeyle eşleşmediğinde
  • Her iki kalıp ifadeyle eşleştiğinde bir ifadeyle eşleşen bağlaç and kalıp
  • Kalıplardan herhangi biri ifadeyle eşleştiğinde bir ifadeyle eşleşen ayırıcı or kalıp

Önceki

 public float HesaplaEnergyLossByStakeOld(Düşman düşmanı)
{
    if (düşman == boş)
        yeni ArgumentNullException(nameof(düşman));

    if (düşman Vampir değilse)
        dönüş .1f;

    1f dönüş;
}

Sonrasında

 public float CalculateEnergyLossByStakeNew(Düşman düşmanı) => düşman anahtarı
{
    null => yeni ArgumentNullException(nameof(düşman) atın),
    vampir değil => .1f,
    _ => 1f
};

Çözüm

Bu öğreticide, Unity'de giderek daha az modern C# kodu yazmak için switch ifadesi, özellik deseni, tip deseni, sabit desen, ilişkisel desen ve mantıksal desenin nasıl kullanılacağını öğrendik.

Umarım, daha temiz kod yazarken kendinize zaman ayırmak için bir sonraki projenizde bunlardan bazılarını kullanabilirsiniz.

Daha temiz Unity kodu için 6 modern C# özelliği ilk olarak LogRocket Blog'da göründü.

etiketlerETİKETLER
Üzgünüm, bu içerik için hiç etiket bulunmuyor.

Sıradaki içerik:

Daha temiz Unity kodu için 6 modern C# özelliği