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;
    }
}