Unity und .NET, was kommt als Nächstes?

ALEXANDRE MUTEL / UNITY TECHNOLOGIESContributor
May 18, 2022|15 Min.
Unity und .NET, was kommt als Nächstes?
Diese Website wurde aus praktischen Gründen für Sie maschinell übersetzt. Die Richtigkeit und Zuverlässigkeit des übersetzten Inhalts kann von uns nicht gewährleistet werden. Sollten Sie Zweifel an der Richtigkeit des übersetzten Inhalts haben, schauen Sie sich bitte die offizielle englische Version der Website an.

Wir haben vor Kurzem eine mehrjährige Initiative gestartet, die Ihnen dabei helfen soll, leistungsfähigeren Code schneller zu schreiben und langfristige Stabilität und Kompatibilität zu gewährleisten. Lesen Sie weiter, um herauszufinden, was wir tun, um die grundlegende Technologieinfrastruktur Ihrer Skripte zu aktualisieren.

Das .NET-Ökosystem entwickelt sich dynamisch und auf vielfältige Weise vorteilhaft weiter, und wir möchten Ihnen diese Verbesserungen so schnell wie möglich zugänglich machen. Unsere interne .NET Tech Group arbeitet an der kontinuierlichen Verbesserung unserer .NET-Integration, einschließlich neuerer C#-Funktionen und .NET Standard 2.1 . Aber wir haben kürzlich, basierend auf Ihrem Feedback, noch einmal einen Gang höher geschaltet, um Ihr Entwicklererlebnis insgesamt zu verbessern.

Dieser Blogbeitrag stellt die Themen vor, an denen wir arbeiten. Wir haben dieses Thema auch auf dem Unity Dev Summit im Rahmen der GDC 2022 besprochen. Die vollständige Sitzung können Sie hier ansehen.

Die Entwicklung von .NET und Unity

Die Geschichte beginnt vor 17 Jahren, als unser CTO damit begann, die Mono .NET-Laufzeitumgebung mit C# zu nutzen. Unity bevorzugte C# aufgrund seiner Einfachheit, kombiniert mit einem JIT-Compiler (Just-in-Time), der Ihren C#-Code in relativ effizienten nativen Code übersetzt. Die übrigen und wesentlich größeren Teile der Unity -Engine wurden in C++ entwickelt, um eine ausgewogene und kontrollierte Performance zu gewährleisten.

Viele Jahre lang lief Unity mit einer speziellen Abspaltung der Mono .NET-Laufzeitumgebung und der Programmiersprache C# (2.0). In dieser Zeit haben wir die Unterstützung für weitere Plattformen hinzugefügt. Wir haben außerdem unseren eigenen Compiler und unsere eigene Laufzeitumgebung, IL2CPP, entwickelt, um Ihnen die Möglichkeit zu geben, iOS und einige Konsolenplattformen als Zielplattformen zu nutzen.

In der Zwischenzeit hat sich das gesamte Microsoft .NET-Ökosystem weiterentwickelt, mit neuen Lizenzierungsmodellen und Unterstützung für Nicht-Windows-Plattformen. Diese Entwicklung hat es uns ermöglicht, die Unity .NET Mono Runtime im Jahr 2018 zu aktualisieren und modernere C#-Sprachversionen (7.0+) zu integrieren. Im selben Jahr veröffentlichten wir auch die erste Version des Burst -Compilers, der als erster schnellen nativen Code für eine Teilmenge der C#-Sprache generierte. Dieser Durchbruch ermöglichte es Unity , sich eine Welt vorzustellen, in der wir die Verwendung von C# in den anderen kritischen Segmenten der Engine ausweiten könnten, ohne diese Teile in C++ entwickeln zu müssen, was zur Entwicklung der DOTS-Laufzeitumgebung führte.

Unity 2020 LTS und Unity 2021 LTS brachten neuere C#-Sprachversionen und neue .NET-APIs. Parallel dazu haben wir enorme Leistungsverbesserungen im .NET-Ökosystem sowie eine benutzerfreundlichere Entwicklungsumgebung durch die Einführung des SDK-Stils csproj und das florierende NuGet-Ökosystem erlebt.

Was wir tun müssen

Als Ergebnis dieser langen Entwicklung umfasst die Unity -Plattform eine sehr große C++-Codebasis, die direkt mit .NET-Objekten interagiert und dabei spezifische Annahmen verwendet, die von der Mono .NET Runtime übernommen wurden. Diese sind für die .NET (Core) Runtime nicht mehr gültig oder effizient.

Darüber hinaus gibt es eine komplizierte, benutzerdefinierte Kompilierungspipeline, die an den Unity Editor gebunden ist und nicht auf MSBuild basiert, wodurch sie nicht ohne Weiteres von allen Standardfunktionen profitieren kann.

Wir haben in den letzten Jahren auch mit vielen von Ihnen gesprochen, sowohl in Interviews als auch im Unity Forum , um herauszufinden, was wir verbessern können, um Ihren Erfolg besser zu ermöglichen. Wir haben gehört, dass Sie die neueste C#-Sprache, die .NET-Laufzeitumgebung und C#-Code von Drittanbietern über NuGet verwenden möchten. Wenn es um die Nutzung der Unity -Plattform geht, haben Sie uns mitgeteilt, dass Sie mit hochwertigen C#-Test-, Debugging- und Profiling-Tools sowie einer guten Integration zwischen der Standard-.NET API und der Unity API das Maximum aus der Zielhardware herausholen möchten. Als C# Unity Programmierer wünschen Sie sich Unity Tools, die nahtlos mit Ihren übrigen Werkzeugen zusammenarbeiten und schnelle Iterationen ermöglichen, damit Sie eine erstklassige Laufzeitleistung erzielen können.

Bis wir dorthin gelangen, werden wir mehrere Jahre brauchen. Wir halten Sie mit regelmäßigen Blog- und Forum-Updates über die technischen Herausforderungen, denen wir dabei begegnen, auf dem Laufenden.

Wie wir das machen werden

Unser erster Schritt bei dieser Initiative war es, uns mit allen internen Mitarbeitern, die sich für C# und .NET in Unity begeistern, zusammenzusetzen, um eine C#/.NET Tech Group zu gründen, die dieses Vorhaben vorantreiben sollte.

Wir möchten auf dem .NET-Ökosystem aufbauen, anstatt individuelle Lösungen zu entwickeln. Um Ihnen die Nutzung der Leistungs- und Produktivitätsverbesserungen zu ermöglichen, die mit dem neuesten .NET SDK/Runtime und MSBuild einhergehen, möchten wir von der Mono .NET Runtime auf CoreCLR, die moderne .NET (Core) Runtime, migrieren.

Diese Initiative bietet Ihnen auch Innovationen jenseits des bestehenden .NET-Universums mit dem Ziel, schnellere .NET-Iterationszyklen für Ihre C#-Skripte zu ermöglichen. Wir werden daran arbeiten, die JIT- und AOT-Lösungen (Ahead-of-Time) – IL2CPP und Burst – zusammenzuführen, um das beste Gleichgewicht zwischen Kompilierzeiteffizienz und Codegenerierungsqualität zu erreichen.

Extern arbeiten wir mit Partnern aus der Branche wie Microsoft und JetBrains zusammen, um sicherzustellen, dass Unity Entwickler die neueste .NET-Technologie nutzen. Wir verstärken auch unsere Beteiligung an Open-Source-Communities. Wir werden dieses Vorhaben in mehrere Schritte unterteilen. Mal sehen, was als Nächstes kommt.

Woran wir im Jahr 2022 arbeiten

In diesem Jahr planen die Teams, an folgenden Strecken zu arbeiten.

Eine Infografik zu den Säulen der Unity -Entwicklererfahrung
C#-Entwicklungsworkflow

Die Iterationszeit bleibt unsere oberste Priorität, denn wir wissen, dass Sie Ihre Zeit optimal nutzen möchten. Hier sind ein paar Beispiele dafür, was wir tun, um dies zu verbessern.

  • Im Rahmen der Kompilierungspipeline verbessern wir die Zeit, die für die IL-Nachbearbeitung benötigt wird, welche für die Modifizierung der kompilierten .NET-Assemblys zuständig ist, nachdem Ihr C#-Code kompiliert wurde. Wir verwenden jetzt einen persistenten Prozess, um die IL-Nachbearbeitung nach der Kompilierungsphase auszuführen, und dadurch können einige hundert Millisekunden eingespart werden.
  • Da der Burst Compiler immer häufiger zum Einsatz kommt, verbessern wir die Granularität der Erkennung von Codeänderungen mithilfe eines transitiven Hash-Algorithmus. Dadurch können wir feststellen, welchen Bursttable-Code wir schneller kompilieren müssen. Wir arbeiten daran, den Burst -Compiler aus dem Hauptprozess auszulagern, damit er Ihren Code dank der Ausführung in einer separaten .NET 6.0-Executable schneller kompilieren kann.
  • Wir verbessern außerdem das Neuladen der Domäne, indem wir die im Hintergrund erstellten Reflektionsdaten optimieren, sobald der Typcache verwendet wird.
  • Wir werden Tests und Validierungen hinzufügen, um die Iterationszeit-Regression für Pakete und Projektvorlagen besser nachverfolgen zu können.

Für die Migration zu MSBuild besteht der erste Schritt darin, unsere Kompilierungspipeline vom Unity Editor zu entkoppeln und in einen separaten Prozess zu verschieben. Dies ist ein kompliziertes Unterfangen, da wir jahrelang gewachsenen Altcode mit Tausenden von Zeilen C++- und C#-Code entwirren müssen, um dies zu erreichen – und gleichzeitig die Abwärtskompatibilität zu wahren. Sie werden aus Ihrer Sicht keine Änderungen bemerken, aber es wird uns den Weg zu MSBuild ebnen und die Wartung vereinfachen.

Wir werden auch das C#-IDE-Debugging-Erlebnis mit Burst verbessern, indem wir einen Modus einführen, der den Debugger automatisch auf verwaltetes Debugging umschaltet, wenn ein Haltepunkt auf einem mit Burst ausgeführten Codepfad gesetzt wird. Das bedeutet, dass Sie das Attribut [BurstCompile] im zu debuggenden Codepfad nicht manuell entfernen müssen.

Modernisierung der .NET-Laufzeitumgebung

Die Arbeiten zur Migration auf die .NET CoreCLR-Laufzeitumgebung haben bereits begonnen und stellen eine sehr anspruchsvolle Aufgabe dar. Um diese Migration erfolgreich durchzuführen, möchten wir das Problem schrittweise angehen und sicherstellen, dass wir einzelne Teile so veröffentlichen können, dass die Stabilität bestehender Unity -Projekte erhalten bleibt.

Wir planen daher, diese Migration in mehreren Phasen durchzuführen:

  • Zunächst werden wir die Unterstützung von .NET CoreCLR für eigenständige Player auf Desktop- Plattformen bereitstellen. Sie können diese Laufzeitumgebung in Ihren Player-Einstellungen neben dem bestehenden Mono und IL2CPP-Backend auswählen. Diese erste Phase sollte uns helfen, den Kernteil der Unity Engine (der wesentlich kleiner ist als der Editor-Teil) zu migrieren und hoffentlich einen Großteil der technischen Herausforderungen dieser Migration zu lösen. Sie werden weiterhin über die .NET Standard 2.1 API auf die .NET-Laufzeitumgebung zugreifen, und wir planen, diese neue Laufzeitumgebung im Laufe des Jahres 2023 zu veröffentlichen.
  • Zweitens werden wir den Unity Editor auf .NET CoreCLR portieren und gleichzeitig die Unterstützung für die .NET Mono -Laufzeitumgebung entfernen. In dieser zweiten Phase geht es darum, wie wir Ihre Skripte im Editor neu laden können, ohne AppDomains zu verwenden, und den Wechsel zu .NET CoreCLR abzuschließen. Dazu gehört auch ein Upgrade von IL2CPP, um die Basisklassenbibliotheken aus dem Repository dotnet/runtime zu unterstützen. Sie erhalten endlich Zugriff auf die vollständige .NET 7.x oder 8.0 API. Wir hoffen, diesen neuen Editor im Laufe des Jahres 2024 veröffentlichen zu können.
Modernisierung der Unity -Laufzeitumgebung

Die Unterstützung von .NET Standard 2.1 in Unity 2021 LTS ermöglicht es uns, die Unity Laufzeitumgebung auf verschiedene Weise zu modernisieren. Wir arbeiten aktuell an zwei Verbesserungen.

Verbesserung des async/await-Programmiermodells . Async/await ist ein grundlegender Programmieransatz für das Schreiben von Gameplay-Code, der auf den Abschluss einer asynchronen Operation warten muss, ohne die Hauptschleife der Engine zu blockieren.

Im Jahr 2011, bevor async/await in .NET zum Standard wurde, führte Unity asynchrone Operationen mit iteratorbasierten Coroutinen ein, aber dieser Ansatz ist mit async/await inkompatibel und kann weniger effizient sein. In der Zwischenzeit wurde mit .NET Standard 2.1 die Unterstützung von async/await in C# und .NET verbessert, indem eine effizientere Handhabung von async/await-Operationen über ValueTask eingeführt und ein eigenes taskähnliches System über AsyncMethodBuilder ermöglicht wurde.

Wir können diese Verbesserungen nun nutzen und arbeiten daher daran, die Verwendung von async/await mit bestehenden asynchronen Operationen in Unity zu ermöglichen (z. B. Warten auf den nächsten Frame oder Warten auf den Abschluss einer UnityWebRequest). Als ersten Schritt verbessern wir die Unterstützung für das Abbrechen ausstehender asynchroner Aufgaben beim Zerstören eines MonoBehavior oder beim Verlassen des Wiedergabemodus mithilfe von Abbruchtoken . Wir arbeiten außerdem eng mit unseren wichtigsten Community-Mitwirkenden zusammen, beispielsweise mit dem Autor von UniTask , um sicherzustellen, dass sie diese neuen Funktionen nutzen können.

Reduzierung von Speicherzuweisungen und Kopien durch Nutzung von Span. Da Unity eine C++-Engine mit einer C#-Skriptschicht ist, findet ein reger Datenaustausch zwischen den beiden statt. Dies kann ineffizient sein, da häufig entweder Daten hin und her kopiert oder neue verwaltete Objekte zugewiesen werden müssen.

Span wurde in C# 7.2 eingeführt, um solche Szenarien zu verbessern, und ist in .NET Standard 2.1 standardmäßig verfügbar. In den letzten Jahren haben Sie vielleicht von den vielen bedeutenden Leistungsverbesserungen gehört oder gelesen, die dank Span an der .NET-Laufzeitumgebung erzielt wurden (siehe Details zu den Verbesserungen in .NET Core 2.1 , .NET Core 3.0 , .NET 6 , .NET 6 ). Wir möchten die Verwendung dieser Funktion in Unity nutzen, da dies dazu beiträgt, Speicherzuweisungen und folglich Garbage-Collection-Pausen zu reduzieren und gleichzeitig die Gesamtleistung vieler APIs zu verbessern.

Begleiten Sie uns auf dieser Reise

Wir hoffen, dass Sie genauso begeistert von diesen Änderungen und Funktionen sind wie wir.

Teilt uns eure Meinung zu unseren Plänen im Forum mit. Wir werden auch den Engineering-Bereich der Unity Platform Roadmap regelmäßig aktualisieren, und Sie können uns dort Ihre Funktionswünsche und Priorisierungsvorschläge mitteilen.

Anmerkung der Redaktion: Dieser Artikel wurde zuletzt im Februar 2023 aktualisiert.