有个需求,点击按钮,调用浏览器下载,将UnityWelGL内的截图、图片等文件通过浏览器下载保存。百度没搜到,遂谷歌查了一下,将解决方法放在这里。

原理

C#代码不能直接操作浏览器,不要紧,Unity提供的jslib可以与浏览器交互!它与普通的js文件没什么不同!

一个可行的方法:C#调用引入的jslib,将序列化后的图片/文件资料传递给jslib内的方法,jslib与浏览器交互并触发下载。

代码(以下载图片为例)

ImageDownloader.jslib

//ImageDownloader.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;
        }
        //atob解码使用base64编码的字符串
        var binary = fixBinary(atob(msg));
        var data = new Blob([binary], { type: contentType });
        //创建一个html dom用于触发blob下载
        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);
    }
};
//并入Unity中,官方写法。
mergeInto(LibraryManager.library, ImageDownloaderPlugin)

把这个jslib丢到Plugins目录下,这样它就会作为插件引入Unity。

c#代码

引入插件

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

测试用的调用方法

//TestJPEGDownload.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestJPEGDownload : MonoBehaviour
{

    public Sprite sprite;
    public UnityEngine.UI.Button button;

    private void Start()
    {
        button.onClick.AddListener(this.onButtonClick);
    }

    private void onButtonClick()
    {
        byte[] photoByte = getImageSprite();//获取jpeg图像的字节流
        if (photoByte != null) {
            DownloadImage(photoByte, sprite.name + ".jpg");
        }else{
            Debug.LogError("不得了");
        }
    }

    private byte[] getImageSprite()
    {
        if (sprite) {
            return sprite.texture.EncodeToJPG();
        }
        return null;
    }
}

上面就是UnityWebGL内图片调用浏览器下载的方法。至于下载其他类型的文件,方法大同小异。

把jslib当作普通的的js文件,使用和普通js没差的方法与浏览器交互,真鸡儿牛批。

我来吐槽

*

*

1位绅士参与评论

  1. 野兔12-02 21:17 (20小时前)回复

    本文仅提供一个解决思路,它已经成功验证了从Unity内到浏览器端传递数据的解决方法。
    至于多个不同格式或多个文件,你可以做自己的处理,诸如压缩,混合,下载队列,这与本文内容无关。

  2. littleplus11-29 16:14 (4天前)回复

    只有兔子的博客依然活着(),我的博客活着,但是已经死了(