Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

New Unity WebGL Embedding API White Paper

Discussion in 'Web' started by alexsuvorov, Sep 13, 2016.

  1. ColossalObelisk

    ColossalObelisk

    Joined:
    Oct 24, 2014
    Posts:
    3
    May I get some help/advice for injecting the name of the build's json file automatically?
    What if I set up my template after building into the "foo" folder with the following:
    Code (JavaScript):
    1. <script>
    2.           var world = UnityLoader.instantiate("container", "Build/foo.json", { Module: { TOTAL_MEMORY: 0x20000000 } });
    3. </script>
    Then I decide to do a build into the "bar" folder. Now my game fails to load, because I had to hard code foo.json into the template. Is there a template tag I can use?

    P.S. It would be great to put a warning on the Unity Manual's "Using WebGL Template" page indicating it is deprecated
     
  2. DukeRoderick

    DukeRoderick

    Joined:
    Dec 25, 2015
    Posts:
    15
    You can find the templates that actually come built in Unity at: {your install location}\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\WebGLTemplates\Default

    To answer your question specifically here is the line from their default template:

    Code (CSharp):
    1. var gameInstance = UnityLoader.instantiate("gameContainer", "%UNITY_WEBGL_BUILD_URL%", {onProgress: UnityProgress});
    %UNITY_WEBGL_BUILD_URL% will become the .json file location.
     
    alxcancado and ColossalObelisk like this.
  3. ColossalObelisk

    ColossalObelisk

    Joined:
    Oct 24, 2014
    Posts:
    3
    @DukeRoderick That worked perfectly; thanks for the quick reply.
     
  4. alexsuvorov

    alexsuvorov

    Unity Technologies

    Joined:
    Nov 15, 2015
    Posts:
    327
    Hello Foriero.

    From your screenshot it seems that you are using the Default WebGL template (with the logo and the fullscreen button). Have you tried to use the Minimal template with the following adjustment:
    Code (html):
    1. var gameInstance = UnityLoader.instantiate("gameContainer", "Build/TEST.json", { width: "100%", height: "100%" });
    2. ...
    3. <body style="margin: 0">
     
  5. alexsuvorov

    alexsuvorov

    Unity Technologies

    Joined:
    Nov 15, 2015
    Posts:
    327
    Hello MartijnDekker.

    If you want to control when the game starts, you can use Module.addRunDependency function. At the time when the module is instantiated, the framework is not loaded yet, so you can not use Module.addRunDependency directly, but you can schedule its execution using Module.preRun array. In the following example the dependency will be added as soon as the build framework code is executed, and will be removed after 10 seconds timeout (note, that you are free to remove the dependency in any other handler, for example, when some "Play" button is clicked).

    Code (JavaScript):
    1. var gameInstance = UnityLoader.instantiate("gameContainer", "Build/build.json");
    2. gameInstance.Module.preRun.push(function () {
    3.   gameInstance.Module.addRunDependency("delayed start");
    4.   setTimeout(function () {gameInstance.Module.removeRunDependency("delayed start");}, 10000);
    5. });
    The problem here is that the browser normally hangs during the asm.js or WebAssembly compilation, and not during the build initialization. Delaying the compilation is also possible but would be a bit more complicated. First try the solution above and let me know if this appears to be not sufficient for you (i.e if you actually need to delay the compilation step).
     
    Last edited: Apr 18, 2017
  6. MadMoonRising

    MadMoonRising

    Joined:
    Nov 7, 2016
    Posts:
    5
    Coud I ask how to implement this into the Kongregate template? I can see how it works in the thread and how it makes things more dynamic with code changes but I can't seem to modify the Kong template code. There are a couple of these templates around, the one i've used pre-5.6 is at Github https://github.com/kongregate/webgl-preloader

    If anyone has access to a newer 5.6 version of this I'd like to know.
     
    alxcancado likes this.
  7. alxcancado

    alxcancado

    Joined:
    Aug 17, 2013
    Posts:
    13
    Good news, Kongregate just updated it for us!
    https://github.com/kongregate/webgl-preloader
     
  8. xlabrom

    xlabrom

    Joined:
    Apr 21, 2013
    Posts:
    4
    for disable compatibilityCheck message on mobile devices
    Code (CSharp):
    1. UnityLoader.compatibilityCheck = function(e,t,r) { t() };
    2. var gameInstance = UnityLoader.instantiate("gameContainer", "Build/TEST.json", { width: "100%", height: "100%" });
     
  9. MadMoonRising

    MadMoonRising

    Joined:
    Nov 7, 2016
    Posts:
    5
  10. stephanwinterberger

    stephanwinterberger

    Joined:
    Aug 22, 2016
    Posts:
    27
    @alexsuvorov I'm coming back to this thread because old problems arise again. Previously you said that parsing time is not significant. I always disagreed but with asm.js it was handleable (loading and starting Unity in background was acceptable). Then I tried wasm and on Chrome the browser totally freezes for many seconds (so no chance to do anything in background!).

    The wasm build made it even worse for us. The UI is completely blocked for seconds.

    Are there any tricks to improve this problems? This is a real deal breaker for us!
     
  11. ThainaYu

    ThainaYu

    Joined:
    Nov 4, 2016
    Posts:
    18
    Can we have `SendMessage(instanceID, "myFunction", "foobar");` in unity webgl?

    So we could have unity interop calling callback function easily

    Name of gameobject can be easily changed to duplicate (Actually function in difference script can too)
    So it would really be appreciated if we have better way we can send callback function between system
     
  12. r3dwolf

    r3dwolf

    Joined:
    Feb 16, 2012
    Posts:
    39
    Hi,
    I need to put a background image while loading, instead the color background.
    How can it be done?
    I tried to remove the backgroundColor option in json file parameter but the DIV is set anyway to a default color
     
    Last edited: May 5, 2017
    kenshin likes this.
  13. alexsuvorov

    alexsuvorov

    Unity Technologies

    Joined:
    Nov 15, 2015
    Posts:
    327
    Hello stephanwinterberger.

    Currently WebAssembly compilation in Chrome is performed synchronously and will inevitably block the page UI. There is currently no workaround for it and no way to fix this from the Unity side. This issue is temporary and is expected to be resolved in the future versions of Chrome.

    Just recently the WebAssembly module caching support has been added to Chrome. The caching support is being tested at the moment and might be added to Unity in the near future. This will help to reduce the loading time in Chrome for returning users (but not for the first time launch).
     
  14. alexsuvorov

    alexsuvorov

    Unity Technologies

    Joined:
    Nov 15, 2015
    Posts:
    327
    Hello ThainaYu.

    The new embedding scheme isolates the build code from the page code, which is very convenient if you want to embed your build on an arbitrary page, or embed multiple games on the same page.

    When developing the layer of interaction between the page and the build, you may always assume that there are other builds running on the same page at the same time. For this reason you might want to embed all the build related JavaScript code into your project in a form of .jslib or .jspre plugins. The main idea here is that the JavaScript plugin code is always running in the scope of the build, so, for example, you can just call the SendMessage from the JavaScript plugin directly, without even knowing how your build was embedded on the page.

    You only need the reference to the game instance when the embedding page itself tries to send some data to the build. In which case if should explicitly specify which instance it wants to send the data to (i.e. using myGameInstance.SendMessage). This also means that there is some JavaScript code on that embedding page which is expecting a specific build, is highly integrated with that build, and most likely is essential for the build functioning. If this really is the case, then it would probably make more sense to just make that JavaScript a part of that build. Of course that is not always an easy thing to do, but it will let your build to be embedded on other pages as well.

    Could you give a specific example where you are not able to achieve necessary interaction by just using a JavaScript plugin embedded in the build (except the case of authorization on a specific portal, where it is assumed that the portal page provides the authorization layer)?
     
    ThainaYu likes this.
  15. alexsuvorov

    alexsuvorov

    Unity Technologies

    Joined:
    Nov 15, 2015
    Posts:
    327
    Hello r3dwolf.

    The standard way to do this is through the Splash Image settings. Add an image to your assets, change its texture type to Sprite, go to File - Build settings... - Player settings... - WebGL settings - Splash Image - Background, drag your sprite into the Background Image. You can also find additional information here https://docs.unity3d.com/Manual/class-PlayerSettingsSplashScreen.html
     
  16. stephanwinterberger

    stephanwinterberger

    Joined:
    Aug 22, 2016
    Posts:
    27
    Thanks for your answer. I totally understand that Chrome handles this poorly but I don't like the Unity-WebGL-Philosophy. I don't think it is enough to blame the browsers. There are so many promises for the future but why aren't you optimizing for the current web-platform? There could be so much done to provide a convenient web experience, for example smaller build size, async code loading, better code striping etc... Please improve Unity-WebGL for the current state of the web! Many of our users aren't on the latest browser versions and it will take very long until all the neat features arrive at our users browsers.
     
    chriszul and ThainaYu like this.
  17. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    Do you happen to know if there is an issue report for this in Chromium/Chrome? If so, could you provide the link so we can track status?

    This was a major upside to us for switching to WebAssembly and it is very disappointing to hear that Chrome is still page-blocking on compilation.

    Thanks
     
    ThainaYu likes this.
  18. pseudowok

    pseudowok

    Joined:
    Jan 3, 2013
    Posts:
    3
    Hi,
    Previously we were able to get status messages as the module loaded such as:
    "Preparing..."
    "Downloading (0 / x)..."
    "Running..."

    Is it possible to get these messages for feedback to the user?

    Also, is there a list of all the events, such as "onRuntimeInitialized"?

    Thanks!
     
  19. Briner

    Briner

    Joined:
    Jul 8, 2015
    Posts:
    25
    Hi guys.

    For all those who have problems with the new WebGL embed API in 5.6, I have created an asset to facilitate the work, an template to solved the common problems like not downloading, loading or progress text and other new features like loading indicator and an smooth transition to the game after load the content, check out here: http://u3d.as/PHt



    PS: hope this is not off topic.
     
  20. alexsuvorov

    alexsuvorov

    Unity Technologies

    Joined:
    Nov 15, 2015
    Posts:
    327
    Hello pseudowok.

    In previous versions of Unity most of the loading functionality has been performed sequentially. This is why it was possible to easily track the loading steps. Starting from 5.6 most of the loading and initialization is performed in parallel, which means that "Downloading (0 / x)..." no longer makes much sense. The new approach reduces the total loading time, as now most asynchronous operations can be performed in parallel, it also gives advantage when some files are already present in the browser cache, or when the serving speed is limited per connection. As soon as the loader receives the headers for all the currently downloaded files, it can determine the total download size and estimate the current progress. In cases when the server does not provide the Content-Length header for the file, it's ratio against the total progress is approximated (i.e. if you are downloading 4 files, and the server does not provide information about the file size, each of the downloaded files will be assigned 25% of the total progress, and you will see the loading bar filled in 4 discrete steps).

    The biggest inconvenience at the moment is that although you can track the download progress, there is currently no reliable way to track the progress of the compilation. Moreover, in some browsers compilation might block the main thread, which can lead to the progress bar being stuck for a few seconds.

    Normally, it is sufficient to just override the onProgress function in the following way:
    Code (JavaScript):
    1. var gameInstance = UnityLoader.instantiate("gameContainer", "Build/build.json", {onProgress: MyProgressFunction});
    where MyProgressFunction(gameInstance, progress) will be called with progress equal to 0 when files are scheduled for download, equal to the download progress (0..1) during file download, and equal to 1 after all the files have been downloaded. This way you will be able to track at least 3 stages: "initialization", "file download", "startup".
     
    Last edited: May 10, 2017
    JonBowen likes this.
  21. alexsuvorov

    alexsuvorov

    Unity Technologies

    Joined:
    Nov 15, 2015
    Posts:
    327
    Yes, I believe this issue is related https://bugs.chromium.org/p/v8/issues/detail?id=6003

    The good news is that in Chrome Canary 60.0.3094.0 WebAssembly compilation is already asynchronous. So you can expect the same improvement in the release version of Chrome soon.
     
    ThainaYu and JonBowen like this.
  22. ThainaYu

    ThainaYu

    Joined:
    Nov 4, 2016
    Posts:
    18
    Sorry that I don't make it clear but `SendMessage` I mean there is `SendMessage` in the .jslib itself

    The jslib is a good approach to do things. But currently now it seem there are so many limitation to work with. One main problem now is handling callBack from third party

    For example, I use firebase database in js with unity webgl. There is a library that can listen to data changed in js sdk

    Code (JavaScript):
    1.  
    2. // MyFirebasePlugin.jslib
    3. ...
    4. var starCountRef = firebase.database().ref("user/" + userID + "/starCount");
    5. starCountRef.on('value', function(snapshot) {
    6.   SendMessage("FirebaseWrapper","UpdateStar",snapshot.val());
    7. });
    8. ...
    9.  
    The problem is I don't really sure that there would be no gameobject named "FirebaseWrapper" would be created again in the game. Unity gameObject could be named anything without unique checking. What happen if there are 2 gameobject named "FirebaseWrapper" ? Would it call both? Would it call the wrong one?

    Worse than that, this problem is the same for the function name. What happen when that `FirebaseWrapper` object has another component that contain function with the same name?

    Currently now I must do so many complicate thing such as making static functions as a callBack listener. Make a dictionary to register callBack to bridge between js and C#. Put the [AOT.MonoPInvokeCallbackAttribute] on one function and use that as a gateway for other listener

    That's why I said I really wish that I could easily send callback between C# and jslib. It should be easy as just

    Code (CSharp):
    1.  
    2. static class FirebaseWrapper
    3. {
    4.     static extern RegisterFirebaseDBListener(Action<string> onCallBack);
    5. }
    6.  
    7. // in any class
    8. FirebaseWrapper.RegisterFirebaseDBListener((json) => {
    9.     // update data
    10. });
    11.  
    Code (JavaScript):
    1.  
    2. // MyFirebasePlugin.jslib
    3. ...
    4. RegisterFirebaseDBListener : function(cb) {
    5.     var starCountRef = firebase.database().ref("user/" + userID + "/starCount");
    6.     starCountRef.on('value', function(snapshot) {
    7.         cb(JSON.stringify(snapshot.val()));
    8.     }
    9. });
    10. ...
    11.  
    Currently now there are so many things we need to handle such as making buffer and free it. Wrapping function callBack as dictionary like like I did. And many. It should be easier

    Another way might be making new function. such as `SendToCallBack`

    Code (JavaScript):
    1.  
    2. // MyFirebasePlugin.jslib
    3. ...
    4. RegisterFirebaseDBListener : function(cb) {
    5.     var starCountRef = firebase.database().ref("user/" + userID + "/starCount");
    6.     starCountRef.on('value', function(snapshot) {
    7.         // SendToCallBack first parameter is callBack function, other is that callBack parameter
    8.         SendToCallBack(cb,snapshot.val()); // using unity json serializer
    9.     }
    10. });
    11. ...
    12.  
     
    Last edited: May 12, 2017
  23. alexsuvorov

    alexsuvorov

    Unity Technologies

    Joined:
    Nov 15, 2015
    Posts:
    327
    Hello ThainaYu.

    SendMessage allows you to interact with dynamically created objects referenced by symbolic names. In most situations this approach is very convenient, however, in some special cases, i.e. when you only operate on static methods, it might introduce some inconvenience and unnecessary overhead.

    If there are no objects in the scene with the name matching the 1st SendMessage argument, you will see a notification message in the browser console about it. No exception is thrown and execution continues normally. SendMessage currently does not return any value, so there is no immediate information about the operation success.

    If there are multiple objects in the scene, with names matching the 1st SendMessage argument, then only one of those objects will receive the message (normally it is the object which was created first, but generally there is no way to know which one will receive the message).

    If there are multiple script components attached to the object, which name matches the 1st SendMessage argument, then all the methods which names match the 2nd SendMessage argument, from all the scripts attached to the destination object, will be called. The order of those methods calls is not defined.

    I believe currently you can only call static C# methods from JavaScript, also you need to use [MonoPInvokeCallback] on those methods. The main inconvenience here is that C# scripts are first converted into C++ with IL2CPP, so any assumptions about the compiled C# code or final function names would be specific to the current version of Unity. On the other hand, C plugins are directly compiled with Emscripten and are not preprocessed. This means that you can export a function from a C plugin and reliably call it from JavaScript, as its name will not be modified or mangled. You can use EMSCRIPTEN_KEEPALIVE macro to export a C function and make sure that it does not get stripped.

    Your example can be implemented without using SendMessage in the following way.

    Add the following Assets/Plugins/callback.с plugin to your project:
    Code (C):
    1. #include "emscripten.h"
    2.  
    3. void EMSCRIPTEN_KEEPALIVE SendToCallBack(void (*callback)(const char*), const char *json) {
    4.   callback(json);
    5. }

    Add the following Assets/Plugins/callback.jslib plugin to your project:
    Code (JavaScript):
    1. mergeInto(LibraryManager.library, {
    2.   RegisterFirebaseDBListener: function (callback) {
    3.     setInterval(function () {
    4.       ccall("SendToCallBack", null, ["number", "string"], [callback, "{result: \"OK\"}"]);
    5.     }, 1000); // simulate FirebaseDB callbacks
    6.   },
    7. });

    Now you can use the following script (based on your code):
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Runtime.InteropServices;
    3.  
    4. static class FirebaseWrapper {
    5.     [DllImport("__Internal")]
    6.     public static extern void RegisterFirebaseDBListener (System.Action<string> callback);
    7. }
    8.  
    9. public class NewBehaviourScript : MonoBehaviour {
    10.  
    11.     [AOT.MonoPInvokeCallback (typeof (System.Action<string>))]
    12.     static void myCallback(string json) {
    13.         Debug.Log("Callback executed with: " + json);
    14.     }
    15.  
    16.     void Start () {
    17.         FirebaseWrapper.RegisterFirebaseDBListener (myCallback);
    18.     }
    19. }
    This should also work somewhat faster than SendMessage, because you are just calling a static method, and there is no need to resolve the symbolic name of a dynamic game object.
     
  24. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,157
    Well that what I want to express. It hard to control which one is the first symbolic name

    Symbolic name is convenient but it hard to control and handle in many cases. So I wish unity should have some alternative option aloong with normal SendMessage. That why I suggest the SendMessage with InstanceID as another function for unity object and in the webgl jslib

    And also I think the most common usage that we need is lambda expression as callBack function

    I mean when we call any javascript library. We normally use

    Code (JavaScript):
    1.  
    2. ListeningToSomething((data) => {
    3.     // Do Something with Data in js
    4. });
    5.  
    And so when we try to wrap this kind of function in C#. I would like to use it in the same manner as C# expression

    Code (CSharp):
    1.  
    2. static extern void ListeningToSomething(Action<string> data);
    3.  
    4. IEnumerator Start()
    5. {
    6.     string data = null;
    7.     bool getCallBackFromJS = false;
    8.     ListeningToSomething((result) => {
    9.         getCallBackFromJS = true;
    10.         data = result;
    11.  
    12.         // Want to write it as easy as this
    13.         // Not a static function or even SendMessage
    14.         // Just making lambda expression directly in this case
    15.     });
    16.  
    17.     yield return new WaitUntil(() => getCallBackFromJS);
    18.  
    19.     // Work with data
    20. }
    21.  
    Thank you very much for your recommendation. I would try to implement it and see the result

    But if there is something like this I wish it should be implemented as a standard alternative to SendMessage in the next version of unity
     
    Last edited: May 19, 2017
  25. gtiberiu

    gtiberiu

    Joined:
    May 25, 2017
    Posts:
    1
    Hello!

    I'm trying to handle errors and compatibility checks using 2 functions I place as parameters in the Module when the build is instantiated by UnityLoader. Here's my code:

    Code (JavaScript):
    1.       var gameInstance = UnityLoader.instantiate("container", "Build/2017-05-25.json", {onProgress: UnityProgress, Module : {
    2.               TOTAL_MEMORY: 268435456,
    3.               errorhandler: function(err, url, line) {
    4.                   console.log ("Exception detected!!!");
    5.                   alert("error " + err + " occurred at line " + line);
    6.  
    7.                   // return true so Unity's error handler is not executed.
    8.                 return true;
    9.               },
    10.               compatibilitycheck: function () {
    11.                 console.log ("compatibilitycheck index");
    12.                 var isMobile = IsMobile ();
    13.                 if (isMobile) {
    14.                   var r = confirm("Mobile platforms detected!");
    15.                   if (r == false) {
    16.                     ///
    17.                   }
    18.                 }
    19.               }
    20.       }
    21.     });
    However, the exceptions and compatibility checks are not handled by the 2 functions from the code above, but by the functions in the UnityLoader.

    Can you tell me what am I doing wrong?

    Thanks
     
  26. imDJK

    imDJK

    Joined:
    Apr 2, 2014
    Posts:
    2
    Hello,

    We were using the this.Clear() function from the old UnityProgress.js to hide our custom loading screen but now this no longer works, any alternative for this certain type of action?
     
  27. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    Sorry to revive this from the dead, but I cant seem to find a full status on this issue.
    This page seems to suggest that this issue will be addressed in v61: https://wasmdash.appspot.com/
    But none of the 60 or 61 (beta or otherwise) release notes mention async WebAssembly compilation.
    Nor mention of it here: https://www.chromestatus.com

    Is there any update on this particular Chrome bug or am I looking in the wrong places?
    Thanks.
     
  28. nickrapp

    nickrapp

    Administrator

    Joined:
    Oct 5, 2015
    Posts:
    54
    @sirrus the bug alex linked is the correct one IIRC, but I was just able to confirm with the Chrome team that the fix for async wasm compilation is now targeting m61
     
    sirrus likes this.
  29. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    Thank you!!!
     
  30. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    Just following up on this (I can make a separate thread if desired).

    I am using Chrome Canary v62.0.3200.0 for testing. Between the time the WebAssembly module is instantiated, onRuntimeInitialized is called and when a basic empty game scene is loaded, any interaction with the existing page UI is still halting.

    For example, we have a loading sequence which includes some HTML5 animations and interactive buttons. The animation halts and the buttons become completely unclickable while the wasm is compiling.

    My expectation is that this should not happen if everything is asynchronous, as it should not block the main browser thread. Any thoughts?
     
  31. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    Sorry to bump this but since Chrome 61 was a stable release today, I wanted to see if my expectation on smooth loading WASM is accurate or not realistic.

    Is there an example where asynchronous WASM compilation happens simultaneously with a loading/progress bar (or any sort of movement) and DOESNT block page UI?
     
  32. Marco-Trivellato

    Marco-Trivellato

    Unity Technologies

    Joined:
    Jul 9, 2013
    Posts:
    1,654
    I don't think async compilation is in yet in 61.
     
  33. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    OK.. Now I'm confused :). So @nickrapp's source was incorrect or the feature is just delayed further?
     
  34. Marco-Trivellato

    Marco-Trivellato

    Unity Technologies

    Joined:
    Jul 9, 2013
    Posts:
    1,654
    My bad. I just tested Chrome 61 and it does not stall, so that indicates asynchronous compilation is there.
     
  35. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    Marco, do you have an example available that shows smooth loading? Perhaps in our tests, its not the compilation that is causing "jankiness" but the instantiation of the scene, somehow? Can I send you a sample link?
     
  36. Marco-Trivellato

    Marco-Trivellato

    Unity Technologies

    Joined:
    Jul 9, 2013
    Posts:
    1,654
    I guess it depends what you mean by smooth loading. Does the progress bar does not advance or is it stuck on black screen?
    sure.

    On this topic, I should mention that we are looking into the current loading flow, hoping to improve it and inform the end-user about what's actually happening.
     
  37. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    Sent you a PM.

    Our loading process is somewhat faked based on the current loading data that we receive from the loader. We're moving to just hide it all behind an interactive introduction anyway to avoid any problems. The UI stall makes that approach less effective, however.

    Definitely looking forward to new loading feedback!

    Thanks.
     
  38. ywj7931

    ywj7931

    Joined:
    Jun 24, 2015
    Posts:
    41
    Is there a way to get load time? Right now, sometimes it loads the game after 99%, sometimes it loads the game after 75% if there is cache. Is there a listener we can listen for starting loading the game?
     
  39. ywj7931

    ywj7931

    Joined:
    Jun 24, 2015
    Posts:
    41
    I deploy my webGL on AWS. But it seems no difference of loading time between no header or "content-encoding: gzip". I just changed those files ending with ".unityweb" to "content-encoding: gzip" in S3 bucket. Is that enought? Why I didn't see any difference? :(
     
  40. ProfPivec

    ProfPivec

    Joined:
    Sep 21, 2012
    Posts:
    28
    I have a problem with loading bar for WebGL. Cannot seem to solve this and would appreciate some help please.

    Our game is around 80mb and hence needs to use gzip compression, otherwise the load from an Apache server takes around 5minutes. With gzip implemented, the download takes around 1 minute.

    Unfortunately, with gzip on, the loading bar no longer works happily. Without gzip, it increments smoothly. With gzip, it increments only 4 times (22, 45, 67 & 90%), which appears to be once for each on the unity files.

    I have set everything for gzip on the server and have content header in the html meta tag. Still no joy.

    I have also tried all the free and paid for WebGL loaders on the asset store, and they all react the same. I have also read on many forums, "just turn off gzip", but this is not an option.

    They only thing that appears left is to fake the progress bar, which I really do not wish to do.

    Any help, or will this not work?

    Thanks in advance, Please?
     
    Last edited: Jan 15, 2018
  41. ammarvohra

    ammarvohra

    Joined:
    Jan 24, 2016
    Posts:
    10
    Hello everyone,

    I am making WebGL game with Unity 5.5.1 and I would like to make an HTML page with initial screens like login & register pages, I would like to have a work flow as following(visual flow is also attached as image):

    1) Load the pre-game screens (login, register, forgot password)
    2) As soon as these pages are loaded, we should display them.
    3) Once displayed, we should start loading the game in the background, it will be seamless for the end-user — in the meantime, the end-user can proceed with either his registration or login
    4) When the user clicks "Log in", the game should be already loaded by then, and therefore the user can play straightaway OR the game is not loaded yet, and the user can see the loading screen until the game is loaded.

    Can anyone provide me the solution how to achieve this? Also if this is not possible how can I reduce load time which right now takes 1 minute to load completely, aroung 20MB of total with .data, .asm, .js and etc files. I have optimized my project fully with most of the possible solutions.

    @alexsuvorov could you share some ideas for this?

    Thanks to all for your time and help. :)
     

    Attached Files:

  42. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    Hi guys, i wanted a way to dynamically change builds within an iframe for my humble webpage.

    I made below master.html, so now you can:
    - use master.html to load any build from any subfolder
    - you only need this single master.html and a UnityLoaderFolder in your web-root
    (UnityLoaderFolder contains UnityLoader.js, UnityProgress.js and the templateData stuff)
    - switch build files and resize the window anytime without doing a full page reload

    Code (CSharp):
    1. <!DOCTYPE html>
    2. <html lang="en-us">
    3.  
    4.     <head>
    5.         <meta charset="utf-8">
    6.         <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    7.         <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
    8.  
    9.         <title>Master Frame</title>
    10.         <link    rel="shortcut icon"    href="UnityLoaderFolder/favicon.ico">
    11.         <link    rel="stylesheet"    href="UnityLoaderFolder/style.css">
    12.  
    13.         <!-- imports -->
    14.         <script    src="UnityLoaderFolder/UnityProgress.js"></script>
    15.         <script    src="UnityLoaderFolder/UnityLoader.js"></script>
    16.  
    17.         <!-- dynamic fileLoading-->
    18.         <script>
    19.  
    20.             //1. change to your domain
    21.             document.domain        = 'marrtgames.com';
    22.  
    23.             //2. refer to your required filename here
    24.             var playerFileID    = parent.myCurrentPlayerFile;
    25.  
    26.             //3. adjust your playerFile folder path, when generated by Unity, it is found like that: "YourBuildName/Build/YourBuildName.json". But the Build folder content is sufficient
    27.             var playerFile        = "playerFiles/"+playerFileID+"/"+playerFileID+".json";    //--> myWebSite/playerFiles/YourBuildName/YourBuildName.json
    28.      
    29.             //4. adjust your player settings
    30.             var gameInstance = UnityLoader.instantiate( "gameContainer", playerFile, {
    31.                 onProgress    : UnityProgress,
    32.                 width        : parent.curWidth+'px',
    33.                 height        : parent.curHeight+'px'
    34.             });
    35.  
    36.             FetchResolution();
    37.  
    38.  
    39.             //change resolution on the fly CAUTION: unity generates the canvas element with the id "#canvas" which should only be "canvas". '#\\#canvas' searches for id = "canvas"
    40.             function FetchResolution(){
    41.                 $('#\\#canvas').width(parent.curWidth+'px').height(parent.curHeight+'px');    //console.log("Resolution Set: "+parent.curWidth+"x"+parent.curHeight);
    42.             }
    43.  
    44.             function SetFullscreen(){
    45.                 gameInstance.SetFullscreen(1);
    46.             }
    47.  
    48.         </script>
    49.     </head>
    50.  
    51.     <body id="body" style="margin:0; " >
    52.         <div class="webgl-content" style="margin:0; display: contents;">
    53.           <div id="gameContainer" style="margin:0;"></div>
    54.         </div>
    55.     </body>
    56.  
    57. </html>

    Untested, because this is a bare-bone thing of what i used, but adding these things to your page should make it work, master.html accesses "myCurrentPlayerFile"
    Code (CSharp):
    1. <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
    2. <script type="text/javascript">
    3.  
    4.     var myCurrentPlayerFile;
    5.  
    6.     function loadPlayer( var myBuildName ){
    7.         myCurrentPlayerFile = myBuildName;
    8.         $('#unityIFrame').attr("src", 'master.html');    //unloads iframe
    9.     }
    10.     function unloadPlayer(){
    11.         $('#unityIFrame').attr("src", '');    //loads iframe
    12.     }
    13.  
    14. // you can also call master.html functions by accessing the iFrame-element, make sure id is correct
    15. //document.getElementById("unityIFrame").contentWindow.FetchResolution();
    16.  
    17. </script>
    18.  
    19. //somewhere in your page:
    20. <button onclick="loadPlayer('myBuild')"    type="button">Game01</button>
    21. //AND the iframe target
    22. <iframe id="unityIFrame" src="" style="border:0px #000000 none;" scrolling="no" name="Game name"></iframe>



    I also got a question:
    Why does firefox load my webGLs in 2s while Chrome|Vivaldi|Edge take like 10s?
    Is if because of "asm.js AOT compilation" (https://docs.unity3d.com/Manual/webgl-browsercompatibility.html)
     
    Last edited: Jul 1, 2018
    tolosaoldfan likes this.
  43. MFKJ

    MFKJ

    Joined:
    May 13, 2015
    Posts:
    264
    Can anyone tell me that how can i get location of the json file in C#
    Code (CSharp):
    1. var myGame = UnityLoader.instantiate(gameContainer, "http://mydomain/myfolder/Build/mygame.json");
    Because i want to load it in C# for getting some values of the json file. Actually i want to add some assetbundle location information into json file so that i can get it from their.
     
  44. leedongwon

    leedongwon

    Joined:
    Jun 20, 2019
    Posts:
    8
    I want to change the .json call part in html.
    Remove the .json from the Build folder and save the json contents in html.

    Code (CSharp):
    1. <script>
    2.       var gameInstance = UnityLoader.instantiate("gameContainer", "Build/Storm_Build.json");
    3.     </script>
    this part

    Code (CSharp):
    1. <script>
    2.     var json = '{\
    3. "companyName": "MeetupAR",\
    4. "productName": "TyphoonFloodRiskAssessment",\
    5. "dataUrl": "Storm_Build.data.unityweb",\
    6. "wasmCodeUrl": "Storm_Build.wasm.code.unityweb",\
    7. "wasmFrameworkUrl": "Storm_Build.wasm.framework.unityweb",\
    8. "TOTAL_MEMORY": 268435456,\
    9. "graphicsAPI": ["WebGL 2.0", "WebGL 1.0"],\
    10. "webglContextAttributes": {"preserveDrawingBuffer": false},\
    11. "splashScreenStyle": "Dark",\
    12. "backgroundColor": "#231F20"\
    13. }';
    14.     var data = JSON.parse(json);
    15.       var gameInstance = UnityLoader.instantiate("gameContainer", data);
    16.     </script>
    This results in an error.
    Code (CSharp):
    1. Invoking error handler due to
    2. JSON.JSON.parse Error: Valid character at position:1
    Please tell me what to do.
     
  45. lightmapper

    lightmapper

    Joined:
    Jan 14, 2015
    Posts:
    27
    I think instantiate accepts a URL or file path not a json object. You can take a look at UnityLoader.js and possibly modify it to suit your needs.
     
  46. JohnnyRouddro

    JohnnyRouddro

    Joined:
    Mar 12, 2018
    Posts:
    2
    Putting the unityContainer inside another container with same width and margin: auto seems to work for me.

    Code (JavaScript):
    1. <body>
    2.     <div style=" width: 960px; margin: auto">
    3.       <div id="unityContainer" style="position: relative; width: 960px; height: 600px"></div>
    4.     </div>
    5.   </body>
     
  47. AryanJumani

    AryanJumani

    Joined:
    Sep 6, 2018
    Posts:
    14
    Hi, I know it is a bit late, but I just wanted to know how do I uninstantiate(or destroy) the webgl on a button click?
     
  48. MFKJ

    MFKJ

    Joined:
    May 13, 2015
    Posts:
    264
    unityInstance.Quit(function() {
    console.log("done!");
    });
    unityInstance = null;

    You can see the details.