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

Call JavaScript function in index.html from WebGL

Discussion in 'Web' started by duna_2012, Feb 6, 2019.

  1. duna_2012

    duna_2012

    Joined:
    Oct 16, 2018
    Posts:
    1
    Hello, I need to call the JavaScript function from my game on WebGL. I need to send the information in the form of Json to the js function in index.html. I thought to use
    Code (CSharp):
    1. Application.ExternalCall()
    , but it is deprecated. How I can do this?
     
  2. raiapplication

    raiapplication

    Joined:
    May 10, 2019
    Posts:
    4
    I have the same question
     
  3. AliAnkara

    AliAnkara

    Joined:
    Dec 17, 2017
    Posts:
    7
    I have the same question
     
  4. De-Panther

    De-Panther

    Joined:
    Dec 27, 2009
    Posts:
    589
    Logic_Bomb likes this.
  5. AliAnkara

    AliAnkara

    Joined:
    Dec 17, 2017
    Posts:
    7
    I know you said this and I don't want it.
    how to call JavaScript function in index.html from WebGL?

    example;

    <script>
    function test(val){
    console.log(val);
    }
    </script>
     
  6. De-Panther

    De-Panther

    Joined:
    Dec 27, 2009
    Posts:
    589
    You already got your answer. Use .jslib file. ExternalCall is deprecated. The only way you have is to use DllImport, Call from C# to a method in .jslib file, and from that method to call the JS method in the web page.
     
    Logic_Bomb likes this.
  7. nsbuluchai

    nsbuluchai

    Joined:
    Dec 11, 2019
    Posts:
    1
    Found any solution ?
     
  8. AliAnkara

    AliAnkara

    Joined:
    Dec 17, 2017
    Posts:
    7
    Sorry but no...
    it's problem stands on one side :)
     
  9. massimofellucci

    massimofellucci

    Joined:
    Feb 27, 2018
    Posts:
    5
    Hi, did you find an answer to your question?
     
  10. De-Panther

    De-Panther

    Joined:
    Dec 27, 2009
    Posts:
    589
    Use .jslib file...
     
    Pullahs likes this.
  11. massimofellucci

    massimofellucci

    Joined:
    Feb 27, 2018
    Posts:
    5
    yes, but i don't know how to reference a function from index.html file.
     
  12. De-Panther

    De-Panther

    Joined:
    Dec 27, 2009
    Posts:
    589
    If there's only one instance of unity in the page, and there are no other functions with that name, you can set the function as a global function in the page. something like:
    Code (JavaScript):
    1. window.yourFunctionName = function () { ... };
    And then inside a function in the .jlib file you can call:
    Code (JavaScript):
    1. window.yourFunctionName();
    You can check if it exist, just to be sure:
    Code (JavaScript):
    1. if (window.yourFunctionName)
    2. {
    3.   window.yourFunctionName();
    4. }
     
  13. bruceb85

    bruceb85

    Joined:
    Sep 26, 2020
    Posts:
    45
    Can you clarify with a working example? Doesn't appear to do anything.
     
  14. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
  15. bruceb85

    bruceb85

    Joined:
    Sep 26, 2020
    Posts:
    45
    Yes I've read through that guide, and I've been able to call functions in .jslib plugin folder from unity c#.

    My issue (possibly unrelated to unity) is I need the jslib function to call functions in a different .js file (processing.js, which is located in the same folder as the index.html).

    I have referenced the .js file in index.html
    <script src="processing.js"></script>

    However, when I attempt to call a function located in processing.js from .jslib I get the following:
    upload_2020-10-9_14-46-38.png

    What would be the correct way for me to call functions in processing.js from .jslib?
     
  16. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    if you get an error "Can't find variable: myTest", then it means that the JavaScript global scope does not contain that variable. This is not a Unity issue, but a general JavaScript development issue. Your script file processing.js should have in its global scope a line

    var myTest = 10;

    or a statement window.myTest = 10;

    and it should load up before the function that references it is executed.

    You can test what variables you have available in the JS global scope by using the Chrome DevTools Console (https://developers.google.com/web/tools/chrome-devtools/console)
     
    xiangshushu and De-Panther like this.
  17. bruceb85

    bruceb85

    Joined:
    Sep 26, 2020
    Posts:
    45
    Why is it looking for a variable?
    This is the function in my .js file I want to call:
    Code (JavaScript):
    1. function myTestFunc()
    2. {
    3. alert("myTestFunc() in processing.js called!")
    4. }
    I am using this to call that function from .jslib:
    Code (JavaScript):
    1. mergeInto(LibraryManager.library, {TestMe: function () {
    2.  
    3.              window.alert("Hello .jslib' ");
    4.              myTestFunc();
    5.                                                          
    6.           },
    7.  
    8.            
    9.  
    10.  
    11. });
    window.alert("Hello .jslib' "); pops up just fine
    myTestFunc(); can't find var myTestFunc error
     
    Last edited: Oct 9, 2020
  18. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    It is not looking for a variable specifically, but because it does not see the thing, it does not know what type it is even supposed to be.

    Try changing that to

    Code (JavaScript):
    1. console.log('is this code even executed?');
    2. function myTestFunc()
    3. {
    4. alert("myTestFunc() in processing.js called!")
    5. }
    6. console.log('what scope am I currently in:');
    7. console.log(this); // Should print out "Window".
    8. window.myTestFunc = myTestFunc; // If the above does not print out Window, we are in a nested scope in this .js file, so export myTestFunc out to global scope.
    and then open up the browser console after loading. You should see the above log prints occur, and the `this` variable print out `Window`. If not, then your .js file is not creating a function in the global scope.

    Try changing that to

    Code (JavaScript):
    1. mergeInto(LibraryManager.library, {TestMe: function () {
    2.               console.log(typeof myTestFunc); // should print out 'function'
    3.               console.log(typeof window.myTestFunc); // should print out 'function' as well.
    4.               window.alert("Hello .jslib' ");
    5.              myTestFunc();                                            
    6.           },
    7. });
    If `typeof window.myTestFunc` prints undefined, then the processing.js code did not properly execute. If `typeof window.myTestFunc` prints out 'function' but `typeof myTestFunc` prints out something else, then you have somehow managed to shadow the definition by introducing an extra variable in the local scope.
     
    ysftulek, De-Panther and bruceb85 like this.
  19. bruceb85

    bruceb85

    Joined:
    Sep 26, 2020
    Posts:
    45
    I've already tried adding print logs which is how I determined I can only trigger local functions inside of jslib.

    As another route, is it possible to find button presses through the html script? For instance if I press a button with the tag "Button/myTestBtn" how can I find if that was triggered in the index.html file unity generates?
     
  20. De-Panther

    De-Panther

    Joined:
    Dec 27, 2009
    Posts:
    589
    You ignored the most important part...
    Did you tried to set the method under the window scope?

    In the js

    window.myTestFunc = myTestFunc;

    and then in the jslib call

    window.myTestFunc();
     
  21. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,549
    You can use
    document.getElementById("whatever")
    from within a Unity .jslib, you can use that to add a click handler or change css styles and so on. I'm also pretty sure you can define
    window.myFunction = function(){ //... }
    within HTML file and then just call window.myFunction() from within a .jslib - as mentioned by others already.
     
    De-Panther likes this.
  22. bruceb85

    bruceb85

    Joined:
    Sep 26, 2020
    Posts:
    45

    SendToJavascript: function (str) {
    window.alert("Hello .jslib"); //returns string
    window.alert(Pointer_stringify(str)); //returns name of button pressed
    window.myTestFunc(); //returns error with no further pop ups
    console.log(typeof myTestFunc);
    console.log(typeof window.myTestFunc);


    },

    upload_2020-10-11_11-43-49.png

    upload_2020-10-11_11-44-7.png

    upload_2020-10-11_11-44-48.png
     
  23. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    Attached a full example project that calls out to a .jslib from C#, and from that .jslib calls out to a JS function in .html file, and to another JS function in a separate external.js file.

    You can find a build in the subdirectory "build_webgl/", and a live build at http://clb.confined.space/dump/CallJSFromCSharp_build_webgl/
     

    Attached Files:

  24. bruceb85

    bruceb85

    Joined:
    Sep 26, 2020
    Posts:
    45
    this worked perfect, thanks
     
    xiangshushu and adamgolden like this.
  25. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,459
    Thank you for the awesome example package. I just tried it in 2021.3 LTS and the first popup works fine
    "A string from C# side!"

    but the second popup gave this error: Do you know what this could be? I'm on windows 10, URP

    CsharpToJS.loader.js:1 exception thrown: ReferenceError: aFunctionImplementedInHtmlFile is not defined,ReferenceError: aFunctionImplementedInHtmlFile is not defined
    at _aFunctionImplementedInJavaScriptLibraryFile (blob:http://localhost/72f0c8fb-48a4-4796-999a-4e3a24f53e7e:3:148972)
    at wasm://wasm/051ecae6:wasm-function[22219]:0x75f05b
    at wasm://wasm/051ecae6:wasm-function[54897]:0xe77353
    at wasm://wasm/051ecae6:wasm-function[46830]:0xd4c0dc
    at wasm://wasm/051ecae6:wasm-function[8008]:0x266a4e
    at wasm://wasm/051ecae6:wasm-function[34196]:0x990f32
    at invoke_iiii (blob:http://localhost/72f0c8fb-48a4-4796-999a-4e3a24f53e7e:3:360089)
    at wasm://wasm/051ecae6:wasm-function[1489]:0x87837
    at wasm://wasm/051ecae6:wasm-function[18371]:0x675d9c
    at wasm://wasm/051ecae6:wasm-function[737]:0x66d0a
    at wasm://wasm/051ecae6:wasm-function[4306]:0x143df8
    at wasm://wasm/051ecae6:wasm-function[44206]:0xcf8b87
    at wasm://wasm/051ecae6:wasm-function[38458]:0xacd025
    at wasm://wasm/051ecae6:wasm-function[37046]:0xa14c7e
    at wasm://wasm/051ecae6:wasm-function[19219]:0x713bbd
    at wasm://wasm/051ecae6:wasm-function[19219]:0x713c2e
    at wasm://wasm/051ecae6:wasm-function[15828]:0x4a7b3b
    at wasm://wasm/051ecae6:wasm-function[34190]:0x990de5
    at browserIterationFunc (blob:http://localhost/72f0c8fb-48a4-4796-999a-4e3a24f53e7e:3:201477)
    at callUserCallback (blob:http://localhost/72f0c8fb-48a4-4796-999a-4e3a24f53e7e:3:154675)
    at Object.runIter (blob:http://localhost/72f0c8fb-48a4-4796-999a-4e3a24f53e7e:3:155935)
    at Browser_mainLoop_runner (blob:http://localhost/72f0c8fb-48a4-4796-999a-4e3a24f53e7e:3:154210)
    printErr @ CsharpToJS.loader.js:1
    CsharpToJS.loader.js:1 Invoking error handler due to
    ReferenceError: aFunctionImplementedInHtmlFile is not defined
    at _aFunctionImplementedInJavaScriptLibraryFile (blob:http://localhost/72f0c8fb-48a4-4796-999a-4e3a24f53e7e:3:148972)
    at wasm://wasm/051ecae6:wasm-function[22219]:0x75f05b
    at wasm://wasm/051ecae6:wasm-function[54897]:0xe77353
    at wasm://wasm/051ecae6:wasm-function[46830]:0xd4c0dc
    at wasm://wasm/051ecae6:wasm-function[8008]:0x266a4e
    at wasm://wasm/051ecae6:wasm-function[34196]:0x990f32
    at invoke_iiii (blob:http://localhost/72f0c8fb-48a4-4796-999a-4e3a24f53e7e:3:360089)
    at wasm://wasm/051ecae6:wasm-function[1489]:0x87837
    at wasm://wasm/051ecae6:wasm-function[18371]:0x675d9c
    at wasm://wasm/051ecae6:wasm-function[737]:0x66d0a
    at wasm://wasm/051ecae6:wasm-function[4306]:0x143df8
    at wasm://wasm/051ecae6:wasm-function[44206]:0xcf8b87
    at wasm://wasm/051ecae6:wasm-function[38458]:0xacd025
    at wasm://wasm/051ecae6:wasm-function[37046]:0xa14c7e
    at wasm://wasm/051ecae6:wasm-function[19219]:0x713bbd
    at wasm://wasm/051ecae6:wasm-function[19219]:0x713c2e
    at wasm://wasm/051ecae6:wasm-function[15828]:0x4a7b3b
    at wasm://wasm/051ecae6:wasm-function[34190]:0x990de5
    at browserIterationFunc (blob:http://localhost/72f0c8fb-48a4-4796-999a-4e3a24f53e7e:3:201477)
    at callUserCallback (blob:http://localhost/72f0c8fb-48a4-4796-999a-4e3a24f53e7e:3:154675)
    at Object.runIter (blob:http://localhost/72f0c8fb-48a4-4796-999a-4e3a24f53e7e:3:155935)
    at Browser_mainLoop_runner (blob:http://localhost/72f0c8fb-48a4-4796-999a-4e3a24f53e7e:3:154210)
    72f0c8fb-48a4-4796-999a-4e3a24f53e7e:3 Uncaught ReferenceError: aFunctionImplementedInHtmlFile is not defined
    at _aFunctionImplementedInJavaScriptLibraryFile (72f0c8fb-48a4-4796-999a-4e3a24f53e7e:3:148972)
    at 051ecae6:0x75f05b
    at 051ecae6:0xe77353
    at 051ecae6:0xd4c0dc
    at 051ecae6:0x266a4e
    at 051ecae6:0x990f32
    at invoke_iiii (72f0c8fb-48a4-4796-999a-4e3a24f53e7e:3:360089)
    at 051ecae6:0x87837
    at 051ecae6:0x675d9c
    at 051ecae6:0x66d0a
    at 051ecae6:0x143df8
    at 051ecae6:0xcf8b87
    at 051ecae6:0xacd025
    at 051ecae6:0xa14c7e
    at 051ecae6:0x713bbd
    at 051ecae6:0x713c2e
    at 051ecae6:0x4a7b3b
    at 051ecae6:0x990de5
    at browserIterationFunc (72f0c8fb-48a4-4796-999a-4e3a24f53e7e:3:201477)
    at callUserCallback (72f0c8fb-48a4-4796-999a-4e3a24f53e7e:3:154675)
    at Object.runIter (72f0c8fb-48a4-4796-999a-4e3a24f53e7e:3:155935)
    at Browser_mainLoop_runner (72f0c8fb-48a4-4796-999a-4e3a24f53e7e:3:154210)
     
  26. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,459
    Found the problem, for some reason when unity made the build, the index.html file did not have these two lines.

    <script src='external.js'></script>

    function aFunctionImplementedInHtmlFile(jsString) {
    alert('Hello from index.html file! We received a string:"' + jsString + '"');
    }

    and also the external.js file wasn't copied to the build folder.
     
  27. Hemaolle_Unity

    Hemaolle_Unity

    Unity Technologies

    Joined:
    Nov 9, 2020
    Posts:
    1
    Btw this seems to be equivalent to adding the function declaration to the window:

    Code (JavaScript):
    1.  
    2. <script>
    3.     // same as window.unityInterface = function(msg) ...
    4.     var unityInterface = function(msg) { console.log("unity interface sadfsadf: " + msg)}
    5. </script>
    6.  
    And .jslib:

    Code (JavaScript):
    1.  
    2. mergeInto(LibraryManager.library, {
    3.     CallJavaScript: function (message) {
    4.         // same as window.unityInterface(UTF8ToString(message));
    5.         unityInterface(UTF8ToString(message));
    6.     },
    7. });
    8.  
    See https://stackoverflow.com/questions/10324501/attach-function-to-domwindow-object
     
    dan_ginovker likes this.