You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity WebGL中JavaScript获取C#列表数据的技术求助

我刚好用Unity WebGL做过类似的交互,你的问题核心在于Unity WebGL的SendMessage确实不支持返回值——它是单向的调用,没法直接从C#拿到返回数据。得换异步回调的思路来解决,让C#主动把数据推给JavaScript,而不是JS去“请求”数据。

解决方案思路

因为WebGL的线程模型限制,C#和JS的交互大多是异步的。我们需要让C#方法执行完后,主动调用一个JS函数,把列表数据传过去(一般用JSON序列化,因为直接传复杂类型会有兼容性问题)。


步骤1:修改C#代码,添加JS回调

把原来返回列表的方法改成无返回值,在获取到列表后,将数据序列化成JSON字符串,再调用JS的回调函数传递数据。注意Unity自带的JsonUtility不能直接序列化List<string>,需要先包装成可序列化的类:

// 定义可序列化的包装类,用来处理List<string>的序列化
[System.Serializable]
public class StringListWrapper
{
    public List<string> items;
}

public void 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()); 

    // 包装列表并序列化为JSON
    var listWrapper = new StringListWrapper { items = goNames };
    string jsonData = JsonUtility.ToJson(listWrapper);
    
    // 调用全局JS回调函数,传递序列化后的字符串
    Application.ExternalCall("onWallsListReceived", jsonData);
}

步骤2:修改JavaScript代码,处理回调数据

原来的getWallsList只需要触发C#的方法即可,真正的数据处理放在新增的回调函数里:

function getWallsList() { 
    // 只触发C#方法,不需要接收返回值
    gameInstance.SendMessage('WallCreator', 'GetGameObjects'); 
}

// 接收C#传递的数据并填充Select组件
function onWallsListReceived(jsonData) {
    var wallsSelect = document.getElementById("wallsSelect");
    // 清空原有选项(可选)
    wallsSelect.innerHTML = "";
    
    // 解析JSON字符串
    var listWrapper = JSON.parse(jsonData);
    var wallsList = listWrapper.items;

    // 循环创建选项
    for (var index = 0; index < wallsList.length; index++) { 
        var itemName = wallsList[index];
        var newOption = document.createElement("option"); 
        newOption.value = index; 
        newOption.innerHTML = itemName; 
        wallsSelect.appendChild(newOption); 
    }
}

步骤3:确保调用时机正确

要保证getWallsList是在Unity实例完全加载后调用的,避免出现gameInstance未定义的问题:

  • 可以在Unity脚本的Start方法里触发JS函数:
    void Start()
    {
        Application.ExternalCall("getWallsList");
    }
    
  • 或者在HTML的Unity加载成功回调中触发:
    <script>
      var gameInstance = UnityLoader.instantiate("gameContainer", "Build/YourBuild.json", {
        onSuccess: function() {
          // 加载完成后调用获取列表的方法
          getWallsList();
        }
      });
    </script>
    

为什么原来的方法不行?

SendMessage在Unity WebGL中是单向通信设计:JS可以调用C#方法,但C#无法直接返回值给JS。这是因为WebGL将C#编译为WebAssembly,受浏览器单线程环境限制,同步获取返回值会阻塞主线程,所以Unity采用了异步回调的模式来实现双向数据传递。

内容的提问来源于stack exchange,提问作者Dauwbot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:06:48