Reputation: 81
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
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
Upvotes: 1
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