Search Unity

Javascript communication 2 ways. Simple examples / tutorials?

Discussion in 'Web' started by wuannetraam, Aug 5, 2021.

  1. wuannetraam

    wuannetraam

    Joined:
    Oct 29, 2019
    Posts:
    87
    I am not a skilled programmer. I know how to code in Unity (the basics). I have searched youtube and came a cross a lot of tutorials which are outdated. They don't work anymore on the Unity 2020+ versions.

    What I am looking for is a very simple example or tutorial on how to do this.

    - Click on an html button added to index.html of your Unity build and execute a function you have added to a c# script in Unity.

    - Click on a UI button created in Unity and execute a javascript function like change background color or the index.html page.

    I don't think that this is really hard to do but I am looking for days now on youtube and google but am stuck.

    Hope someone can help me out.
     
  2. roka

    roka

    Joined:
    Sep 12, 2010
    Posts:
    598
  3. wuannetraam

    wuannetraam

    Joined:
    Oct 29, 2019
    Posts:
    87
  4. gtk2k

    gtk2k

    Joined:
    Aug 13, 2014
    Posts:
    288
    Reference document.
    https://docs.unity3d.com/ja/2018.4/Manual/webgl-interactingwithbrowserscripting.html

    JS -> C# call sample

    Code (CSharp):
    1. using AOT;
    2. using System;
    3. using System.Runtime.InteropServices;
    4. using UnityEngine;
    5.  
    6. public class testlib : MonoBehaviour
    7. {
    8.     [DllImport("__Internal")]
    9.     private static extern void init(Action<int> btnClickCallback);
    10.  
    11.     [MonoPInvokeCallback(typeof(Action<int>))]
    12.     private static void htmlButtonClick(int arg)
    13.     {
    14.         Debug.Log($"HTML Button click: {arg}");
    15.     }
    16.  
    17.     void Start()
    18.     {
    19.         init(htmlButtonClick);
    20.     }
    21. }
    22.  
    testlib.jslib (JavaScript)
    Code (JavaScript):
    1. mergeInto(LibraryManager.library, {
    2.     init: function(btnClickCallback) {
    3.         document.getElementById('btn_id').onclick = () => {
    4.             dynCall_vi(btnClickCallback, 3);
    5.         };
    6.     }
    7. });
     
    De-Panther and wuannetraam like this.
  5. wuannetraam

    wuannetraam

    Joined:
    Oct 29, 2019
    Posts:
    87
    thank you for the extra information bit I still don't get it. Is there someone who can lecture me on this via some kind of call like on discord or zoom? I am willing to pay for it...
     
  6. wuannetraam

    wuannetraam

    Joined:
    Oct 29, 2019
    Posts:
    87

    Ok I am testing this now and I get it to work. It shows the Debug Log in the Console in my browser when I click on a html button. Awesome. But now I am getting stuck. I have a "Sphere" object in my scene and I would like to dissable it when I click on the html button. So I tought I add "Public gameObject sphere; to the script and then "sphere.gameObject.SetActive(false);" above the Debug Log code. But then Unity gives this error: "n object reference is required for the non-static field, method, or property". So what would be the way to add a public game object to this script and do something with it?

    My code now looks likes this:


    Code (CSharp):
    1. using AOT;
    2. using System;
    3. using System.Runtime.InteropServices;
    4. using UnityEngine;
    5.  
    6. public class testlib : MonoBehaviour
    7. {
    8.     public  GameObject sphere;
    9.     [DllImport("__Internal")]
    10.     private static extern void init(Action<int> btnClickCallback);
    11.  
    12.     [MonoPInvokeCallback(typeof(Action<int>))]
    13.     private static void htmlButtonClick(int arg)
    14.     {
    15.         sphere.gameObject.SetActive(false);
    16.         Debug.Log($"HTML Button click: {arg}");
    17.     }
    18.  
    19.  
    20.     void Start()
    21.     {
    22.         init(htmlButtonClick);
    23.     }
    24. }
     
  7. xuan_celestial

    xuan_celestial

    Joined:
    Jul 17, 2018
    Posts:
    18
    Another way you can achieve this is, attach this script to a Game Object in scene named it 'Testing'.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Testing: MonoBehaviour
    4. {
    5.     public GameObject sphere;
    6.  
    7.     public void DeactivateSphere()
    8.     {
    9.         sphere.SetActive(false);
    10.     }
    11. }
    Then, hook this line to your html button when it is pressed:

    unityInstance.SendMessage('Testing', 'DeactivateSphere');

    -----

    As referenced in the document, under section:
    Calling Unity scripts functions from JavaScript
    Unity - Manual: WebGL: Interacting with browser scripting (unity3d.com)
     
  8. wuannetraam

    wuannetraam

    Joined:
    Oct 29, 2019
    Posts:
    87

    I don't think this works in Unity 2020. I watched youtube videos where they did this too but the index.html has changed.
     
  9. gtk2k

    gtk2k

    Joined:
    Aug 13, 2014
    Posts:
    288
    I think you should publish an event.

    .jslib Import C# Script File

    Code (CSharp):
    1. using AOT;
    2. using System;
    3. using System.Runtime.InteropServices;
    4. using UnityEngine;
    5.  
    6. public class TestLib : MonoBehaviour
    7. {
    8.  
    9.     public delegate void dlgOnHtmlButtonClick();
    10.     public static event dlgOnHtmlButtonClick OnHtmlButtonClick;
    11.  
    12.     [DllImport("__Internal")]
    13.     private static extern void init(Action btnClickCallback);
    14.  
    15.     [MonoPInvokeCallback(typeof(Action))]
    16.     private static void htmlButtonClick()
    17.     {
    18.         OnHtmlButtonClick?.Invoke();
    19.     }
    20.  
    21.     void Start()
    22.     {
    23.         init(htmlButtonClick);
    24.     }
    25. }
    26.  
    .jslib File
    Code (JavaScript):
    1. mergeInto(LibraryManager.library, {
    2.     init: function(btnClickCallback) {
    3.         document.getElementById('btn_id').onclick = () => {
    4.             dynCall_vi(btnClickCallback, 3);
    5.         };
    6.     }
    7. });
    8.  
    GameObject Attatch C# Script File
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class GameObjectScript : MonoBehaviour
    4. {
    5.     // Start is called before the first frame update
    6.     void Start()
    7.     {
    8.         TestLib.OnHtmlButtonClick += TestLib_OnHtmlButtonClick;
    9.     }
    10.  
    11.     private void TestLib_OnHtmlButtonClick()
    12.     {
    13.         gameObject.SetActive(!gameObject.activeSelf);
    14.     }
    15. }
    16.  
     
  10. wuannetraam

    wuannetraam

    Joined:
    Oct 29, 2019
    Posts:
    87
    Thank you but that does not seem to work for me. Nothing happends when I test it.
     
  11. gtk2k

    gtk2k

    Joined:
    Aug 13, 2014
    Posts:
    288
  12. wuannetraam

    wuannetraam

    Joined:
    Oct 29, 2019
    Posts:
    87
    thank you. I checked out this project but this is not wat I think I need. This calls a JS function within C#. I need it the other way around.
    I have tried these scripts. But when I publish my project and run it in the browser and click on a HTML button I get this error in the console:

    Code (CSharp):
    1. Builds.wasm.gz:0x7a2b4d Uncaught RuntimeError: null function or function signature mismatch
    2.     at Builds.wasm.gz:0x7a2b4d
    3.     at HTMLButtonElement.document.getElementById.onclick (Builds.framework.js.gz:2)
     
  13. wuannetraam

    wuannetraam

    Joined:
    Oct 29, 2019
    Posts:
    87
    What can be the problem and how do I fix this?
     
  14. gtk2k

    gtk2k

    Joined:
    Aug 13, 2014
    Posts:
    288
    Please build once. Since index.html is in the build destination folder, add <button id = "btn-id"> test </ button> to an appropriate location in index.html and try it.
     
    Last edited: Aug 9, 2021