Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Unity Future .NET Development Status

Discussion in 'Experimental Scripting Previews' started by JoshPeterson, Apr 13, 2021.

  1. CaseyHofland

    CaseyHofland

    Joined:
    Mar 18, 2016
    Posts:
    549
    @JoshPeterson I'm writing a simple clock system and I want to use TimeOnly which is in .NET 6, so I copied it and put it in a separate Asmdef.

    Will there be a compiler definition to specify ".NET6_OR_NEWER"? I want to specify it be undefined in my constraints.
     
  2. CarePackage17

    CarePackage17

    Joined:
    Dec 6, 2014
    Posts:
    21
    I guess you'll be able to use the framework defines documented here: https://learn.microsoft.com/en-us/d...eprocessor-directives#conditional-compilation

    So it'd be NET6_0_OR_GREATER in your case.
     
  3. CaseyHofland

    CaseyHofland

    Joined:
    Mar 18, 2016
    Posts:
    549
    TangerineDev likes this.
  4. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,773
  5. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    Hi. I was watching the Unity roadmap for 2023 talk from the GDC, and Simon Elliston Ball says that they are working on an API to make Fast Enter Play Mode easier to adopt. Then he says that this will also help projects be ready for the future of .NET with Core CLR. Here's the video at 7:20.

    Here are some questions: Does anyone know what's the relation between using Core CLR and Fast Enter Play mode? Does the absence of Domain Reloads mean that we'll have to use Fast Enter Play Mode shenanigans? I already use them, I don't need to be convinced to try them, but it still makes me a little worried. I imagined Unity would still have something equivalent to Domain Reloads. If that isn't the case, what will happen to existing Objects in the Editor after user code is modified and recompiled outside of Play Mode?

    Thanks!
     
    Last edited: Mar 30, 2023
  6. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,084
    OCASM and TangerineDev like this.
  7. OndrejP

    OndrejP

    Joined:
    Jul 19, 2017
    Posts:
    296
    I don't have any internal information, based on posts here on forums I think it's something like this:

    With CoreCLR, Unity Editor will use feature called "AssemblyLoadContext" for user assemblies
    • AssemblyLoadContext supports Unload
    • To successfully Unload assemblies, there cannot be any references to user types or instances
    • If you subscribe for example to EditorApplication.update, that's a reference
    • If you add instance of you class into some list held by Unity Engine, that's also a reference
    • If you create GCHandle to instance of your type, that's also a reference
    There are few possible ways to address this
    1. Use Weak references (these don't "protect" object from Garbage collector)
    2. Callback "OnBeforeDomainReload" with analysis tools
    3. Analysis and forceful clearing
    ad 1. Weak references are problematic for several cases, they are slower, make GC slower and would need to be placed everywhere where user instance can be stored (probably impossible).

    ad 2. Callbacks on the other hand might work well, the problem with them is that they require users to use them and handle them well.

    ad 3. Forceful clearing might work, but I'm not sure how realistic it is. Setting references to user instances to null might cause more issues.

    My guess is that there will be some callbacks, which get executed when user code is about to be unloaded. You'll unregister events and remove object references you've stored anywhere in the Unity Engine. This will be accompanied by analysis tool, which will tell you which references are still there preventing unload.

    Also it's likely there will be some fallback system, which will simply unload Unity Engine assemblies as well - or in the worst case, it will restart whole .NET runtime (which I'm guessing will be probably as slow as Domain reload with Mono).

    @JoshPeterson Would be nice if you could confirm or refute this ^^ :D
     
  8. PetrisPeper

    PetrisPeper

    Joined:
    Nov 10, 2017
    Posts:
    62
    Personally, I'd hope Unity would rather host the player code in a separate process and just use IPC to communicate with that. This would remove the need for assembly unloading and would also introduce more stability to the editor.
     
    TangerineDev likes this.
  9. Huszky

    Huszky

    Joined:
    Mar 25, 2018
    Posts:
    106
    That would not work with custom editor scripts.
     
  10. Mindstyler

    Mindstyler

    Joined:
    Aug 29, 2017
    Posts:
    224
    AFAIK yeah fast enter playmode and coreclr require functionally similar code considerations, like resetting static fields manually and such easy tasks. But it only effects the editor behaviour and not anything in the compiled and shipped game.
    So really not sure what @OndrejP is talking about.
     
  11. SevenPointRed

    SevenPointRed

    Joined:
    Feb 3, 2016
    Posts:
    199
    Resetting manually is all good until you use a libary that cant do it and then its impossible :(
     
  12. Mindstyler

    Mindstyler

    Joined:
    Aug 29, 2017
    Posts:
    224
    99% certain that only statics in monobehaviours / directly unity-interfacing-types have to be reset.
     
  13. blight15

    blight15

    Joined:
    Feb 23, 2023
    Posts:
    1
    Wow that's wonderful.
    I want more details about trends of Unity game development.
     
  14. TieSKey

    TieSKey

    Joined:
    Apr 14, 2011
    Posts:
    219
    No, all static variables will remain with previous values, not only unity related ones.
    For example, the native gRPC library seems to hold values in static variables so it completely breaks when u try to use it without domain reloads.
     
  15. simon-ferquel-unity

    simon-ferquel-unity

    Unity Technologies

    Joined:
    Apr 1, 2021
    Posts:
    65
    We are indeed looking at making fast enter playmode easier by bringing more consistent APIs to deal with the editor lifecycle (code reload, enter/exit playmode, etc.). The reason why it shows up in .net modernization and talks about CoreCLR is because basically, Fast enter play mode will be enabled for everybody without any way to disable it with CoreCLR.

    So what is fast enter play mode and why can't we keep the old way around with CoreCLR?
    - Fast enter playmode remove the domain reload happening just before entering play mode, requiring users to cleanup any static state that should be reset on entering playmode.
    - It can cause issues in code that was not crafted to take fast enter play mode into account (e.g. static events being handled multiple times etc.
    - CoreCLR does not have anything similar to unloadable app domains. Instead it has Assembly Load Context (more about it further). So that means that even if we thought it would be a good idea (and spoiler: we think we should have helped user more in the past to make the domain reload on enter playmode disappear for good), we could not make it happen with CoreCLR.

    So how will we handle Code Reload (e.g. reloading a the user code once a change is done) without restarting the editor ?
    - We will use AssemblyLoadContexts. AssemblyLoadContexts (ALC) allow you to load a set of assemblies together and when it is not needed anymore, ask the runtime to unload them together.
    - This API requires a little bit of cooperation: the app domain will still be leaving, and the assemblies are unloaded when no living outstanding GC handles points to any object of those assemblies.
    - Special note here: static fields and events in the code being unloaded don't cause any problem. The problem are static fields and events in code that is not unloaded pointing to stale objects.

    What does it mean?
    It means that any static field, or event that is not part of the ALC being unloaded and that is holding a reference to any object in that ALC, will make it live longer than it should. Any usage of ALC requires to be super careful of those outstanding references.

    How will we use ALCs?
    We will have the following ALC structure (note: it is still subject to change)
    - Unity.Loader + CoreCLR PrivateCoreLib in the default ALC (which is not unloadable) - Layer 0
    - Unity Modules (except platform specific modules) + .net BCL libraries in a first unloadable ALC - Layer 1
    - White listed packages known to autocleanup there events and static fields + platform-specific modules - Layer 2
    - User code + non-white listed packages - Layer 3

    How will we prevent leaking ALC from the Unity API (Unity modules) ?
    - We are in the process of cleaning up our API replacing all static fields by properties
    - We are working on roslyn source generators helping us to intercept all potentially problematic static properties and events assignments, identifying the layer of the referenced object and register it of auto-cleanup on ALC unload
    - If that fails and we detect ALC leaks, we will have an heuristic that will make the next code reload unload both layer 3 and 2, then if it still fails, will unload all 3 layers.

    What about threading and async code ?
    - On each code reload we will generate an execution context with an AsyncLocal giving us the "Code Reload Generation" where it was created. This execution context will be the ambient one in the main thread.
    - Whenever user code write async code, this execution context will flow, allowing us to do some analysis.
    - Just after a Code Reload, we will look at all running managed threads, observe their async locals and warn if anything that should not be running is still running (e.g. an async task that does not listen for a CancellationToken)
    - In our synchronization context, we will look for any async callback resuming on a stale execution context and emit a warning
    - We will add a diagnostic switch allowing to attach a debugger and emit a breakpoint when those situations arise (allowing a good debugging experience for our users)

    Will my code work as is ?
    - Well, it depends on the code
    - Embracing Fast Enter Playmode should help in bringing your code to CoreCLR ultimately (CoreCLR will have FEP always enabled, and the cleanup requirements that ALC require are in the same family of concerns)
    - We expect that most user code related to the game code itself should mostly work as is. Editor extensions might be a bit more complicated.
     
  16. burningmime

    burningmime

    Joined:
    Jan 25, 2014
    Posts:
    845
  17. simon-ferquel-unity

    simon-ferquel-unity

    Unity Technologies

    Joined:
    Apr 1, 2021
    Posts:
    65
    You are actually highlighting 2 categories of static events that we are going to treat differently:

    - First one is a regular static event from the API (In that case it's `Undo.UndoRefoPerformed` but many are of the same kind): those ones will be automatically cleaned up: when an ALC is unloaded, we'll unsubscribe the event for you - maybe with a warning because we'd prefer not to hide the magic in those cases. This is the case where we'll rely on a roslyn source generator to intercept our static events "add" methods to automatically unhook events when an ALC is requsted to be unloaded.
    - Second one is an editor lifecycle event. We will deprecate those events, and replace them with a set of coherent "declarative attibute". You will be able to write code like:

    Code (CSharp):
    1. [BeforeCodeReload]
    2. static CleanupThings(){...}
    3.  
    4. [AfterCodeReload]
    5. static InitializeThings(){...}
    without having to manually subscribe / unsubscribe to events (the editor will do that for you)
     
  18. OndrejP

    OndrejP

    Joined:
    Jul 19, 2017
    Posts:
    296
    Thank you for the detailed info, it sounds great.
    Automatic event cleaning is good idea. I think that's one of the most common cases.

    What about other things, for example when you add your object into some list, which is stored in Unity Engine? PlayerLoop comes to my mind or hooking something into UI through UI Toolkit and VisualElement hierarchy.
    Will that be full responsibility of us?
     
    TangerineDev likes this.
  19. simon-ferquel-unity

    simon-ferquel-unity

    Unity Technologies

    Joined:
    Apr 1, 2021
    Posts:
    65
    We will still serialize / deserialize the current scene graph on code reload (as we do on domain reload today), so I am not to worried about this kind of lists (we have good ideas about serializationperformance boosts that coreclr will bring). However, if we see that a particular module is a common offender for ALC leaks we should be able to move it to layer 3 ALC, to unload it on each code reload.
     
  20. burningmime

    burningmime

    Joined:
    Jan 25, 2014
    Posts:
    845
    So the best practice for a custom undo handler would be something like...

    Code (CSharp):
    1. // run once on app startup, then any time the assembly is reloaded
    2. [InitializeOnLoadMethod, AfterCodeReload]
    3. static hookUndoHandler()
    4. {
    5.     // subtract then add to prevent accidentaly being called twice; we on;y ever want one instance
    6.     // of the undo handler attached
    7.     Undo.undoRefoPerformed -= myUndoHandler;
    8.     Undo.undoRefoPerformed += myUndoHandler;
    9. }
    10.  
    11. [BeforeCodeReload]
    12. static unhookUndoHandler()
    13. {
    14.     Undo.undoRefoPerformed -= myUndoHandler;
    15. }
    16.  
    17. static void myUndoHandler()
    18. {
    19.     /* ... */
    20. }
    ...? Ehhh... seems like a bit of a PITA, but I guess it's not too bad, and at least it makes it explicit what's going on.
     
  21. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    258
    Why do you think those wouldn't work with an IPC system? There's not really any reason why they couldn't, it just depends on the implementation of IPC used.
     
  22. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    If I'm understanding ALCs correctly, an ALC can't be unloaded if there are references to it in other ALC. So I believe line 7 shouldn't be needed?

    Many Editor tools and systems access runtime objects directly in code. Wouldn't that be impossible with IPC? I'm not saying all that code couldn't be changed to use IPC channels to interact with the running game, but that would mean rewriting a lot of code.
     
    Last edited: Mar 31, 2023
  23. Enderlook

    Enderlook

    Joined:
    Dec 4, 2018
    Posts:
    44
  24. TangerineDev

    TangerineDev

    Joined:
    Sep 28, 2020
    Posts:
    122
    I wouldn't expect this as it would require probably an entire revamp AGAIN of the engine and second of all I wouldn't expect it to work on the C++ side as well...

    Sounds like something cool to mess with, but probably idiotic in a game engine setting XD
     
  25. b_bishop

    b_bishop

    Joined:
    May 17, 2022
    Posts:
    7
    Sorry if this question is lacking awareness with regards to the current state of Unity, I'm just revisiting after being gone from this project for a while.

    Is .NET 7 fully supported now for development with Unity beta 2023.1? - If it matters, I only target Windows.

    By fully support I mean including the usage of C# 11.0 language features and able to build with the preprocessor symbols 'NET7' / 'NET7_0_OR_GREATER'.
     
  26. TangerineDev

    TangerineDev

    Joined:
    Sep 28, 2020
    Posts:
    122
    No
     
    OndrejP and b_bishop like this.
  27. PetrisPeper

    PetrisPeper

    Joined:
    Nov 10, 2017
    Posts:
    62
    @simon-ferquel-unity Have you considered hosting the user code in separate process and just closing that on reload while using IPC to make sure all the APIs work the same by the way?
     
  28. burningmime

    burningmime

    Joined:
    Jan 25, 2014
    Posts:
    845
    This was mentioned above. It seems full of pitfalls and a TON of work on Unity's side to make everything work right (plus, some graphics APIs rely on direct pointer access to memory; you could maybe try to work it with memory mapped files, but... yeah, that sounds like its own can of worms).

    The big question is "why"? They're already working on making code reload safe by doing the several layers thing, and adding instrumentation/analysis to help users modify their scripts to be code reload safe. The main benefit of process isolation would be sand-boxing/security, which isn't as much a concern in Unity as in like a web browser.
     
  29. Huszky

    Huszky

    Joined:
    Mar 25, 2018
    Posts:
    106
    Well, actually it would be really nice for games which support modding. You could create an isolated runtime which does not let mod code access file system or network resources. It would probably not work with IL2CPP, but why would it not just run with the upcoming CoreCLR?

    @JoshPeterson Did you have any internal conversation about this yet?
     
  30. Huszky

    Huszky

    Joined:
    Mar 25, 2018
    Posts:
    106
    Well, yes you could make it so that editor code is reached through some IPC but that would require a lot of work from Unity. I think that with those resources they should just improve the hot reload experience.
     
    TangerineDev likes this.
  31. Enderlook

    Enderlook

    Joined:
    Dec 4, 2018
    Posts:
    44
    Because third-party libraries which were not specifically made to be used in Unity -but in .NET as general- wouldn't work properly when reloading code. That is why.
    The fact that Unity has these special quirks makes it much more difficult to use libraries from nuget.
     
  32. burningmime

    burningmime

    Joined:
    Jan 25, 2014
    Posts:
    845
    What's an example of a 3rd-party library that would not work in Unity with ALCs in .NET core, but *would* work if it were hosted via IPC?
     
    TangerineDev likes this.
  33. burningmime

    burningmime

    Joined:
    Jan 25, 2014
    Posts:
    845
    You can already do that yourself, though. If you're making a game (targeting mac/windows/linux) and want sand-boxed mod support, you can launch another process, give that process the exact permissions you want it to have, and access it via IPC. Sounds like a massive pain to do, but I guess if you're worried about viruses in mods.
     
    Saniell likes this.
  34. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,773
    This is not something we have considered. In general, we're looking to stay within the guardrails of normal .NET libraries. That would hopefully allow users to use third-party libraries where they see fit. We don't want to require everyone to do this though.
     
    Gooren, OndrejP, Huszky and 2 others like this.
  35. Mindstyler

    Mindstyler

    Joined:
    Aug 29, 2017
    Posts:
    224
    While I somewhat see the benefit here, that should ultimately be completely up to the end-dev if they want to do it this way or not, just as burningmime is suggesting. Restricting possible resource access for mods is something that is deeply limiting, and is not something that 95% of games should ever consider, especially since you as the game dev are not in any way liable for mods and people should have the mental capacity of knowing to only use mods they trust, just like any other application.
     
  36. Sarono

    Sarono

    Joined:
    Apr 12, 2018
    Posts:
    8
    In Unity2021LTS, List.Sort/Array.Sort allocates 128b, in .NET 6, there is no memory allocated. It's too bad.:(
     

    Attached Files:

    oscarAbraham likes this.
  37. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,773
    Unfortunately the class libraries we are using now from Mono are not quite as tuned as the ones from .NET 6 and later. We are actively working on moving Unity to those newer class libraries though - so this should be fixed once we do that.
     
    Gooren, oscarAbraham, Thaina and 6 others like this.
  38. TangerineDev

    TangerineDev

    Joined:
    Sep 28, 2020
    Posts:
    122
    Sure, in a performance critical context that IS bad, but you could just code your own algorithm ;), right?

    But seriously though, performance improvements like these, which are built-in directly into the BCL is why we programmers are awaiting Unity + .NET 6!
    Hope we get to see a polished implementation soon!
     
  39. xdayo17

    xdayo17

    Joined:
    Apr 12, 2022
    Posts:
    1
    When will .NET 6 implementation published to alpha stage?
     
  40. runner78

    runner78

    Joined:
    Mar 14, 2015
    Posts:
    760
    From what I've seen on Github, Unity's fork is already on .NET 8.
    What would interest me is whether it is planned, since the .NET release and the first tech release are in the same period, whether Unity then updates the .NET version every 202x.1 version.
     
    Tuncle, cxode, Alvarden and 2 others like this.
  41. Mindstyler

    Mindstyler

    Joined:
    Aug 29, 2017
    Posts:
    224
    They stated previously that they will switch to a new dotnet version always very shortly after a new one is released.
     
    TangerineDev likes this.
  42. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,773
    We don't have specific release plans to share yet. I do expect that our release on Unity with newer .NET will be based on .NET 8 (not .NET 6). I also do not expect that we will back port any changes for this initial release of Unity using the CoreCLR JIT to any existing Unity LTS versions.

    We will share release plans when we get closer to release, sorry!
     
  43. Deleted User

    Deleted User

    Guest

    Adding to my list of things to check out when the new .NET is available to test: ONNX Runtime for C#.

    I know Unity has an inference engine in Barracuda, but Barracuda is really limited. I haven't been able to run a LLM on it yet ;).
     
  44. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,084
    Random thing I found in Net7:
    https://stackoverflow.com/questions/390900/cant-operator-be-applied-to-generic-types-in-c
    Code (CSharp):
    1. You can do this with C# 11 and .NET 7+:
    2.  
    3.     static void Main()
    4.     {
    5.         Console.WriteLine(Compare(2, 2));
    6.         Console.WriteLine(Compare(2, 3));
    7.     }
    8.     static bool Compare<T>(T x, T y) where T : IEqualityOperators<T, T, bool>
    9.     {
    10.         return x == y;
    11.     }
    There's a lot of interesting possibilities. Hopefully we'll get it soon!
     
    TangerineDev likes this.
  45. Mindstyler

    Mindstyler

    Joined:
    Aug 29, 2017
    Posts:
    224
    Well yeah. 'Generic math' is one of the bigger parts of up to date .net. :D Definitely a great feature, and good to see more people finally being aware.
     
    TangerineDev likes this.
  46. TangerineDev

    TangerineDev

    Joined:
    Sep 28, 2020
    Posts:
    122
    And the cool thing about all of this is that afaik this doesn't box, meaning no garbage!
     
    Deleted User and OndrejP like this.
  47. DHAR1

    DHAR1

    Joined:
    Dec 14, 2022
    Posts:
    1
    im really exited to hear anything on this. Super happy to read this forum post and replys. can we expect a ".NET 8 pivot" engineering tools roadmap or unity platform roadmaps? i do see the roadmaps on their regarding upgrading to a newer version of C# and .NET Runtime roadmap but will there be one for this change in particular?
     
    Last edited: Apr 26, 2023
  48. RaventurnPatrick

    RaventurnPatrick

    Joined:
    Aug 9, 2011
    Posts:
    165
    Is there any estimation as to when we will get this release plan? I.e. "a few years" or rather "a few months"?
     
  49. MiTschMR

    MiTschMR

    Joined:
    Aug 28, 2018
    Posts:
    358
    They won't disclose their targets because they are not yet ready for the public. It doesn't matter how many people ask, it will be the same answer until they decide to tell us.
     
    Luxxuor and Nad_B like this.
  50. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,773
    Yeah, we're still at the point where we don't have confidence in when a release will happen. I want to be clear that this is not a matter of hiding any information, on the contrary, I'd like to be as open as I can about our plans. We're currently still heads-down working on this, and we don't yet know when it will be ready, so we don't want to give any false hope.

    We will communicate it when we know more though.