这一版有部分问题,使用最下面的…
WebFilePicker.jslib (放在Plugins目录)
var WebFilePickerLibrary = {
/**
* 从浏览器中获取文件并发送给 Unity WebGL 应用程序。
* @param {number} objectNamePtr - Unity 对象名称的指针。
* @param {number} funcNamePtr - Unity 回调函数名称的指针。
* @param {number} fileTypePtr - 允许的文件类型字符串的指针。
* @param {number} allowMultiple - 是否允许多选(1 表示允许多选,0 表示单选)。
* @param {number} maxSizeMB - 文件大小限制(单位:MB)。如果 <=0,则无限制。
*/
getFileFromBrowser: function(objectNamePtr, funcNamePtr, fileTypePtr, allowMultiple, maxSizeMB) {
var objectName = UTF8ToString(objectNamePtr);
var funcName = UTF8ToString(funcNamePtr);
var fileType = UTF8ToString(fileTypePtr);
var maxSizeBytes = maxSizeMB > 0 ? maxSizeMB * 1048576 : 0;
var input = document.createElement("input");
input.type = "file";
input.multiple = !!allowMultiple; // 转换为布尔值
input.accept = fileType;
input.style.display = "none";
/**
* 处理通用文件
* @param {File[]} files - 用户选择的文件列表。
*/
var handleFiles = function(files) {
var results = [];
var filesProcessed = 0;
for (let i = 0; i < files.length; i++) {
const file = files[i];
// 检查文件大小限制
if (maxSizeBytes > 0 && file.size > maxSizeBytes) {
SendMessage(objectName, funcName,
`error:File '${file.name}' exceeds limit (${(file.size / 1048576).toFixed(1)}MB/${maxSizeMB}MB)`);
return;
}
const reader = new FileReader();
reader.onload = (e => {
results.push({
name: file.name,
type: file.type,
data: new Uint8Array(e.target.result)
});
filesProcessed++;
// 所有文件处理完毕时发送结果
if (filesProcessed === files.length) {
var resultData = results.map(result => {
return {
name: result.name,
type: result.type,
data: Array.from(result.data)
};
});
SendMessage(objectName, funcName, JSON.stringify(resultData));
}
});
reader.readAsArrayBuffer(file);
}
};
// 监听文件选择事件
input.addEventListener('change', function(evt) {
const files = evt.target.files;
if (!files || files.length === 0) {
SendMessage(objectName, funcName, "error:No file selected");
return;
}
handleFiles(files);
});
// 触发文件选择对话框
document.body.appendChild(input);
input.click();
document.body.removeChild(input);
}
};
mergeInto(LibraryManager.library, WebFilePickerLibrary);
WebFilePicker.cs
using System;
namespace MYTOOL
{
[Serializable]
public class FileResult
{
public string name; // 文件名称
public string type; // MIME 类型
public byte[] data; // 二进制数据
}
/// <summary>
/// 提供与Unity WebGL平台交互的方法,用于从浏览器中获取文件(图片、视频或其他类型)
/// </summary>
public static class WebFilePicker
{
public const string IMAGE_FILE_TYPE = "image/*";
public const string VIDEO_FILE_TYPE = "video/*";
#if UNITY_WEBGL
[System.Runtime.InteropServices.DllImport("__Internal")]
private static extern void getFileFromBrowser(string objName, string methodName, string fileType, bool allowMultiple, int maxSizeMB);
#endif
/// <summary>
/// 从浏览器中获取图片文件
/// </summary>
/// <param name="objName">Unity对象名称</param>
/// <param name="methodName">Unity回调方法名称</param>
/// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
public static void GetImageFromBrowser(string objName, string methodName, int maxSizeMB = 0)
{
GetFileFromBrowser(objName, methodName, IMAGE_FILE_TYPE, maxSizeMB);
}
/// <summary>
/// 从浏览器中获取多个图片文件
/// </summary>
/// <param name="objName">Unity对象名称</param>
/// <param name="methodName">Unity回调方法名称</param>
/// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
public static void GetImagesFromBrowser(string objName, string methodName, int maxSizeMB = 0)
{
GetFilesFromBrowser(objName, methodName, IMAGE_FILE_TYPE, maxSizeMB);
}
/// <summary>
/// 从浏览器中获取视频文件
/// </summary>
/// <param name="objName">Unity对象名称</param>
/// <param name="methodName">Unity回调方法名称</param>
/// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
public static void GetVideoFromBrowser(string objName, string methodName, int maxSizeMB = 0)
{
GetFileFromBrowser(objName, methodName, VIDEO_FILE_TYPE, maxSizeMB);
}
/// <summary>
/// 从浏览器中获取任意类型的文件
/// </summary>
/// <param name="objName">Unity对象名称</param>
/// <param name="methodName">Unity回调方法名称</param>
/// <param name="fileType">文件类型</param>
/// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
public static void GetFileFromBrowser(string objName, string methodName, string fileType, int maxSizeMB = 0)
{
#if UNITY_WEBGL && !UNITY_EDITOR
getFileFromBrowser(objName, methodName, fileType, false, maxSizeMB);
#else
UnityEngine.Debug.LogError("only implemented for WebGL platform.");
#endif
}
/// <summary>
/// 从浏览器中获取多个任意类型的文件
/// </summary>
/// <param name="objName">Unity对象名称</param>
/// <param name="methodName">Unity回调方法名称</param>
/// <param name="fileType">文件类型</param>
/// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
public static void GetFilesFromBrowser(string objName, string methodName, string fileType, int maxSizeMB = 0)
{
#if UNITY_WEBGL && !UNITY_EDITOR
getFileFromBrowser(objName, methodName, fileType, true, maxSizeMB);
#else
UnityEngine.Debug.LogError("only implemented for WebGL platform.");
#endif
}
}
}
使用:调用WebFilePicker里提供的方法,回调时返回json字符串,反序列化为FileResult即可拿到原始数据。
注意:mime_type => type
效果:
统一格式返回(数组)
WebFilePicker.jslib (放在Plugins目录)
var WebFilePickerLibrary = {
/**
* 从浏览器中获取文件并发送给 Unity WebGL 应用程序。
* @param {number} objectNamePtr - Unity 对象名称的指针。
* @param {number} funcNamePtr - Unity 回调函数名称的指针。
* @param {number} fileTypePtr - 允许的文件类型字符串的指针。
* @param {number} allowMultiple - 是否允许多选(1 表示允许多选,0 表示单选)。
* @param {number} maxSizeMB - 文件大小限制。如果<=0则无限制。
*/
getFileFromBrowser: function (objectNamePtr, funcNamePtr, fileTypePtr, allowMultiple, maxSizeMB) {
var objectName = UTF8ToString(objectNamePtr);
var funcName = UTF8ToString(funcNamePtr);
var fileType = UTF8ToString(fileTypePtr);
var maxSizeBytes = maxSizeMB > 0 ? maxSizeMB * 1048576 : 0;
var inputFile = document.createElement("input");
inputFile.type = "file";
inputFile.multiple = !!allowMultiple; // 转换为布尔值
inputFile.accept = fileType;
inputFile.style.display = "none";
// 标记是否已完成操作
let isHandled = false;
/**
* 处理通用文件
* @param {File[]} files - 用户选择的文件列表。
*/
var handleFiles = function (files) {
var results = [];
var filesProcessed = 0;
for (let i = 0; i < files.length; i++) {
const file = files[i];
// 检查文件大小限制
if (maxSizeBytes > 0 && file.size > maxSizeBytes) {
var errorResult = [{
result: -3,
name: file.name,
type: file.type,
data: []
}
];
SendMessage(objectName, funcName, JSON.stringify(errorResult));
return;
}
const reader = new FileReader();
reader.onload = (e => {
results.push({
result: 0,
name: file.name,
type: file.type,
data: Array.from(new Uint8Array(e.target.result))
});
filesProcessed++;
// 所有文件处理完毕时发送结果
if (filesProcessed === files.length) {
SendMessage(objectName, funcName, JSON.stringify(results));
}
});
reader.onerror = () => {
var errorResult = [{
result: -2,
name: file.name,
type: file.type,
data: []
}
];
SendMessage(objectName, funcName, JSON.stringify(errorResult));
};
reader.readAsArrayBuffer(file);
}
};
// 监听文件选择事件
inputFile.addEventListener('change', function (evt) {
isHandled = true;
const files = evt.target.files;
if (files.length > 0) {
handleFiles(files);
} else {
var cancelResult = [{
result: -1,
name: "",
type: "",
data: []
}
];
SendMessage(objectName, funcName, JSON.stringify(cancelResult));
}
// 清理 focus 监听器
window.removeEventListener('focus', onFocus);
});
// 定义 focus 事件的回调函数
var onFocus = () => {
setTimeout(() => {
if (!isHandled) {
var cancelResult = [{
result: -1,
name: "",
type: "",
data: []
}
];
SendMessage(objectName, funcName, JSON.stringify(cancelResult));
}
}, 200);
};
// 监听窗口焦点事件(部分浏览器取消选择后会触发)
window.addEventListener('focus', onFocus, {
once: true
});
// 触发文件选择对话框
document.body.appendChild(inputFile);
inputFile.click();
document.body.removeChild(inputFile);
}
};
mergeInto(LibraryManager.library, WebFilePickerLibrary);
using System;
namespace MYTOOL
{
[Serializable]
public class FileSelectionResult
{
/// <summary>
/// <para> 0 正常</para>
/// <para>-1 取消</para>
/// <para>-2 加载错误</para>
/// <para>-3 文件大小超出限制</para>
/// </summary>
public int result;
/// <summary>
/// 文件名称
/// </summary>
public string name;
/// <summary>
/// MIME 类型
/// </summary>
public string type;
/// <summary>
/// 二进制数据
/// </summary>
public byte[] data;
/// <summary>
/// 是否操作成功
/// </summary>
public bool IsSuccess => result == 0;
/// <summary>
/// 用户是否取消了操作
/// </summary>
public bool IsCancelled => result == -1;
/// <summary>
/// 是否发生加载错误
/// </summary>
public bool IsLoadError => result == -2;
/// <summary>
/// 文件大小是否超出限制
/// </summary>
public bool IsSizeExceeded => result == -3;
/// <summary>
/// 获取状态描述信息
/// </summary>
public string StatusMessage =>
result switch
{
0 => "操作成功",
-1 => "用户取消",
-2 => "加载错误",
-3 => "文件大小超出限制",
_ => "未知状态"
};
/// <summary>
/// 判断是否有文件数据
/// </summary>
public bool HasFileData => data != null && data.Length > 0;
/// <summary>
/// 获取文件大小(以字节为单位),如果 data 为空则返回 0
/// </summary>
public long GetFileSize() => data?.Length ?? 0;
}
/// <summary>
/// 提供与Unity WebGL平台交互的方法,用于从浏览器中获取文件(图片、视频或其他类型)
/// </summary>
public static class WebFilePicker
{
public const string IMAGE_FILE_TYPE = "image/*";
public const string VIDEO_FILE_TYPE = "video/*";
#if UNITY_WEBGL
[System.Runtime.InteropServices.DllImport("__Internal")]
private static extern void getFileFromBrowser(string objName, string methodName, string fileType, bool allowMultiple, int maxSizeMB);
#endif
/// <summary>
/// 从浏览器中获取图片文件
/// </summary>
/// <param name="objName">Unity对象名称</param>
/// <param name="methodName">Unity回调方法名称</param>
/// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
public static void GetImageFromBrowser(string objName, string methodName, int maxSizeMB = 0)
{
GetFileFromBrowser(objName, methodName, IMAGE_FILE_TYPE, maxSizeMB);
}
/// <summary>
/// 从浏览器中获取多个图片文件
/// </summary>
/// <param name="objName">Unity对象名称</param>
/// <param name="methodName">Unity回调方法名称</param>
/// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
public static void GetImagesFromBrowser(string objName, string methodName, int maxSizeMB = 0)
{
GetFilesFromBrowser(objName, methodName, IMAGE_FILE_TYPE, maxSizeMB);
}
/// <summary>
/// 从浏览器中获取视频文件
/// </summary>
/// <param name="objName">Unity对象名称</param>
/// <param name="methodName">Unity回调方法名称</param>
/// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
public static void GetVideoFromBrowser(string objName, string methodName, int maxSizeMB = 0)
{
GetFileFromBrowser(objName, methodName, VIDEO_FILE_TYPE, maxSizeMB);
}
/// <summary>
/// 从浏览器中获取任意类型的文件
/// </summary>
/// <param name="objName">Unity对象名称</param>
/// <param name="methodName">Unity回调方法名称</param>
/// <param name="fileType">文件类型</param>
/// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
public static void GetFileFromBrowser(string objName, string methodName, string fileType, int maxSizeMB = 0)
{
#if UNITY_WEBGL && !UNITY_EDITOR
getFileFromBrowser(objName, methodName, fileType, false, maxSizeMB);
#else
UnityEngine.Debug.LogError("only implemented for WebGL platform.");
#endif
}
/// <summary>
/// 从浏览器中获取多个任意类型的文件
/// </summary>
/// <param name="objName">Unity对象名称</param>
/// <param name="methodName">Unity回调方法名称</param>
/// <param name="fileType">文件类型</param>
/// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
public static void GetFilesFromBrowser(string objName, string methodName, string fileType, int maxSizeMB = 0)
{
#if UNITY_WEBGL && !UNITY_EDITOR
getFileFromBrowser(objName, methodName, fileType, true, maxSizeMB);
#else
UnityEngine.Debug.LogError("only implemented for WebGL platform.");
#endif
}
}
}