Unity 获取WebGL URL中参数,JS调用C#

Posted unity阿翘哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity 获取WebGL URL中参数,JS调用C#相关的知识,希望对你有一定的参考价值。

Unity 获取WebGL URL中参数,以及JS调用C#

Unity版本2021.3.6
导出WebGL文件夹要和Asset同级,不然会导出失败

一、Unity 获取WebGL URL中参数

1.c#代码

***脚本挂在到场景WebGL物体上面

using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;

public class CSharpOrJS : MonoBehaviour


    #region 接收URL参数

    [DllImport("__Internal")]
    private static extern string GetURLMessageFunction();

    public static string UrlMsg = string.Empty;

    public UnityEngine.UI.Text Text;
    void Start()
    
        try
        
            UrlMsg = GetURLMessageFunction();

        
        catch (System.Exception e)
        
            UrlMsg = "[catch]" + e.Message;
        
        Debug.LogError($"UrlMsg>>>\\nUrlMsg");

        Text.text = UrlMsg;
    

    #endregion


    #region JS调用C#

    //调用方式写到导出WebGL的Index.html
    //unityInstance.SendMessage('脚本挂在的场景物体名字','调用方法名字','参数(有就写没有就不写)') 
    
    public void JSCallUnity1()
    
        Debug.LogError("JS调用Unity,无参无返回值");

    
    public void JSCallUnity2(string value)
    
        Debug.LogError($"JS调用Unity,有参无返回值\\n value");
    

    #endregion




2.unity部分

unity场景结构图

自定义一个CSOrJSPlugins.jslib文件放unity的Plugins下面(创建文本改后缀即可)

CSOrJSPlugins.jslib文件用来获取URL中参数

CSOrJSPlugins.jslib代码参考

var CSOrJSPlugins = 
      
    GetURLMessageFunction: function()
    
        var returnStr = window.location.search;
        var buffer = _malloc(lengthBytesUTF8(returnStr) + 1);
        writeStringToMemory(returnStr, buffer);
        return buffer;
     
;
 
mergeInto(LibraryManager.library, CSOrJSPlugins);

二、JS调用C#

1.c#部分已经在上面的c#代码定义好了,如下图:

2.导出的index.html代码参考!


index.html代码

<!DOCTYPE html>
<html lang="en-us">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Unity WebGL Player | testnull</title>
    <link rel="shortcut icon" href="TemplateData/favicon.ico">
    <link rel="stylesheet" href="TemplateData/style.css">
  </head>
  <body>
    <div id="unity-container" class="unity-desktop">
      <canvas id="unity-canvas" width=960 height=600></canvas>
      <div id="unity-loading-bar">
        <div id="unity-logo"></div>
        <div id="unity-progress-bar-empty">
          <div id="unity-progress-bar-full"></div>
        </div>
      </div>
      <div id="unity-warning"> </div>
      <div id="unity-footer">
        <div id="unity-webgl-logo"></div>
        <div id="unity-fullscreen-button"></div>
        <div id="unity-build-title">testnull</div>
      </div>
    </div>
    <script>
      var container = document.querySelector("#unity-container");
      var canvas = document.querySelector("#unity-canvas");
      var loadingBar = document.querySelector("#unity-loading-bar");
      var progressBarFull = document.querySelector("#unity-progress-bar-full");
      var fullscreenButton = document.querySelector("#unity-fullscreen-button");
      var warningBanner = document.querySelector("#unity-warning");

      // Shows a temporary message banner/ribbon for a few seconds, or
      // a permanent error message on top of the canvas if type=='error'.
      // If type=='warning', a yellow highlight color is used.
      // Modify or remove this function to customize the visually presented
      // way that non-critical warnings and error messages are presented to the
      // user.
      function unityShowBanner(msg, type) 
        function updateBannerVisibility() 
          warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
        
        var div = document.createElement('div');
        div.innerHTML = msg;
        warningBanner.appendChild(div);
        if (type == 'error') div.style = 'background: red; padding: 10px;';
        else 
          if (type == 'warning') div.style = 'background: yellow; padding: 10px;';
          setTimeout(function() 
            warningBanner.removeChild(div);
            updateBannerVisibility();
          , 5000);
        
        updateBannerVisibility();
      

      function test1()
        console.log("调用unity无参数方法") 
        unityInstance_G.SendMessage('WebGL','JSCallUnity1') 
      

      function test2()
        console.log("调用unity有参数方法") 
        unityInstance_G.SendMessage('WebGL','JSCallUnity2','我是测试的参数')  
      

      var buildUrl = "Build";
      var loaderUrl = buildUrl + "/WebGLTest.loader.js";
      var config = 
        dataUrl: buildUrl + "/WebGLTest.data.unityweb",
        frameworkUrl: buildUrl + "/WebGLTest.framework.js.unityweb",
        codeUrl: buildUrl + "/WebGLTest.wasm.unityweb",
        streamingAssetsUrl: "StreamingAssets",
        companyName: "DefaultCompany",
        productName: "testnull",
        productVersion: "1.0",
        showBanner: unityShowBanner,
      ;

      // By default Unity keeps WebGL canvas render target size matched with
      // the DOM size of the canvas element (scaled by window.devicePixelRatio)
      // Set this to false if you want to decouple this synchronization from
      // happening inside the engine, and you would instead like to size up
      // the canvas DOM size and WebGL render target sizes yourself.
      // config.matchWebGLToCanvasSize = false;

      if (/iPhone|iPad|iPod|android/i.test(navigator.userAgent)) 
        // Mobile device style: fill the whole browser client area with the game canvas:

        var meta = document.createElement('meta');
        meta.name = 'viewport';
        meta.content = 'width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, shrink-to-fit=yes';
        document.getElementsByTagName('head')[0].appendChild(meta);
        container.className = "unity-mobile";

        // To lower canvas resolution on mobile devices to gain some
        // performance, uncomment the following line:
        // config.devicePixelRatio = 1;

        canvas.style.width = window.innerWidth + 'px';
        canvas.style.height = window.innerHeight + 'px';

        unityShowBanner('WebGL builds are not supported on mobile devices.');
       else 
        // Desktop style: Render the game canvas in a window that can be maximized to fullscreen:

        canvas.style.width = "960px";
        canvas.style.height = "600px";
      

      loadingBar.style.display = "block";

      var unityInstance_G;

      var script = document.createElement("script");
      script.src = loaderUrl;
      script.onload = () => 
        createUnityInstance(canvas, config, (progress) => 
          progressBarFull.style.width = 100 * progress + "%";
        ).then((unityInstance) => 
          loadingBar.style.display = "none";

          unityInstance_G = unityInstance;

          fullscreenButton.onclick = () => 
            unityInstance.SetFullscreen(1);
          ;

        ).catch((message) => 
          alert(message);
        );
      ;
      document.body.appendChild(script);
    </script>
  </body>
</html>

Unity 发布的 WebGL 使用SendMessage传递多个参数

如果要实现Unity与浏览器的数据交互一般都会采用两种方式

方法一:

Application.ExternalCall("SayHello","helloworld");

这种方式可以在Unity中调用伊尔迷案中的JS函数

 

方法二:

SendMessage("Main Camera", "FunctionName", “参数”);

这种方式可以在网页中用JS代码往Unity中传递参数,调用对应的函数

 

但我在平时使用的过程中法闲了一个问题就是SendMessage只接受一个参数,这就非常尴尬了,万一我们预留的函数需要多个参数呢,这个问题困惑了我好几天

 不论你怎么尝试着传递参数都会出现这种错误

我试过这样

SendMessage("Main Camera", "SetWenDu", 33,22);

还有这样

SendMessage("Main Camera", "SetWenDu", “33”+“22”);

但时候都会出现这种错误

直到我有一天看到了一个国外的博客

 

尊重版权我把原链接粘贴上

http://www.feedingedge.co.uk/blog/2011/03/09/browser-to-unity3d-communication-and-back-again/

 

 

我发现Unity的SendMessage本来就只支持一个参数,难怪我一直不成功

博客中使用了一种自定义分隔符的方式实现了多个参数的传递

 

 

unity中:

void inboundfunction(string indata)
{

string[] words = indata.Split(\'~\');

data1 = words[0];
moredata2 = words[1];
anotherpiece3 = words[2];

}

 

JS中:

<script type=”text/javascript”>
<!–
function callbackunity(arg)
{
alert(arg);
var unity = unityObject.getObjectById(“unityPlayer”);
unity.SendMessage(“Rezzer”, “inboundfunction”, “item1~item2~item3”);
}
–>
</script>

 

这种方法把多个参数合并成一个参数在C#中使用split吧参数分割开这样就巧妙地实现了多个参数的传递

 

以上是关于Unity 获取WebGL URL中参数,JS调用C#的主要内容,如果未能解决你的问题,请参考以下文章

Unity,WebGL, 页面JS调用Unity方法

unity webgl获取跳转页面的url信息

如何在 Unity/C# WebGL 平台中调用 async/await JavaScript 函数?

浅谈unity webGL与three.js

unity打包webgl程序和js键盘监听事件冲突的问题。

Unity_WebGL相关