Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 686
Dauwbot Avatar asked Feb 27 '19 12:02

Dauwbot


People also ask

What is access function C?

DESCRIPTION. The access() function shall check the file named by the pathname pointed to by the path argument for accessibility according to the bit pattern contained in amode, using the real user ID in place of the effective user ID and the real group ID in place of the effective group ID.

What is access C return?

Returned valueIf the specified access is permitted, access() returns 0. If the given file cannot be accessed in the specified way, access() returns -1 and sets errno to one of the following values: Error Code. Description.

What is access function in Linux?

In Linux, access command is used to check whether the calling program has access to a specified file. It can be used to check whether a file exists or not. The check is done using the calling process's real UID and GID. int access(const char *pathname, int mode);


1 Answers

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

like image 114
Dauwbot Avatar answered Oct 13 '22 22:10

Dauwbot