Unity’de .NET 4.x kullanma
Unity betiği oluşturmanın temel aldığı C# ve .NET, Microsoft'un 2002'de ilk yayımlanmalarından bu yana güncelleştirmeleri almaya devam etti. Ancak Unity geliştiricileri C# diline ve .NET Framework'e eklenen yeni özelliklerin sürekli akışının farkında olmayabilir, çünkü Unity 2017.1'den önce yıllardır eksik güncelleştirmeleri olan bir .NET 3.5 eşdeğeri betik çalışma zamanı kullanıyordu.
Unity 2017.1 sürümüyle, Unity betik çalışma zamanının deneysel bir sürümünü .NET 4.6, C# 6.0 uyumlu bir sürüme yükseltti. Unity 2018.1'de .NET 4.x eşdeğeri çalışma zamanı artık deneysel olarak kabul edilmezken, eski .NET 3.5 eşdeğer çalışma zamanı artık eski sürüm olarak kabul edilir. Unity 2018.3 sürümüyle, Unity yükseltilen betik çalışma zamanını varsayılan seçim yapmayı ve C# 7'ye daha da güncelleştirmeyi tahmin ediyor. Bu yol haritası hakkında daha fazla bilgi ve en son güncelleştirmeler için Unity'nin blog gönderisini okuyun veya Deneysel Betik Önizlemeleri forumunu ziyaret edin. Bu arada, .NET 4.x betik çalışma zamanıyla sunulan yeni özellikler hakkında daha fazla bilgi edinmek için aşağıdaki bölümlere göz atın.
Önkoşullar
- Unity 2022.2 veya üzeri (2022.1.7 önerilir)
- Visual Studio 2019
Unity'de .NET 4.x betik çalışma zamanını etkinleştirme
.NET 4.x betik çalışma zamanını etkinleştirmek için aşağıdaki adımları izleyin:
Unity Inspector'da Projeyi Düzenle > Ayarlar Player Diğer Ayarlar'ı seçerek Player > Ayarlar'ı > açın.
Yapılandırma başlığı altında Api uyumluluk Düzeyi açılan menüsüne tıklayın ve .NET Framework'i seçin. Unity'yi yeniden başlatmanız istenir.
.NET 4.x ve .NET Standard 2.1 profilleri arasında seçim
.NET 4.x eşdeğeri betik çalışma zamanına geçtikten sonra, Player Ayarlar (Project Ayarlar > Player'ı Düzenle>) açılır menüsünü kullanarak Api Uyumluluk Düzeyi'ni belirtebilirsiniz. İki seçenek vardır:
.NET Standard 2.1. Bu profil, .NET Foundation tarafından yayımlanan .NET Standard 2.1 profiliyle eşleşir. Unity, yeni projeler için .NET Standard 2.1'i önerir. Boyut kısıtlamalı platformlar için avantajlı olan .NET 4.x'ten daha küçüktür. Ayrıca Unity, Unity'nin desteklediği tüm platformlarda bu profili desteklemeyi taahhüt etmiştir.
.NET Framework. Bu profil en son .NET 4 API'sine erişim sağlar. .NET Framework sınıf kitaplıklarında bulunan tüm kodları içerir ve .NET Standard 2.1 profillerini de destekler. Projeniz .NET Standard 2.0 profiline dahil olmayan API'nin bir bölümünü gerektiriyorsa .NET 4.x profilini kullanın. Ancak bu API'nin bazı bölümleri Unity'nin tüm platformlarında desteklenmeyebilir.
Unity'nin blog gönderisinde bu seçenekler hakkında daha fazla bilgi edinebilirsiniz.
.NET 4.x Api Uyumluluk Düzeyi kullanılırken derleme başvuruları ekleme
Api Uyumluluk Düzeyi açılan listesinde .NET Standard 2.1 ayarı kullanılırken, API profilindeki tüm derlemelere başvurulur ve kullanılabilir. Ancak, daha büyük .NET 4.x profili kullanılırken Unity ile gönderilen derlemelerin bazılarına varsayılan olarak başvurulmuyor. Bu API'leri kullanmak için el ile bir derleme başvurusu eklemeniz gerekir. Unity'nin birlikte gönderebileceği derlemeleri Unity düzenleyici yüklemenizin MonoBleedingEdge/lib/mono dizininde görüntüleyebilirsiniz:
Örneğin, .NET 4.x profilini kullanıyor ve kullanmak HttpClient
istiyorsanız, System.Net.Http.dll için bir derleme başvurusu eklemeniz gerekir. Bu olmadan, derleyici bir derleme başvurusunun eksik olduğundan şikayet eder:
Visual Studio, Unity projeleri için her açıldığında .csproj ve .sln dosyalarını yeniden oluşturur. Sonuç olarak, projeyi yeniden açtıktan sonra kaybolacakları için derleme başvurularını doğrudan Visual Studio'ya ekleyemezsiniz. Bunun yerine, csc.rsp adlı özel bir metin dosyası kullanılmalıdır:
Unity projenizin kök Assets dizininde csc.rsp adlı yeni bir metin dosyası oluşturun.
Boş metin dosyasının ilk satırına şunu girin:
-r:System.Net.Http.dll
yazın ve dosyayı kaydedin. "System.Net.Http.dll" ifadesini, başvuru eksik olabilecek tüm derlemelerle değiştirebilirsiniz.Unity düzenleyicisini yeniden başlatın.
.NET uyumluluğundan yararlanma
.NET 4.x betik çalışma zamanı, yeni C# söz dizimi ve dil özelliklerine ek olarak Unity kullanıcılarına eski .NET 3.5 betik çalışma zamanıyla uyumsuz olan büyük bir .NET paketleri kitaplığına erişim sağlar.
NuGet'ten Unity projesine paket ekleme
NuGet , .NET için paket yöneticisidir. NuGet, Visual Studio ile tümleşiktir. Ancak Unity'de bir proje açtığınızda Visual Studio proje dosyaları yeniden oluşturularak gerekli yapılandırmaları geri aldığı için Unity projelerinin NuGet paketlerini eklemesi için özel bir işlem gerekir. NuGet'ten Unity projenize paket eklemek için:
Eklemek istediğiniz uyumlu bir paketi (.NET Standard 2.0 veya .NET 4.x) bulmak için NuGet'e göz atın. Bu örnek, .NET Standard 2.0 projesine JSON ile çalışmaya yönelik popüler bir paket olan Json.NET eklemeyi gösterir.
İndir düğmesine tıklayın:
İndirilen dosyayı bulun ve uzantıyı .nupkgolan .zip olarak değiştirin.
Zip dosyasının içinde lib/netstandard2.0 dizinine gidin ve Newtonsoft.Json.dll dosyasını kopyalayın.
Unity projenizin kök Varlıklar klasöründe Eklentiler adlı yeni bir klasör oluşturun. Eklentiler, Unity'de özel bir klasör adıdır. Daha fazla bilgi için Unity belgelerine bakın.
Newtonsoft.Json.dll dosyasını Unity projenizin Plugins dizinine yapıştırın.
Unity projenizin Assets dizininde link.xml adlı bir dosya oluşturun ve unity'nin bayt kodu çıkarma işleminin IL2CPP platformuna aktarırken gerekli verileri kaldırmadığından emin olarak aşağıdaki XML'yi ekleyin. Bu adım bu kitaplığa özgü olsa da, Düşünceler ion kullanan diğer kitaplıklarla ilgili sorunlarla benzer yollarla karşılaşabilirsiniz. Daha fazla bilgi için lütfen bu makaledeki Unity belgelerine bakın.
<linker> <assembly fullname="System.Core"> <type fullname="System.Linq.Expressions.Interpreter.LightLambda" preserve="all" /> </assembly> </linker>
Her şey yerine yerleştirdiğinizde artık Json.NET paketini kullanabilirsiniz.
using Newtonsoft.Json;
using UnityEngine;
public class JSONTest : MonoBehaviour
{
class Enemy
{
public string Name { get; set; }
public int AttackDamage { get; set; }
public int MaxHealth { get; set; }
}
private void Start()
{
string json = @"{
'Name': 'Ninja',
'AttackDamage': '40'
}";
var enemy = JsonConvert.DeserializeObject<Enemy>(json);
Debug.Log($"{enemy.Name} deals {enemy.AttackDamage} damage.");
// Output:
// Ninja deals 40 damage.
}
}
Bu, bağımlılıkları olmayan bir kitaplığı kullanmanın basit bir örneğidir. NuGet paketleri diğer NuGet paketlerine bağlı olduğunda, bu bağımlılıkları el ile indirmeniz ve aynı şekilde projeye eklemeniz gerekir.
Yeni söz dizimi ve dil özellikleri
Güncelleştirilmiş betik çalışma zamanını kullanmak, Unity geliştiricilerine C# 8'e ve bir dizi yeni dil özelliğine ve söz dizimine erişim sağlar.
Otomatik özellik başlatıcıları
Unity'nin .NET 3.5 betik çalışma zamanında, otomatik özellik söz dizimi başlatılmamış özellikleri hızla tanımlamayı kolaylaştırır, ancak başlatma betiğinizin başka bir yerinde gerçekleşmektedir. Artık .NET 4.x çalışma zamanıyla, otomatik özellikleri aynı satırda başlatmak mümkündür:
// .NET 3.5
public int Health { get; set; } // Health has to be initialized somewhere else, like Start()
// .NET 4.x
public int Health { get; set; } = 100;
Dize ilişkilendirme
Eski .NET 3.5 çalışma zamanıyla, dize birleştirmenin uygunsuz söz dizimi gerekiyordu. Artık .NET 4.x çalışma zamanı ile dize ilişkilendirme özelliği, $
ifadelerin dizelere daha doğrudan ve okunabilir bir söz dizimiyle eklenmesini sağlar:
// .NET 3.5
Debug.Log(String.Format("Player health: {0}", Health)); // or
Debug.Log("Player health: " + Health);
// .NET 4.x
Debug.Log($"Player health: {Health}");
İfade gövdeli üyeler
.NET 4.x çalışma zamanında daha yeni C# söz dizimiyle lambda ifadeleri işlevlerin gövdesini değiştirerek daha kısa olmasını sağlayabilir:
// .NET 3.5
private int TakeDamage(int amount)
{
return Health -= amount;
}
// .NET 4.x
private int TakeDamage(int amount) => Health -= amount;
Salt okunur özelliklerde ifade gövdeli üyeleri de kullanabilirsiniz:
// .NET 4.x
public string PlayerHealthUiText => $"Player health: {Health}";
Görev Tabanlı Zaman Uyumsuz Desen (TAP)
Zaman uyumsuz programlama , uygulamanızın yanıt vermemeye başlamasına neden olmadan zaman alan işlemlerin gerçekleştirilmesini sağlar. Bu işlevsellik, kodunuzun bu işlemlerin sonuçlarına bağlı koda devam etmeden önce zaman alan işlemlerin bitmesini beklemesini de sağlar. Örneğin, bir dosyanın yüklenmesini veya ağ işleminin tamamlanmasını bekleyebilirsiniz.
Unity'de zaman uyumsuz programlama genellikle eş yordamlarla gerçekleştirilir. Ancak C# 5'ten bu yana, .NET geliştirmesinde tercih edilen zaman uyumsuz programlama yöntemi, System.Threading.Task ile ve await
anahtar sözcüklerini kullanan async
Görev Tabanlı Zaman Uyumsuz Desen (TAP) olmuştur. Özetle, bir async
işlevde, uygulamanızın geri kalanının güncelleştirilmesini engellemeden bir görevin tamamlanmasını sağlayabilirsiniz await
:
// Unity coroutine
using UnityEngine;
public class UnityCoroutineExample : MonoBehaviour
{
private void Start()
{
StartCoroutine(WaitOneSecond());
DoMoreStuff(); // This executes without waiting for WaitOneSecond
}
private IEnumerator WaitOneSecond()
{
yield return new WaitForSeconds(1.0f);
Debug.Log("Finished waiting.");
}
}
// .NET 4.x async-await
using UnityEngine;
using System.Threading.Tasks;
public class AsyncAwaitExample : MonoBehaviour
{
private async void Start()
{
Debug.Log("Wait.");
await WaitOneSecondAsync();
DoMoreStuff(); // Will not execute until WaitOneSecond has completed
}
private async Task WaitOneSecondAsync()
{
await Task.Delay(TimeSpan.FromSeconds(1));
Debug.Log("Finished waiting.");
}
}
TAP karmaşık bir konudur ve Unity'ye özgü nüanslar geliştiricilerin dikkate alması gerekir. Sonuç olarak TAP, Unity'deki eş yordamlar için evrensel bir değişim değildir; ancak bu, kullanılacak başka bir araçtır. Bu özelliğin kapsamı bu makalenin dışındadır, ancak aşağıda bazı genel en iyi yöntemler ve ipuçları verilmiştir.
Unity ile TAP için başlangıç başvurusu
Bu ipuçları Unity'de TAP ile çalışmaya başlamanıza yardımcı olabilir:
- Beklenmesi amaçlanan zaman uyumsuz işlevlerin dönüş türü
Task
veyaTask<TResult>
olmalıdır. - Görev döndüren zaman uyumsuz işlevlerin adlarının sonuna "Async" soneki eklenmelidir. "Zaman uyumsuz" soneki, bir işlevin her zaman beklenmesi gerektiğini belirtmeye yardımcı olur.
- Yalnızca geleneksel zaman uyumlu koddan zaman uyumsuz işlevleri tetikleyen işlevler için dönüş türünü kullanın
async void
. Bu tür işlevler kendileri beklenemez ve adlarında "Zaman Uyumsuz" soneki olmamalıdır. - Unity, zaman uyumsuz işlevlerin varsayılan olarak ana iş parçacığında çalıştığından emin olmak için UnitySynchronizationContext kullanır. Unity API'sine ana iş parçacığı dışından erişilemez.
- ve
Task.ConfigureAwait(false)
gibiTask.Run
yöntemlerle arka plan iş parçacıklarında görevler çalıştırabilirsiniz. Bu teknik, performansı artırmak için ana iş parçacığından pahalı işlemleri boşaltmak için kullanışlıdır. Ancak, arka plan iş parçacıklarını kullanmak, yarış koşulları gibi hata ayıklaması zor sorunlara yol açabilir. - Unity API'sine ana iş parçacığı dışından erişilemez.
- İş parçacıklarını kullanan görevler Unity WebGL derlemelerinde desteklenmez.
Eş yordamlar ve TAP arasındaki farklar
Eş yordamlar ile TAP / async-await arasında bazı önemli farklar vardır:
- Coroutine'ler değer döndüremez, ancak
Task<TResult>
döndürebilir. - Try-catch deyimini koyamazsınız
yield
ve bu da coroutines ile hataların işlenmesini zorlaştırır. Ancak, try-catch TAP ile çalışır. - Unity'nin eş yordam özelliği MonoBehaviour'dan türetilmez sınıflarda kullanılamaz. TAP, bu tür sınıflarda zaman uyumsuz programlama için mükemmeldir.
- Bu noktada Unity, tap'i eş yordamların toptan değişimi olarak önermez. Profil oluşturma, belirli bir proje için bir yaklaşımın ve diğerinin belirli sonuçlarını bilmenin tek yoludur.
nameof işleci
nameof
işleci bir değişkenin, türün veya üyenin dize adını alır. Bazı durumlarda nameof
hatalar günlüğe kaydedilir ve bir sabit listesi dize adı alınıyor:
// Get the string name of an enum:
enum Difficulty {Easy, Medium, Hard};
private void Start()
{
Debug.Log(nameof(Difficulty.Easy));
RecordHighScore("John");
// Output:
// Easy
// playerName
}
// Validate parameter:
private void RecordHighScore(string playerName)
{
Debug.Log(nameof(playerName));
if (playerName == null) throw new ArgumentNullException(nameof(playerName));
}
Arayan bilgisi öznitelikleri
Arayan bilgisi öznitelikleri , bir yöntemin çağıranı hakkında bilgi sağlar. Arayan Bilgisi özniteliğiyle kullanmak istediğiniz her parametre için varsayılan bir değer sağlamanız gerekir:
private void Start ()
{
ShowCallerInfo("Something happened.");
}
public void ShowCallerInfo(string message,
[System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
Debug.Log($"message: {message}");
Debug.Log($"member name: {memberName}");
Debug.Log($"source file path: {sourceFilePath}");
Debug.Log($"source line number: {sourceLineNumber}");
}
// Output:
// Something happened
// member name: Start
// source file path: D:\Documents\unity-scripting-upgrade\Unity Project\Assets\CallerInfoTest.cs
// source line number: 10
Statik kullanma
Statik kullanmak, sınıf adını yazmadan statik işlevleri kullanmanıza olanak tanır. Statik kullanarak, aynı sınıftan birkaç statik işlev kullanmanız gerekiyorsa alandan ve zamandan tasarruf edebilirsiniz:
// .NET 3.5
using UnityEngine;
public class Example : MonoBehaviour
{
private void Start ()
{
Debug.Log(Mathf.RoundToInt(Mathf.PI));
// Output:
// 3
}
}
// .NET 4.x
using UnityEngine;
using static UnityEngine.Mathf;
public class UsingStaticExample: MonoBehaviour
{
private void Start ()
{
Debug.Log(RoundToInt(PI));
// Output:
// 3
}
}
IL2CPP Ile İlgili Dikkat Edilmesi Gerekenler
Oyununuzu iOS gibi platformlara aktarırken Unity, IL2CPP altyapısını kullanarak IL'yi hedef platformun yerel derleyicisi kullanılarak derlenen C++ koduna "dönüştürme" yapacaktır. Bu senaryoda, Düşünceler ion bölümleri ve anahtar sözcüğün kullanımı gibi desteklenmeyen dynamic
birkaç .NET özelliği vardır. Bu özellikleri kendi kodunuzda kullanmayı denetleyebilirsiniz ancak Unity ve IL2CPP göz önünde bulundurularak yazılmamış üçüncü taraf DLL'leri ve SDK'ları kullanırken sorunlarla karşılaşabilirsiniz. Bu makale hakkında daha fazla bilgi için Unity'nin sitesindeki Betik Kısıtlamaları belgelerine bakın.
Ayrıca, yukarıdaki Json.NET örnekte belirtildiği gibi Unity, IL2CPP dışarı aktarma işlemi sırasında kullanılmayan kodu çıkarma girişiminde bulunur. Bu işlem genellikle bir sorun olmasa da, Düşünceler kullanan kitaplıklarda, çalışma zamanında çağrılan ve dışarı aktarma zamanında belirlenmeyecek özellikleri veya yöntemleri yanlışlıkla çıkarabilir. Bu sorunları çözmek için, çıkarma işleminin çalıştırılmaması için projenize derlemelerin ve ad alanlarının listesini içeren bir link.xml dosyası ekleyin. Daha fazla bilgi için bkz . Unity'nin bytecode striping belgeleri.
.NET 4.x Örnek Unity Projesi
Örnek, çeşitli .NET 4.x özelliklerine örnekler içerir. Projeyi indirebilir veya kaynak kodunu GitHub'da görüntüleyebilirsiniz.