Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

WebGL Xbox One Browser Compatibility

Discussion in 'Web' started by R1PFake, Oct 21, 2020.

  1. R1PFake

    R1PFake

    Joined:
    Aug 7, 2015
    Posts:
    556
    Hello, I tried to search but didn't find anything about console (Xbox One) Browser Compatibility for WebGL.

    The official documentation https://docs.unity3d.com/Manual/webgl-browsercompatibility.html says:
    "Note that Unity WebGL content is not currently supported on mobile devices. It may still work, especially on high-end devices, but many current devices are not powerful enough and don’t have enough memory to support Unity WebGL content well. For this reason, Unity WebGL shows a warning message when trying to load content on mobile browsers (which can be disabled if needed)."

    But I don't know if they consider the Xbox One browser as a "mobile browser".

    Does anyone know if the Xbox One browser can run (simple) WebGL games?
    And are there some things that I should know if I target the Xbox One browser?

    It's only a small 2d game that I want to show to friends, all of them have a Xbox One, but a few of them don't have a PC, that's why I would like to build for the Xbox One browser.
     
    jukka_j likes this.
  2. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    Most (if not all?) gaming consoles and Smart TVs embed either WebKit or Chromium to implement the web browser. We do "weakly support" running in both embedded WebKit and Chromium, so this is a scenario that should work.

    By weakly supported, I mean that we do not currently test running WebGL on any of the console or TV browsers, so you will be treading on unknown grounds there. E.g. it might be that some of these consoles have gone and explicitly disabled WebGL support. In that case Unity WebGL builds would not work. I don't know if that's the case - if people do try this out, I'd love to hear how that experience goes.

    There are no known issues currently with any of the console/Smart TV browsers that would make us immediately know to say "it won't work". This is an interesting question, which I've pondered some times in the past, but never really had time to try out in practice (I don't have any of the current consoles to test either :( )

    We are interested in taking in bugs if things are not going smoothly, but I have no idea how feasible it will be to fix them.

    In short, give it a shot, and let us know too.. you may be the first doing that :)

    A quick way to test how well it'll run WebGL may be to try the following sites:

    https://itch.io/games/html5
    https://www.khronos.org/registry/webgl/sdk/tests/webgl-conformance-tests.html
    https://webglsamples.org/aquarium/aquarium.html
     
  3. R1PFake

    R1PFake

    Joined:
    Aug 7, 2015
    Posts:
    556
    I made a very basic test with the default WebGL template and uploaded it to itch, the game was 2d pure UI without any input code. The game loads fine on the Xbox One Edge browser, size was a bit weird (something was cut off) but it seems to work fine in full screen mode. I played the game with the virtual cursor and the UI button worked fine too.

    There was a message which said something about the app using custom input (I don't know the exact message, because I don't use the english browser) and the cursor was gone and I had to press a specific button (it's shown in a help popup) to return the virtual cursor. I didn't try to use any other input code, but since the app showed this message I assume that actual xbox controller input would work in game code and the app hides the cursor so you could use the stick for ingame controls instead.

    I will maybe test some actual Xbox controller input in the future, but currently I don't need it, because my game is 2d with only UI button input, so I will just tell my friends to use the virtual mouse cursor to play my game.

    But this was just a very simple / small prototype, my "real" game uses more "advanced" stuff like a C# JSON plugin and code to load files from the StreamingAssets and code to store/load strings in the PlayerPrefs, I will test if all of these things work in the Xbox browser at the weekend.

    And I will use a different WebGL template for auto size scaling.
     
    Last edited: Oct 21, 2020
    gtk2k, De-Panther and jukka_j like this.
  4. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    Great to read that it worked out as well as it did. Gamepad vs mouse controls do probably need some customization.

    There is the pointer lock API that Unity uses to toggle between mouse hidden and visible states. I wonder how it handles that. (maybe that is what triggered the custom input it was referring to - or maybe it happens if the page registers to read gamepad events, which Unity does)
     
  5. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,556
    PS4 Pro with System Software 8.00: "Your browser does not support WebGL."
     
    gtk2k likes this.
  6. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    That is unfortunate :( That just leaves me to wonder what Nintendo is doing with the Switch...
     
  7. R1PFake

    R1PFake

    Joined:
    Aug 7, 2015
    Posts:
    556
    There seems to be a issue with System.Text.Json and WebGL, it doesn't throw any errors and the Deserialize method returns an object, but the object has a list property which is empty after the method call. The same code works just fine in the editor. I checked the browser console log and there is no error message at all.

    I thought it maybe a error because I use custom generic JsonConverter<T> classes and create their instances with the Activator.CreatInstance, but I disabled code stripping and added some debug logs and they seem to be created properly, even with the generic Activator call, so I don't know what else could be the issue, because I don't know how the System.Text.Json Deserialize method is implemented.

    I will try to add more debug log calls in the methods tomorrow, but kinda hard to find the error, because there is no error message, no way to debug the webgl build (or is there?) and every build takes very long for some reason, even on my gaming pc
     
  8. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    Debugging WebAssembly content is currently hard - the WebAssembly Community Group is in the process of developing a DWARF based debugging format to enable Wasm debugging, but that unfortunately is not yet available.

    If you are able to reduce the code down to a small test case, feel free to report it as a bug. One thing to double check is to do a Development build, and set stack traces to Full in the WebGL build settings.
     
  9. R1PFake

    R1PFake

    Joined:
    Aug 7, 2015
    Posts:
    556
    Do you know Microsoft C# Blazor client side project? As far as I know they also use WebAssembly and you can debug the C# code in Visual Studio while debugging the web site. And if I understand correctly they don't even need to compile their C# code to C++ / WebAssembly because they wrote a (smaller) .NET runtime in WebAssembly which can interperte the C# code directly at runtime without compiling it to a different language. I don't know how they do it and maybe I understood something wrong, but maybe they could share some of their tricks :D

    Buut back to topic, before I debug more or setup a bug report project: System.Text.Json is from a NuGet package. My Unity project is set to target .NET 4.x, so I downloaded the .NET 4.7 version (newest) of the NuGet package in a seperate C# project in Visual Studio and copied all the dlls from the package to my Unity Plugin folder. This is the "right" way to do it correct? Or is this not supported and only worked by coincidence in my Windows standalone build?
    The package claims to be "cross platform" so no windows specific code and they even use it in their own C# web projects templates.They also have a package for .NET Standard 2.0, maybe I should try that one instead.

    The weird thing is that the deserialize method call actually works, it creates the correct instance and doesn't throw, but doesn't fill the list property, so I assume that I *should* work and it's just a special case, maybe it's because of the custom converter to handle abstract types, I will check if the deserializer has some additional logging properties.


    Update:

    I added additional debug logs can I can confirm that the error happens, because Lists are not deserialized at all, this isn't even related to converters like I thought before, because it also happens with other classes, which don't have a custom converter.

    But I had a similar problem when I first started with System.Text.Json the problem was that the List property needs a public setter, because it doesn't fill existing List instances unlike Newtonsoft.

    // This doesn't work with System.Text:Json, because a public setter is needed
    public List<MyClass> Items { get; } = new List<MyClass>();

    // This works just fine in Unity windows build and editor but not during WebGL build
    public List<MyClass> Items { get; set; } = new List<MyClass>();

    Note: The setter is not used anywhere else other than the initialize value and during deserialization. But the property getter and list members ARE used in game code.

    This there any chance that IL2CPP somhow removes the setter, because it "thinks" that the setter isn't needed, because it's only used during reflection?

    Btw I disabled code stripping, so it can't be that, maybe it's some other kind of optimization?
     
    Last edited: Oct 23, 2020
  10. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    What you are doing should work to my understanding.

    I wonder if this might be something IL2CPP related. You can try switching the Windows native build to use IL2CPP backend instead of the Mono backend. That will get the C# execution environment to be the same on Windows vs WebGL. I wonder if that shows an error on Windows side then?
     
    gtk2k likes this.
  11. R1PFake

    R1PFake

    Joined:
    Aug 7, 2015
    Posts:
    556
    Okay I give up on System.Text.Json I made a new small example project, for some reason it throws an actual exception in this new test project, but I still don't know how to fix it. The code works just fine in editor, but fails again during WebGL.

    Should I upload the project somehwere, so you can have a look at it?

    The problem (at least with the int property) seems to be that the deserializer uses some generic stuff and there is no AOT code for these. And I don't know how to force AOT to generate the code for these, because the classes are internal.

    In the mean time I will write my own simple json reader/writer which doesn't require any generics or custom converters, the format is very simple anyways and I need special support for abstract types which requires converter hacks in both System.Text.Json and Newtonsoft anyways. Hopefully it will work in WebGL or at least I will have full access to the code, to debug it properly. And it will not require all these external dlls, I have to import 9 depending dlls just for System.Text.Json.
     
  12. R1PFake

    R1PFake

    Joined:
    Aug 7, 2015
    Posts:
    556
    I tried windows build with IL2CPP and I get the same error there, so it's a problem with AOT, it's a very long stack trace, but the actual error happens, because it can't create an instance of type System.Text.JsonPropertyInfoNotNull'4 (so generic), because no AOT code was generated for it.

    It's a class that the serializer uses internally, I have no control over it, so I can't add any attributes or other workarounds.
     
  13. De-Panther

    De-Panther

    Joined:
    Dec 27, 2009
    Posts:
    590
    adamgolden likes this.
  14. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    Thanks for taking the time to poke on the details here. Please do raise a bug report, that will route the issue to the IL2CPP team to look at.
     
  15. R1PFake

    R1PFake

    Joined:
    Aug 7, 2015
    Posts:
    556
    I spent a few hours to write my own json (de)serializer annnd it didn't work with IL2CPP (at first), but after reading the documentation I realized that the Windows IL2CPP supports C# debugging, so I attached the debugger to the player and my deserializer uses reflection PropertyInfo.CanWrite to check if the property should be read, but the CanWrite returned false during the IL2CPP build even with a public setter, because the setter wasn't used any where other than the initializer and the IL2CPP build thought it's a good idea to remove the setter (tbh it's a bad to remove a public property setter during the build, I mean we made it public for a reason and not for fun, but that's a different topic).

    After spending some more time in the documentation I added a link.xml and added a single line to preserve the whole dll, because Im not going to bother to add a attribute to every single "dummy" data class.

    So end of the story. It finally works with IL2CPP build and I could run it on the Xbox and I learned many new things about Unity / IL2CPP..

    Btw I search for "Unity IL2CPP PropertyInfo.CanWrite" and other people have similar problems and frustration, maybe they should move this property "optimization" to a higher lever, because my stripping level was set to low and it still happend.
     
    Last edited: Oct 24, 2020
    gtk2k likes this.
  16. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    Thanks for the feedback. I've routed this to the IL2CPP team, who manages the C# codegen aspects for AoT targets.
     
    De-Panther and R1PFake like this.
  17. mike-voorhees

    mike-voorhees

    Unity Technologies

    Joined:
    Aug 9, 2016
    Posts:
    50
    Let me try and give some context as to what is going on here. What you are seeing is a by product of managed code stripping, which is performed by a tool called UnityLinker. Managed code stripping is always enabled when targeting the IL2CPP backend. It is disabled by default when targeting the mono backend, but it can be enabled in the Player Settings by setting the Managed Stripping Level.

    > tbh it's a bad to remove a public property setter during the build, I mean we made it public for a reason and not for fun, but that's a different topic

    The goal of managed code stripping is to remove all code that is not needed at runtime in order to reduce build size but also to reduce IL2CPP compilation times. This is a tricky balancing act. If public members are not fair game then the only thing that would be removed from any assembly would be unused private members. Assemblies/Packages you reference such as System.Text.Json would have very little removed from them and managed code stripping would become relatively useless. It's not public members that cause problems for code stripping, it's reflection. With most serialization libraries being reflection based, they often lead to problems.

    The default Managed Stripping Level for IL2CPP is Low. Some assemblies are not stripped during Low in an attempt to make managed code stripping more user friendly. Your assembly must be on the unfortunate side of the logic we use to determine what assemblies to strip. More complete details are available here. The logic to determine which assemblies to strip is a legacy of the past. It's hard to understand and often not forgiving enough, as you've found out. The challenge is that for every person that would benefit from us expanding the set of assemblies that are not stripped there is another user who will have their build size and build times regress. We review this topic occasionally.

    > After spending some more time in the documentation I added a link.xml and added a single line to preserve the whole dll, because Im not going to bother to add a attribute to every single "dummy" data class.

    You are right that link.xml is tedious to use for preserving individual types and members. We are aware of this and will be supporting new attribute based annotations in future releases.

    There is an alternative to link.xml that has existed for many years, The `[Preserve]` attribute. You would need to put that on each property that you want to survive code stripping. It can still be a tedious if you have a lot of properties. Preserving the entire assembly may still be a better option for you.

    Some long term context. UnityLinker is a super set of monolinker/ILLinker. Microsoft's long term vision for code stripping and serialization is Source Generators. They explain in slightly more detail here.

    -Mike
     
    De-Panther likes this.