Unity WebGL+jslib实现与js通信(例.图片下载)
一、项目配置
按照上一篇文章配置即可
二、调用测试
1.新建jslib,我这里用txt新建。
mergeInto(LibraryManager.library, 
{
 
  Hello: function ()
  {
    window.alert("Hello, world!");
  },
 
  HelloString: function (str) 
  {
    window.alert(Pointer_stringify(str));
  },
 
   HelloFloat: function () 
   {
       return 1;
   },
 
 }); 
2.如果遇到打包时报错,检测编码格式

3. 将jslib放入Unity-Plugins文件夹下
4.C#端代码,引入Dll
    [DllImport("__Internal")]
    private static extern void Hello();
 
    [DllImport("__Internal")]
    private static extern void HelloString(string str);
 
    [DllImport("__Internal")]
    private static extern float HelloFloat(); 
5.C#端代码,调用
Hello();
HelloString("This is a string.");
HelloFloat(); 
6.打包测试,注意Editor模式运行会报错EntryPointNotFoundException。需要打包运行测试。
三、下载图片
1.对应jslib如下:
var ImageDownloaderPlugin = {
    ImageDownloader: function (str, fn) {
        console.log("start jslib download");
        var msg = Pointer_stringify(str);
        var fname = Pointer_stringify(fn);
        var contentType = 'image/jpeg';
        function fixBinary(bin) {
            var length = bin.length;
            var buf = new ArrayBuffer(length);
            var arr = new Uint8Array(buf);
            for (var i = 0; i < length; i++) {
                arr[i] = bin.charCodeAt(i);
            }
            return buf;
        }
        var binary = fixBinary(atob(msg));
        var data = new Blob([binary], { type: contentType });
        var link = document.createElement('a');
        link.download = fname;
        link.innerHTML = 'DownloadFile';
        link.setAttribute('id', 'ImageDownloaderLink');
        link.href = window.URL.createObjectURL(data);
        link.onclick = function () {
            var child = document.getElementById('ImageDownloaderLink');
            child.parentNode.removeChild(child);
        };
        link.style.display = 'none';
        document.body.appendChild(link);
        link.click();
        window.URL.revokeObjectURL(link.href);
    }
};
mergeInto(LibraryManager.library, ImageDownloaderPlugin)
 
注意编码格式,如果是utf-8的话,建议去掉“//中文注释”,否则unity会打包报错。
2.C#中引入DLL
    [DllImport("__Internal")]
    private static extern void ImageDownloader(string str, string fn); 
3.完整代码如下:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
    public Button saveBtn;
    public Image img;
    public Text text;
    [DllImport("__Internal")]
    private static extern void ImageDownloader(string str, string fn);
    
    public void DownloadImage(byte[] imageData, string imageFileName = "newpic")
    {
        if (imageData != null)
        {
            Debug.Log("Downloading..." + imageFileName);
            ImageDownloader(System.Convert.ToBase64String(imageData), imageFileName);
        }
    }
    // Start is called before the first frame update
    void Start()
    {
        text.text = "";
        saveBtn.onClick.AddListener(SavePicture);
    }
    void SavePicture()
    {
        //获取系统时间  
        System.DateTime now = new System.DateTime();
        now = System.DateTime.Now;
        string filename = string.Format("image{0}{1}{2}{3}.png", now.Day, now.Hour, now.Minute, now.Second);
        SaveTexture2DToPngFile(img.sprite.texture, filename);
        text.text = "图片已保存!";
    }
    public void SaveTexture2DToPngFile(Texture2D tex, string filePath)
    {
        byte[] data = DeCompress(tex).EncodeToPNG();
        DownloadImage(data, filePath);
    }
    public Texture2D DeCompress(Texture2D source)
    {
        RenderTexture renderTex = RenderTexture.GetTemporary(
            source.width,
            source.height,
            0,
            RenderTextureFormat.Default,
            RenderTextureReadWrite.Linear);
        Graphics.Blit(source, renderTex);
        RenderTexture previous = RenderTexture.active;
        RenderTexture.active = renderTex;
        Texture2D readableText = new Texture2D(source.width, source.height);
        readableText.ReadPixels(new Rect(0, 0, renderTex.width, renderTex.height), 0, 0);
        readableText.Apply();
        RenderTexture.active = previous;
        RenderTexture.ReleaseTemporary(renderTex);
        return readableText;
    }
}