Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

.Net 5 support

Discussion in 'Experimental Scripting Previews' started by Lymdun, Mar 3, 2020.

  1. Digika

    Digika

    Joined:
    Jan 7, 2018
    Posts:
    225
    How would that work when using standard net api that accepts span<T>?
     
    jGate99 likes this.
  2. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    Hmm I was wrong, it can be done as follows:

    Code (CSharp):
    1. Span<byte> bytes;
    2. unsafe
    3. {  
    4.     byte* tmp = stackalloc byte[length];  
    5.     bytes = new Span<byte>(tmp, length);
    6. }
     
  3. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    265
    This is a C# 7.2 feature, not C# 8. It just compiles down to a regular stackalloc which gets passed into the Span<T>(void *, int) constructor, so it works fine with the System.Memory package. C# 8 further expanded stackalloc to allow it to be used as an expression (which always returns a span).

    The System.Memory package implements what's referred to as "slow span", which looks something like this:
    Code (CSharp):
    1. readonly ref struct Span<T>
    2. {
    3.     readonly Pinnable<T> pinnable;
    4.     readonly IntPtr byteOffset;
    5.     readonly int length;
    6. }
    This allows it to function perfectly fine without explicit runtime support (so it also works fine in Unity), at the expense of performance (and the ability to store a GC-tracked "ref").
     
    Last edited: Sep 29, 2020
  4. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    Well then that's even worse and C# 7 isn't fully added to Unity. As I said missing packages that contain Span, ValueTask etc makes these features unsupported in Unity, right @JoshPeterson ? By unsupported I mean that any found bugs will be marked as postponed, by design etc.
     
    TheZombieKiller likes this.
  5. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    265
    Yeah, in a way. It's similar to how C# 8 technically isn't fully supported because we don't have the runtime changes needed for default interface implementations.
     
  6. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,936
    Right, Unity has full C# 7 language support, but we don't have the base class library types that you mentioned.
     
  7. runner78

    runner78

    Joined:
    Mar 14, 2015
    Posts:
    792
    Span<T> is only a new Library Feature, not defined by the language. Default interface implementations is an language and runtime feature.
     
  8. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    265
    Span<T> is present in the C# specs and there's specific language support for stackalloc (among a few other things), which makes it part of the language as well.
     
  9. VolodymyrBS

    VolodymyrBS

    Joined:
    May 15, 2019
    Posts:
    150
    Yes, C# 7.2 has a special case for Span<T>. But Span<T> is not included in .NET Standard 2.0 or any of .NET Framework versions. This is probably the first and last example when a new language version feature requires new type but the type is not included in the target framework.

    All .NET Frameworks, .NET Standard 1.x, .NET Standard 2.0 and .NET Core 2.x use C# 7.3 as default language version. But only NET Core 2.1 and 2.2 have Span<T> included. All others require nuget package.

    Similarly Unity require Span<T> from somewhere outside because it's support level is .NET Standard 2.0 or .NET Frameworks 4.x
     
    TheZombieKiller likes this.
  10. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    NET Core 2.1+, NET Standard 2.1 and NET 5.0.

    Seems like fast span was added to mono https://github.com/mono/mono/issues/7249 in 2018

    #edit
    Oh I've missed this one:
     
  11. VolodymyrBS

    VolodymyrBS

    Joined:
    May 15, 2019
    Posts:
    150
    I count only Target framework that use C#7.3 by default and have Span<T>
     
  12. Digika

    Digika

    Joined:
    Jan 7, 2018
    Posts:
    225
    I' not sure why are you quoting me here and in what way your response is relevant. If I wanted to go unsafe and into pointer madness I always could do that directly since early C#. The whole idea of span is that it was a fairly convenient, surprisingly good and low-overhead abstraction.
     
  13. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    Have you read what you asked?
    As
    Span<byte> bytes = stackalloc byte[]; 
    is C# 7.2 feature not C# 8, you send Span directly to the api, not sure what you asked about.
     
    Last edited: Sep 30, 2020
  14. Digika

    Digika

    Joined:
    Jan 7, 2018
    Posts:
    225
    Have you? Let's see:

    Where did I say otherwise? Where did I even talk about it?

    It does not work out of the box, as Baste said:
    To which I've asked:
    and your response:
    What unsafe context and pointers have ANYTHING to do with built in core .NET 5/Core libraries native Span abstraction implementation with stackalloc?
     
    Last edited: Sep 30, 2020
  15. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    265
    On another note, I think it's useful to mention that the default implementations of Stream.Read(Span<byte>) and Stream.Write(ReadOnlySpan<byte>) use ArrayPool and then call the regular managed array implementations. So even without .NET Standard 2.1 you can take advantage of them using extension methods:
    Code (CSharp):
    1. using System;
    2. using System.IO;
    3. using System.Buffers;
    4.  
    5. // Based on https://source.dot.net/#System.Private.CoreLib/Stream.cs
    6. public static class SpanStreamExtensions
    7. {
    8.     public static int Read(this Stream @this, Span<byte> buffer)
    9.     {
    10.         byte[] sharedBuffer = ArrayPool<byte>.Shared.Rent(buffer.Length);
    11.  
    12.         try
    13.         {
    14.             int numRead = @this.Read(sharedBuffer, 0, buffer.Length);
    15.  
    16.             if ((uint)numRead > (uint)buffer.Length)
    17.                 throw new IOException("Stream was too long.");
    18.  
    19.             new Span<byte>(sharedBuffer, 0, numRead).CopyTo(buffer);
    20.             return numRead;
    21.         }
    22.         finally
    23.         {
    24.             ArrayPool<byte>.Shared.Return(sharedBuffer);
    25.         }
    26.     }
    27.  
    28.     public static void Write(this Stream @this, ReadOnlySpan<byte> buffer)
    29.     {
    30.         byte[] sharedBuffer = ArrayPool<byte>.Shared.Rent(buffer.Length);
    31.  
    32.         try
    33.         {
    34.             buffer.CopyTo(sharedBuffer);
    35.             @this.Write(sharedBuffer, 0, buffer.Length);
    36.         }
    37.         finally
    38.         {
    39.             ArrayPool<byte>.Shared.Return(sharedBuffer);
    40.         }
    41.     }
    42. }
    You can't override these methods like you can with the real ones since they're extensions, but it's nice to be able to at least make use of them.
     
    Kamyker likes this.
  16. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    I'm done, you clearly don't know how to ask a question.
     
  17. Sunkin351

    Sunkin351

    Joined:
    Oct 1, 2020
    Posts:
    1
    I'd just like to point out that a solution to bring .NET 5 C# to Unreal Engine exists in the form of a plugin.
    https://github.com/nxrighthere/UnrealCLR
    I'm looking into using it right now to see if it's usable, but first impressions look promising.
    All in all, Unity is running far behind, but I don't think I need to tell you that. ^_^
     
    Andresmonte and nxrighthere like this.
  18. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    265
    You could theoretically do something similar to that in Unity by P/Invoking nethost/hostfxr, but I'd much rather have native support.

    On that note, I wonder how feasible it'd be to have an open source Mono wrapper around .NET Core similar to what xoofx did here: https://xoofx.com/blog/2018/04/06/porting-unity-to-coreclr/

    Unity's fork of Mono is open source, so if they've made any changes to existing APIs (or added new ones) then the details are known.
     
    JaredThirsk likes this.
  19. MagdielM

    MagdielM

    Joined:
    May 27, 2020
    Posts:
    32
    @JoshPeterson couldn't help but raise an eyebrow at this:
    What exactly is keeping Unity from implementing breaking changes to the ecosystem? The primary reason that comes to my mind would be maintaining compatibility with in-production projects, but this is what long-term support releases are for, no? To my understanding, migrating projects across TECH cycles is generally discouraged, so why should developers expect their current projects to port smoothly from, say, 2020.3 LTS to 2021.1?

    The only other reason I can think of is stopping breaking changes from happening to the engine itself and having to fix those in time for the next TECH cycle, but surely the team can plan more than one year ahead, right?

    It just feels like Unity is trying to revamp and modernize very quickly while also treading as lightly as it can. The way I see it, these two goals are diametrically opposed.
     
    NotaNaN, Cardinal90 and bdovaz like this.
  20. Digika

    Digika

    Joined:
    Jan 7, 2018
    Posts:
    225
    May be they plan to move away from c# and mono/.net in future so that's why they dont want to bother?
     
  21. JoNax97

    JoNax97

    Joined:
    Feb 4, 2016
    Posts:
    611
    No way they will do that. They removed unityscript to focus in C#, ditched the mono compiler in favor of Roslyn, and have designed Burst around making C# more performant.
    There's no reason for them to suddenly abandon this path
     
  22. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    they abandone .Net Core in favor of .Net 5
     
  23. JoNax97

    JoNax97

    Joined:
    Feb 4, 2016
    Posts:
    611
    .NET 5 is an evolution of .NET Core, it's not like thy would suddenly drop everything and rewrite the engine in ruby or something.
     
  24. jiraphatK

    jiraphatK

    Joined:
    Sep 29, 2018
    Posts:
    300
    Guys, follow unity devs' twitter to get more info about this directly. There is an interesting discussion about this particular subject last week.
     
  25. runner78

    runner78

    Joined:
    Mar 14, 2015
    Posts:
    792
    Projects in production, Long Term Projects (KSP startet with Unity3.x, currently at 2019.2). Internal Unity code/packages. Asset store...
     
  26. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,936
    There are many users with projects in various states of production in various Unity versions, both tech stream and LTS. We've made the choice to be very careful about breaking those projects with .NET base class library changes.

    For example, any assemblies compiled using a .NET Framework ecosystem (e.g. mscorlib.dll) will need to be recompiled against a .NET Core/.NET 5 ecosystem (e.g. System.Runtime.dll). For many projects, this is a costly process! We're sensitive to that fact, and we are willing to move slower than we possibly could to ensure that users are not required to make changes like this until we have a full solution they can migrate to. So in some sense, this compatibility story is slowing down movement to .NET Core/.NET 5. But it is a conscious decision we've made to maintain stability. We feel that stability of the .NET base class libraries allows our users to move faster, as they don't have to pay the cost to upgrade.

    With that said, we are definitely sticking with C# and .NET. We are moving to the new .NET Core ecosystem, but I don't have an ETA for a release date yet.
     
    NotaNaN, AliAlbarrak and YourWaifu like this.
  27. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    What about NET Standard 2.0 assemblies - are they compatible with NET 5? If they are then everyone should be aware of it as early as possible. Let everyone know to target NET Standard and if not possible prepare to recompile them for NET 5 in the future.

    Would be interesting to see how many Asset Store assemblies target Net Framework - I guess this information should be clearly visible for every asset in the future to know if they're Net 5 compatible.
     
  28. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,936
    Yes, they are! Indeed, this has been our guidance - to target .NET Standard 2.0 where possible, as that provides the most flexibility in the future.

    I really like this idea. Is it certainly something we can do to get a sense about how many projects might be broken by a change to the .NET Core ecosystem.
     
  29. MagdielM

    MagdielM

    Joined:
    May 27, 2020
    Posts:
    32
    Okay fair point, honestly. Now what exactly do you mean by a "full solution"? Or perhaps a better question would be what still needs to be done with the engine internally for the team to consider the migration experience straightforward enough to be willing to make the jump to
    .NET Core?
     
  30. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,936
    Each user should be able to flip some switch to put Unity into .NET Core mode. Then assuming any pre-compiled assemblies in their project are built against .NET Standard 2.0 or some version of .NET Core (or .NET 5 maybe) that Unity supports, they can build the project and run the player without any regression in build time performance, run time performance, output code size, or behavior. We need to be able to do this for all Unity projects.

    Keep in mind that Unity is not a .NET application, but rather, a native application that embeds a .NET VM. Unity currently supports two .NET VMs - Mono and IL2CPP. Both were designed to be embedded in a native application. So switching Unity to .NET Core is a bit different from switching a .NET application.

    Some of the following list is done, some has been prototyped, and some is yet to be started, but here is an overview of what would need to happen:
    • Update to the latest upstream Mono code (which supports the use of the .NET Core class libraries)
    • Make IL2CPP work with the .NET Core class libraries
      • The class libraries interface with the runtime via managed to native methods calls named "internal calls" in Mono. The .NET Core class libraries have hundreds of internal calls for the runtime to implement.
      • The .NET Core class libraries also use managed to native method calls via p/invoke for platform-specific APIs. These need to be implemented for all platforms Unity supports.
      • Implement runtime features that the .NET Core base class libraries need (e.g. default interface methods)
    • The Unity editor make heavy use of App Domains to implement its play mode. .NET Core does not have App Domains, so play mode would need to be implemented in a that uses some like assembly load context.
    • Possibly use CoreCLR instead of Mono as a JIT VM solution, although CoreCLR was not designed to be embedded in a native application, so it would need an embedding API added on top.
    With any large software project, there are always dragons lurking in the details, and I'm sure that I've missing something in this list, but it is a start.
     
  31. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    265
    This is what the .NET Core Hosting API is for.
     
    Last edited: Oct 15, 2020
    Qbit86 and pcysl5edgo like this.
  32. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    Another question that could be asked in a poll (and separate one directed to 100k$+ companies) is if they are even updating their projects to newer Unity versions. From my experience most of them were stuck to older Unity versions to avoid random bugs. Cross-project plugins were specifically made to work with all versions.

    Looks like there's a tool that analyzes if dlls could be ported to net5 or standard without issues.

    Sometimes it gives hints how to replace them:

    I guess this means that AppDomain is kind of implemented in NET 5.


    Running from project inside Unity:
    Download https://github.com/microsoft/dotnet-apiport (ApiPort Download) and change pathToApiportExe below:
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using System.Diagnostics;
    3. using System.IO;
    4. using UnityEditor;
    5. using UnityEngine;
    6. using Debug = UnityEngine.Debug;
    7.  
    8. public static class AnalyzeProjectReportNet
    9. {
    10.     [MenuItem( "Tools/AnalyzeProjectReportNet" )]
    11.     public static void AnalyzeProjectReportMethod()
    12.     {
    13.         string pathToApiportExe = "YOUR PATH HERE Downloads/Apiport.2.7.0/net461/ApiPort.exe";
    14.  
    15.         int safePath = 1;
    16.         string reportPath = Path.Combine( Path.GetDirectoryName( Application.dataPath ), "AnalyzeProjectReport.html" );
    17.         while ( File.Exists( reportPath ) )
    18.         {
    19.             reportPath = Path.Combine( Path.GetDirectoryName( Application.dataPath ), $"AnalyzeProjectReport{safePath}.html" );
    20.             safePath++;
    21.         }
    22.         string command = $"{pathToApiportExe} analyze " +
    23.             $"-f \"{Application.dataPath}\" " +
    24.             $"-t \".NET\" " +
    25.             $"-t \".NET + Platform Extensions\" " +
    26.             $"-t \".NET Standard, Version = 2.0\" " +
    27.             $"-t \".NET Standard + Platform Extensions, Version = 2.0\" " +
    28.             $"-r HTML -o \"{reportPath}\"";
    29.  
    30.         RunCommands( new List<string> { command } );
    31.     }
    32.  
    33.     public static void RunCommands( List<string> cmds, string workingDirectory = "" )
    34.     {
    35.         using ( var process = new Process() )
    36.         {
    37.             var psi = new ProcessStartInfo();
    38.             psi.FileName = "cmd.exe";
    39.             psi.RedirectStandardInput = true;
    40.             psi.RedirectStandardOutput = true;
    41.             psi.RedirectStandardError = true;
    42.             psi.UseShellExecute = false;
    43.             psi.WorkingDirectory = workingDirectory;
    44.             process.StartInfo = psi;
    45.             process.Start();
    46.             process.OutputDataReceived += ( sender, e ) => { Debug.Log( e.Data ); };
    47.             process.ErrorDataReceived += ( sender, e ) => { Debug.LogError( e.Data ); };
    48.             process.BeginOutputReadLine();
    49.             process.BeginErrorReadLine();
    50.             using ( StreamWriter sw = process.StandardInput )
    51.             {
    52.                 foreach ( var cmd in cmds )
    53.                 {
    54.                     sw.WriteLine( cmd );
    55.                 }
    56.             }
    57.             process.WaitForExit();
    58.         }
    59.     }
    60. }
    61.  
     
  33. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    You could try CoreRT. I was able to compile System.Process to make it work in il2cpp that doesn't support it otherwise.

    In my case I've made proxy C# library to few System.Process methods, compiled to native, used in Unity il2cpp with DllImport. I think it can also generate C++ instead.
     
    Last edited: Oct 15, 2020
  34. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    265
    It exists but I believe most of it is stubbed out and just throws. I recall reading that it's primarily there for compatibility with code that uses it to query loaded assemblies.
     
  35. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,936
    Yeah, that is pretty cool. It is not as rich as the embedding API that Mono and IL2CPP expose though, and Unity uses the entire embedding API from both, so we've needed to extend the CoreCLR hosting API pretty signifigantly.
     
  36. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,936
    This really varies. Many large projects are on older Unity versions, especially those in production. But during the development life cycle, even big projects are upgraded. We're committed to not breaking existing projects, no matter where they are in development though, so I don't expect us to ship anything until it is ready.

    This is pretty cool, I've not seen it before. This would certainly be useful to help users ensure that their pre-built assemblies are correct. Thanks!
     
  37. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,936
    We have looked at CoreRT. Microsoft is doing some really great work in the AOT area with it.

    The biggest issues now from our end are platform support and maturity. IL2CPP supports all of the platforms Unity ships with, where CoreRT only supports a few, so we would need to port and maintain it. In addition, IL2CPP is pretty mature at this point, where CoreRT is much younger.

    That CoreRT C++ backend is rather interesting, but I think even Microsoft acknowledges that it is experimental now.
     
    saskenergy and JoNax97 like this.
  38. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    265
    Yeah, I think there's a larger API surface you can access (although I forget the method), but even then there's other issues such as CoreCLR not supporting custom internal calls by default (which was mentioned in xoofx's article). Unity would need to reimplement that functionality or move things over to QCalls.
     
    NotaNaN and JoshPeterson like this.
  39. pcysl5edgo

    pcysl5edgo

    Joined:
    Jun 3, 2018
    Posts:
    65
    https://github.com/dotnet/runtime/issues/39798
    "Advanced Embedding API in .NET5 like Mono"

    There is an interesting issue.

     
    Last edited: Oct 16, 2020
  40. ManuelRauber

    ManuelRauber

    Joined:
    Apr 3, 2015
    Posts:
    122
    so... is there any chance that we can get back a working Unity Analytics? Right now, the AnalyticsEventTracker is not exposed from the DLL and the editor is throwing errors on existing scripts. :)

    care to share?
     
  41. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,936
    Sorry, I'm unaware of of anything about this issue. Can you submit a bug report though? This sounds like something that should be corrected.
     
  42. jiraphatK

    jiraphatK

    Joined:
    Sep 29, 2018
    Posts:
    300
    ManuelRauber and JoNax97 like this.
  43. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090

    Hmm... Maybe we don't need Burst to achieve C++ performance after all.
     
    Ramobo and Qbit86 like this.
  44. pcysl5edgo

    pcysl5edgo

    Joined:
    Jun 3, 2018
    Posts:
    65
    I have a question about update Roslyn version.
    Unity seems to locate Roslyn compiler under "Editor/Data/Tools/Roslyn/".
    I can easily use the latest preview C# compiler by replacing Roslyn compiler. (The runtime dependent feature cannot be used of course. I mainly use Target-Typed new, nint, and SkipLocalsInitAttribute.)

    .NET 5 and the Roslyn compiler corresponding to C#9 will appear in November.
    Are there any difficulties relating to update Roslyn?
     
    Last edited: Oct 31, 2020
    jasonboukheir, JesOb and Qbit86 like this.
  45. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,936
    We only support the version of Roslyn that ships with Unity, because it is the one we have tested. You're free to use whatever version you would like to though, but we won't be able to help with any problems.
     
  46. pcysl5edgo

    pcysl5edgo

    Joined:
    Jun 3, 2018
    Posts:
    65
    I'm sorry. I would like to add a few things to what I wrote.
    Is the Unity-Technologies' Roslyn update test a hard work?
     
  47. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,936
    Sorry, I'm unsure what you mean. Can you elaborate?
     
  48. pcysl5edgo

    pcysl5edgo

    Joined:
    Jun 3, 2018
    Posts:
    65
    The C#8 Roslyn compiler appeared in September 2019.
    Unity-Technologies started using it on 28. May 2020(Unity2020.2.0a12 release date).
    Unity-Technologies needs 8 months to update Roslyn.
    I wonder how much the Roslyn update is difficult.
     
    Last edited: Nov 2, 2020
  49. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,936
    The difficulty is that we need to test Roslyn across a number of different use cases, which takes time. I'm sure that we could update to new Roslyn versions faster, but we need to weigh that work against other development priorities, as we have limited resources.

    With that said, C# 9 will be out soon, but it is only supported with the .NET 5 class libraries, I believe. So Unity may not be able to update co C# 9 until we support the .NET 5 class libraries. We will investigate though.
     
  50. pcysl5edgo

    pcysl5edgo

    Joined:
    Jun 3, 2018
    Posts:
    65
    Thank you for the answer!
    This is what I want to know!