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

Unity WebGL中如何从C#脚本调用异步JavaScript函数?

问题原因

Unity WebGL通过DllImport调用JS函数是同步机制,而你定义的async函数返回的是Promise对象,并非直接的字符串结果,同步调用无法解析Promise,因此C#脚本拿不到钱包地址。

解决方案:用UnitySendMessage实现异步回调

Unity WebGL处理JS异步交互的标准方式是通过UnitySendMessage,让JS在异步操作完成后主动将结果传递给C#脚本。

1. 修改JSlib文件

移除async返回逻辑,改为在MetaMask请求完成后,通过UnitySendMessage将结果发送到C#的指定方法:

mergeInto(LibraryManager.library, {
  RequestMetaMaskWallet: function() {
    window.ethereum.request({ method: 'eth_requestAccounts' })
    .then(accounts => {
      const account = accounts[0];
      // 向Unity指定对象的方法发送结果
      // 参数1:挂载C#脚本的游戏对象名称,参数2:C#方法名,参数3:传递的字符串
      UnitySendMessage("WalletManager", "OnMetaMaskConnected", account);
    })
    .catch(err => {
      if (err.code === 4001) {
        console.log('用户拒绝连接MetaMask');
      } else {
        console.error(err);
      }
      // 发送空字符串标识连接失败/拒绝
      UnitySendMessage("WalletManager", "OnMetaMaskConnected", "");
    });
  },
});

2. 修改C#脚本

添加接收JS回调的方法,调整调用逻辑为触发异步请求而非同步等待返回:

using UnityEngine;
using UnityEngine.UI;
using System.Runtime.InteropServices;

public class WalletManager : MonoBehaviour
{
    [DllImport("__Internal")]
    private static extern void RequestMetaMaskWallet();

    public Button connectMetaMaskButton;

    void Start()
    {
        Button btn = connectMetaMaskButton.GetComponent<Button>();
        btn.onClick.AddListener(ConnectWallet);
    }

    void ConnectWallet()
    {
        // 触发JS的异步请求,不等待返回
        RequestMetaMaskWallet();
        // 临时禁用按钮防止重复点击
        connectMetaMaskButton.interactable = false;
    }

    // 必须是public方法,用于接收JS的回调
    public void OnMetaMaskConnected(string account)
    {
        // 恢复按钮状态
        connectMetaMaskButton.interactable = true;
        
        if (!string.IsNullOrEmpty(account))
        {
            Debug.Log("钱包连接成功:" + account);
            connectMetaMaskButton.gameObject.SetActive(false);
            // 这里可以继续处理钱包地址(比如显示到UI、存储到本地等)
        }
        else
        {
            Debug.Log("连接失败或用户拒绝授权");
            // 可添加提示用户重新尝试的逻辑
        }
    }
}

关键注意事项

  • 确保挂载C#脚本的游戏对象名称是WalletManager(与JS中UnitySendMessage的第一个参数完全一致),如果对象改名,JS里也要同步修改。
  • C#的OnMetaMaskConnected方法必须是public,且参数类型为string,否则JS无法调用。
  • 必须在浏览器环境下测试(WebGL构建后或Unity的WebGL预览模式),MetaMask不支持Unity编辑器的本地PlayMode。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 17:12:48