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

What .NET stack for UWP/HoloLens?

Discussion in '2018.1 Beta' started by Willy-Delcloy, Mar 16, 2018.

  1. Willy-Delcloy

    Willy-Delcloy

    Joined:
    Oct 27, 2015
    Posts:
    6
    Hi,

    I was trying Unity 2018.b11 expecting that I could write DLLs in .NET Standard 2.0 and use them on PC or HoloLens in my Unity project.

    I thought that it could do so easily because the Player Settings panel for UWP allows to choose "netstandard 2.0" (i.e. "API Compatibility Level") and the Build Player window let me select the latest SDK version (16299).

    But the reality is a mess...

    Even if I try to build a simple UWP app for PC, I encounter issues due to the assembly-weaver. According to the tool, the target platform do not propose the APIs I try to use.

    I expected to call functions like "XMLDocument.load(string)" for instance.

    After several tests, it seems that I have to write a code that uses the API of .NETCore 1.1 although Unity do not support this API...

    To summarize:
    - .NET Framework 4.6 is not usable with HoloLens nor UWP for PC,
    - .NET Standard 2.0 also,
    - a mystery API has to be used...

    So I have several questions:
    - what APIs do I have to target? .NET Core 1.1? .NET Standard something?
    - do you plan to update the Player settings and Build Player windows to avoid the current confusing situation?
    - do you plan to update your code to let developers use .NET Standard 2.0 on HoloLens? [Assuming the SDK 16299 will be deployed on HoloLens.]

    As a side note: I can't try IL2CPP so I have to rely on .NET as the backend because my project is quite large and use native DLLs that lead to problems I have not fixed yet...
     
  2. holo-krzysztof

    holo-krzysztof

    Joined:
    Apr 5, 2017
    Posts:
    77
    The problem is that the .NET runtime on hololens does not implement .NET Standard 2.0; the highest one available there is 1.4.

    You might build against 16299 but hololens is still on 14393 so if you call an API from the first will crash you call any APIs newer than that.

    If you use .NET scripting backend on UWP Unity uses the one shipped with Windows. On IL2CPP it uses Mono, which implements .NET Standard 2.0 in this version. Using that will likely solve your problem.
     
  3. Willy-Delcloy

    Willy-Delcloy

    Joined:
    Oct 27, 2015
    Posts:
    6
    OK, I may try NET Standard 1.6...

    But I also tested what would happen if I build a UWP version of my code for a PC with SDK 16299. The build failed with the following error:
    ""
    Reference rewriter: Error: method `System.Void System.Xml.XmlDocument::Load(System.String)` doesn't exist in target framework. It is referenced from TestAssembly46.dll at System.Void TestAssembly46.Class1::.ctor().
    ""

    TestAssembly46 is a very small DLL that I wrote for debug purpose. The constructor contains a call to 'System.Xml.XmlDocument::Load(System.String)', which is available since version 2.0 of .NET Standard. So I tried to compile the DLL in .NET Framework 4.6.1 and .NET Standard 2.0 but I had no success.

    Is .NET Standard 2.0 supported for UWP?
     
    Last edited: Mar 19, 2018
  4. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    Targeting SDK 16299 doesn't automatically make .NET Standard 2.0 available. For that to be available, you need to change targeted .NET version to UniversalWindowsPlatform, 6.0.0. However, Unity doesn't support this. On .NET scripting backend, we only support targeting UniversalWindowsPlatform, 5.0.0, which is a much more restricted .NET profile. Therefore you cannot use .NET Standard 2.0 if you're targeting .NET scripting backend.

    We don't plan adding support for .NET Standard 2.0 on .NET scripting backend for the following reasons:

    • If you target .NET Standard 2.0 with .NET scripting backend, your game won't run on anything lower than Windows 10 Fall Creators Update. I don't imagine any game developer would want to place such a restriction on their target audience, considering many people haven't upgraded to the newest OS yet;
    • It's not insignificant amount of work in Unity to make this work;
    • By the time most people upgrade to Windows 10 Fall Creators Update, we plan to remove .NET scripting backend support from Unity, so working on it now is kind of pointless.

    If you want to target .NET Standard 2.0 on UWP, use IL2CPP scripting backend. That way you're not restricted on Windows version you want to run, and you are using a supported path.
     
  5. Willy-Delcloy

    Willy-Delcloy

    Joined:
    Oct 27, 2015
    Posts:
    6
    Thank you for your answer.

    Actually I'm not developing a game but an AR platform for a big company; we use Unity to display CAD models (among other things). The idea of upgrading all the involved computers to the newest OS may be an option here!

    But I understand your points and I would like to try IL2CPP. However when I tried it I encountered some issues with our native plugins (I will try again...) and more importantly I have some concerns with how our software architecture was built. In order to upgrade only parts of the software, it was developed as a set of DLLs -- plugins -- that an "almost empty" Unity player project loads when it starts. The Unity player exe is very rarely updated whilst we regularly push new versions of plugins to fix bugs and introduce new features.

    As far as I know, IL2CPP is only able to manage one big app. I saw on this forum someone working at Unity telling that it would be technically possible to make IL2CPP output DLLs but is it true? And how long would it take to make that?

    In addition, if we assume that IL2CPP can output DLLs, I don't see how I would be able to make a DLL plugin through IL2CPP outside of the Unity editor...

    Finally, I would appreciate that someone update Unity documentation to write exactly what .NET stack is supposed to be used with or without HoloLens and UWP in Unity 2018 (.NET Framework? .NET Standard? .NET Framework with .NET Core in mind?), and that you plan to remove the .NET scripting backend.
     
  6. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    When you say DLLs, do you mean native plugins or managed plugins? IL2CPP does not do or care about native plugins - they work the same way on all scripting backends. Could you elaborate what problems you ran into with regards to using them on IL2CPP?

    If you're talking about managed DLLs - IL2CPP does convert all of them into C++ code and then compiles them into a single DLL called "GameAssembly.dll" (see this https://docs.unity3d.com/Manual/IL2CPP-HowItWorks.html). However, this isn't different from how .NET scripting backend works - we require all your DLLs to be present in your Unity project when you build it. Furthermore, .NET native will link your managed DLLs into a single native DLL when you build your exported VS project too - your shipped application package wouldn't contain individual managed DLLs in either case.
     
  7. Willy-Delcloy

    Willy-Delcloy

    Joined:
    Oct 27, 2015
    Posts:
    6
    We did something funky :)

    We have a separate Visual Studio solution that builds managed DLLs (our plugins), and many of them link with UnityEngine.dll. For each of them, a post-build event copy the DLL to two folders: 1/ an Asset folder of a Unity project that we use to test and develop the code, 2/ a folder that stores the DLLs to ship them later.

    In the Unity editor, only one GameObject is present. When pressing Play, it will load GameObjects stored in the managed DLLs we copied. What DLLs should be loaded and the loading order are given in XML files. We also use this project to export AssetBundles (one DLL = one AssetBundle).

    When we decide to ship our program, we use another Unity project that relies on the same mechanism: one GameObject will load managed DLLs. This time, it will load through Assembly.Load() because we are outside of the editor and Assets will be found in AssetBundles we built in the first Unity project.

    Obviously, this is quite complicated but at the end we get something that is easy to upgrade on customer computers and we can distribute a only a subset of our app.

    Do you see other technical solutions to make an upgradable game or app without asking the user to download and install everything all the time? It seems complicated with the solution of one big "GameAssembly.dll".

    About the problems I encountered with IL2CPP, I can't elaborate... It was with the Unity version "5.4.0b16-HTP" (for HoloLens). Perhaps a bug in Unity at this time or something I did wrong (our code is a bit large). I will give it a try again with Unity 2018b11.
     
  8. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    I expect most of your game size to consist of assets, rather than code (unless you really don't have many). Just because it links the code into one DLL doesn't mean it will necessarily be huge. Besides, Windows Store only redownloads the pieces that changed when updating apps. So if you change code, GameAssembly.dll and il2cpp global metadata files will be redownloaded to update the game (rather than the whole game). The same would happen on .NET scripting backend too.

    Unity 5.4 is a very old Unity version... 2 years old in fact. IL2CPP is in a much, much, much better state today than it was back then.
     
  9. doktor123456

    doktor123456

    Joined:
    Apr 5, 2018
    Posts:
    1
    Hi,

    So I have several questions:
    - what APIs do I have to target? .NET Core 1.1? .NET Standard something?
    ....


    have a look here:

    https://docs.microsoft.com/en-us/uwp/api/

    build your DLLs as UWP DLLs against https://www.nuget.org/packages/Microsoft.NETCore.UniversalWindowsPlatform/5.0.0 to match what unity is using when creating the UWP VS project. Target 14393 with the UWP DLLs.


    Reference rewriter: Error: method `System.Void System.Xml.XmlDocument::Load(System.String)` doesn't exist in target framework. It is referenced from TestAssembly46.dll at System.Void TestAssembly46.Class1::.ctor().


    have a look at Windows.Data.Xml.Dom in the UWP API. (https://docs.microsoft.com/en-us/uwp/api/windows.data.xml.dom)

    i know this brings a cluster fu of rewriting existing XML handling code but at least - it works ;) (well, seems to work... throws errors en masse (broken assemblys, typeloadexceptions, etc) in the editor but on the HL the code runs without throwing runtime errors - so far, still testing. i just drop the DLLs in the unity project and put all the code that uses them in #if NETFX_CORE blocks).

    you might want to consider to have 2 sets of DLLs for the editor and the HL as mentioned here https://stackoverflow.com/questions/39299961/building-a-uwp-app-in-unity-using-tcpclient .