Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unity - communicating with clientside Javascript and ajax. How to pass data back to the webpage from unity?

What I am really asking is this; if there are dependencies which are impossible to compile into the unity build, is there a way of still calling them from within the unity and simply using the scripts loaded into the browser from the website and communicating with them?

Relevant documentation does not address this deeply: https://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html

I am creating a website wrapper for a unity application. The buttons for the experience are located within the website, as the buttons affect the rest of the site, not just the unity application.

When certain content is loaded in the unity game play however, the app needs to be able to affect the website. Is there a way to pass the data back to the website in a creative way? Currently, I am including all my javascript code for the website in the unity compile, and it is erroring out on:

gameInstance = UnityLoader.instantiate("gameContainer", "/Build/DomumProto16_Web.json", {
    onProgress: UnityProgress
}); 

Sending data to the gameplay from the website:

gameInstance.SendMessage('Manager','Filter', JSON.stringify(filterActive));

Need to call this function from the unity gameplay. However, ajax.ajax_url is undefined due to it being localized using wp_localize_script() on the backend.

function showStudentWork(studentIndex){
        
    //make sure to remove all the 
    var x = document.getElementById("studentWork");

    var studentID = studentWork[studentIndex];
    console.log(studentID);
    
    $.ajax({
        url: ajax.ajax_url,
        type: "POST",
        data: {
            action: 'getStudentPost',
            currentStudent: studentID
        },
        success: function (data) {
            x.innerHTML = "";
            x.innerHTML = data;
            x.style.display = "grid";
        },
        error: function (error) {
            console.log(`Error ${error}`);
        }
    });
    
    return false;

}

What I am really asking is this; if there are dependencies which are impossible to compile into the unity build, is there a way of still calling them from within the unity and simply using the scripts loaded into the browser from the website and communicating with them?

like image 616
stackOverFlew Avatar asked Oct 26 '20 07:10

stackOverFlew


People also ask

Can Unity export to Web?

Publish Your Project as a WebGL Browser Game Unity is able to export a project as a WebGL application.

How do I send a HTTP request in Unity?

Create a UnityWebRequest configured to send form data to a server via HTTP POST . This method creates a UnityWebRequest, sets the url to the string uri argument and sets the method to POST . The Content-Type header will be set to application/x-www-form-urlencoded .

Why did Unity stop using JavaScript?

It's a proprietary language and it doesn't actually follow any concrete specification of standard JavaScript and is modified at will by the engine developers. > Because of this, the vast majority of JavaScript libraries you find will not work by default in Unity.


1 Answers

Here are two methods. One is, in my opinion, easier, but it is deprecated and you should ~not~ use it. Options two is the 'corrrect' way, but it is kinda ugly imo.

Option 1: Application.ExternalCall

Documentation

This option allows you to call browser javascript directly, but Unity has deprecated support for it and is probably a bad idea for anything long term.

In a given browser with a Unity web player working, consider the following: In browser source, define a javascript function

<other html>
<script>
function foo(msg) {
    alert(msg);
}
</script>

In Unity, whenever it is nessecary:

Application.ExternalCall( "foo", "The game says hello!" );

This allows Javascript to be called from Unity. There is similar functionality for communication in the opposite direction.

Option 2: jslibs

Documentation

This is the unity-endorsed way of doing things. It involved packaging javascript libraries into your games.

First, create a javascript file that will be packaged with your game. Here is an example file:

// Unity syntactic sugar
mergeInto(LibraryManager.library, {
    // Declare all your functions that can be called from c# here
    alert_user: function (msg) {
        window.alert(msg);
    },
    other_func: function () {
     // does something else
     // etc.
     // put as many functions as you'd like in here
    }
}

Place that file, with extension .jslib in your Plugins folder on your project.

Then, in your c# files, you need to:

// Declare a monobehavior, whatever
using UnityEngine;
using System.Runtime.InteropServices;

public class NewBehaviourScript : MonoBehaviour {

    // IMPORTANT
    // You have to declare the javascript functions you'll be calling
    // as private external function in your c# file. Additionally,
    // They need a special function decorator [DllImport("__Internal")]
    // Example:
    [DllImport("__Internal")]
    private static extern void alert_user(string msg);

    // With that unpleasantness over with, you can now call the function
    void Start() {
        alert_user("Hello, I am a bad person and I deserve to write c#");
    }
}

Et viola. You can call other javascript from your c# javascript, and interact with the dom, but I will leave all those decisions up to you.

The other direction

In both cases, communication in the opposite direction (browser saying something to Unity) is the same format.

In javascript, create a UnityInstance (the way of this is a little two long-winded to put into this answer, check either docs). Then, just .sendMessage.

e.g.: c#

...
void DoSomething (string msg) {
    // this is a c# function that does something in the game
    // use your imagination
}
...

javascript:

let game = UnityLoader // Actually load the game here
game.SendMessage('TheNameOfMyGameObject', 'DoSomething', 'This is my message');
like image 188
Carson Avatar answered Nov 10 '22 17:11

Carson