Dauwbot
Dauwbot

Reputation: 81

Access C# List from JavaScript

As part of our internship we've been tasked with creating a business application using Unity WebGL. After reading on interactions between JS and the C# code we're in a corner.
We're trying to get back a list from C# to populate a Select on our webpage and we just don't know how to do it. We've followed the Unity documentation and can easily communicate and get back data to use in our C# from our webpage.
We can't however access C# data in our browser. SendMessage() method does not allow returns.
Here's our code so far

index.html

          <select id="wallsSelect"></select>

jsfile

    function getWallsList() {
    //function is called at the creation of our object
    var wallsSelect = document.getElementById("wallsSelect");
    index = 0;
    var wallsList = gameInstance.SendMessage('WallCreator', 'GetGameObjects'); //would like to get back our list of walls and populate our Select with it

    for (item in wallsList) {
        var newOption = document.createElement("option");
        newOption.value = index;
        newOption.innerHTML = item;

        wallsSelect.appendChild(newOption);
        index++;
    }

C# code finally

public List<string> GetGameObjects()
{
    List<string> goNames = new List<string>();
    foreach (var item in goList)
    {
        goNames.Add(item.name);
    }
    Debug.Log("Accessed GetGameObjects method. GameObject count = " + goNames.Count.ToString()); //The object is instanciated and return the right count number so it does work without a problem
    return goNames;

}

Yes we did check https://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html and I've made numerous research and found some interesting resources that I can't wrap my head around being too inexperienced, for example http://tips.hecomi.com/entry/2014/12/08/002719

To conclude, I would like to point out it's our first "real world" project and Unity-WebGL is quite an experience to play with seeing the lack of documentation.

Upvotes: 7

Views: 2022

Answers (2)

Dauwbot
Dauwbot

Reputation: 81

Okay, after extensively reading the Unity doc and some help from our technical lead I've attained a "good enough" solution.

Unity gives you a way to call JS functions from C# code to communicate with your HTML page in which your Unity module reside. I had to create a "dummy" class which is Serializable and just store the name and coordinates of my object.

C# code

 //We create a class with the Serializable attribute and stock the name and size of our GameObject 

[Serializable]
    public class SzModel
    {
        public string modelName;
        public Vector3 modelSize;
    }

//we have to import our .jslib method into our C# (see below)
    [DllImport("__Internal")]
    private static extern void UpdateModel(string model);

//We use our dummy class to create a JSON parseable list of those objects
    void WallsList()
    {
        List<SzModel> szModelList = new List<SzModel>();
        foreach (var item in goList)
        {
            SzModel newWall = new SzModel();
            newWall.modelName = item.Name;
            newWall.modelSize = item.Size;
            szModelList.Add(newWall);
        }

        UpdateModel(JsonHelper.ToJson<SzModel>(szModelList.ToArray(), true));
    }

//We create an helper class to be able to use JsonUtility on list
//code can be found here -> https://stackoverflow.com/a/36244111/11013226

After that we need to inform our HTML page of the new object, we use the UpdateModel() method to do that. Unity use .jslib files to communicate between C# (which is transformed to JS code at build time) and our browser. So we can declare a function in this .jslib file. Those files reside in Asset/Plugins and are auto converted when building. As you can see below we have to use the Pointer_stringify method to get our json data back and not just the pointer to it.

.jslib file

mergeInto (LibraryManager.library, {

    UpdateModel : function(model){
        model = Pointer_stringify(model);
        updateModel(model);
    },
//rest of code
});

And finally I can use my json data in my webpage, in this case to display a list of the names of the walls.

function updateModel(model) {
    var jsonWallsList = JSON.parse(model);
    var wallsList = document.getElementById("wallsSelect"),
        option,
        i = jsonWallsList.Items.length - 1,
        length = jsonWallsList.Items.length;

    for (; i < length; i++) {
        option = document.createElement('option');
        option.setAttribute('value', jsonWallsList.Items.modelName);
        option.appendChild(document.createTextNode(jsonWallsList.Items[i]['modelName']));
        wallsList.appendChild(option);
    }
}

Which give the following in the select on my webpage a select from C# in Unity-webgl

Upvotes: 1

Bedir
Bedir

Reputation: 586

I think you should try using hidden fields in your html that you can modify with C#. You can then access that data with JavaScript. For example:

HTML:

<input type="hidden" value="currentValue" id="hiddenField1">

C#:

private void changeHiddenField(){

    hiddenField1.Value = "differentValue";

}

JS:

var hiddenFieldVal = document.getElementById("hiddenField1").value;

For more information about hidden fields in HTML https://www.w3schools.com/tags/att_input_type_hidden.asp

Please forgive any syntax errors.

Upvotes: 0

Related Questions