由于浏览器的安全设置,System.IO的大部分功能都会受限。本文假设你要在Unity做一个头像上传的功能,这里我提供一个通过Unity和JavaScript实现的方法。
先在工程里起一个Plugins文件夹,用文本编辑器新建一个FileUploader.jslib。
var ImageUploaderPlugin = {
ImageUploaderCaptureClick: function() {
if (!document.getElementById('ImageUploaderInput')) {
var fileInput = document.createElement('input');
fileInput.setAttribute('type', 'file');
fileInput.setAttribute('id', 'ImageUploaderInput');
fileInput.style.visibility = 'hidden';
fileInput.onclick = function (event) {
this.value = null;
};
fileInput.onchange = function (event) {
SendMessage('FileOpenDialog', 'OnFileSelected', URL.createObjectURL(event.target.files[0]));
}
document.body.appendChild(fileInput);
}
var OpenFileDialog = function() {
document.getElementById('ImageUploaderInput').click();
document.getElementById('canvas').removeEventListener('click', OpenFileDialog);
};
document.getElementById('canvas').addEventListener('click', OpenFileDialog, false);
}
};
mergeInto(LibraryManager.library, ImageUploaderPlugin)
在工程里起一个WebGLTemplate文件夹,在里头再新建一个文件夹,名字随意,这里存放着WebGL打包用到的HTML模板。你可以先把Unity自带的先复制进去。
不管你最后基于哪个模板改,你都得在html里再加个JavaScript函数
function onFileSelected(event) {
var file = event.target.files[0];
var jsonObject = {
Path: URL.createObjectURL(file),
Filename: file.name
};
unityInstance.SendMessage('FileOpenDialog', 'OnFileSelected', JSON.stringify(jsonObject));
}
document.getElementById('upload').addEventListener('change', onFileSelected);
其中FileOpenDialog是GameObject名(这个就相当于Unity里GameObject.SendMessage),OnFileSelected顾名思义是回调,我们把本地中的文件以JSON形式发送给Unity,里头包含blob地址和文件名。
然后还得再加个隐藏的Input元素来接收选择的文件,例如:
<input id="upload" type="file" style="display:none" onchange="onFileSelected(event)">
这样,就可以在其他地方直接调用`OpenFileDialog`方法来打开文件选择对话框。
调用方式见如下:
// 通过JavaScript函数来触发文件选择对话框
Application.ExternalEval(@"
document.getElementById('upload').click();
");
回调以及文件内容的读取可以参考这个:
// 在文件选择对话框中选择完成后的回调函数
public void OnFileSelected(string info)
{
FileInfo result = JsonConvert.DeserializeObject<FileInfo>(info);
Debug.Log("Selected File: " + result.Filename + ", path: " + result.Path);
StartCoroutine(LoadData(result.Path));
}
IEnumerator LoadData(string url)
{
UnityWebRequest request = UnityWebRequest.Get(url);
DownloadHandlerBuffer handler = new DownloadHandlerBuffer();
request.downloadHandler = handler;
yield return request.SendWebRequest();
if (request.result != UnityWebRequest.Result.Success)
{
Debug.Log(request.error);
yield break;
}
Debug.Log("File loaded! " + url);
byte[] data = handler.data;
// 根据需要进行处理 data 的操作
}
[Serializable]
public class FileInfo
{
public string Path;
public string Filename;
}
拿到的blob地址一定要用UnityWebRequest去读并拿到二进制数据,切记!