Unity实现网页端 打开本地文件选择图片上传到阿里云的OSS

第一步 在Plugins文件下创建 OSSFileUploader.jslib(用记事本创建,更改后缀名就行)文件

csharp 复制代码
mergeInto(LibraryManager.library, {
    // Global variables for callback functions
    uploadCallback: null,
    statusCallback: null,

    // Initialize uploader
    InitializeUploader: function() {
        // Create hidden file input element
        var fileInput = document.createElement('input');
        fileInput.type = 'file';
        fileInput.id = 'unityFileInput';
        fileInput.style.display = 'none';
        document.body.appendChild(fileInput);

        // Listen for file selection events
        fileInput.addEventListener('change', async function(event) {
            var file = event.target.files[0];
            if (file) {
                console.log('Unity selected file:', file.name);
                
                // Get global scope safely within the event handler
                var globalScope;
                if (typeof window !== 'undefined') {
                    globalScope = window;
                } else if (typeof global !== 'undefined') {
                    globalScope = global;
                } else if (typeof self !== 'undefined') {
                    globalScope = self;
                } else {
                    globalScope = {};
                }
                
                // Call Unity callback function
                if (globalScope.uploadCallbackObjectName && globalScope.uploadCallbackMethodName) {
                    SendMessage(globalScope.uploadCallbackObjectName, globalScope.uploadCallbackMethodName, file.name);
                }
                
                // Start upload - inline all functionality here
                try {
                    // Notify Unity of status update
                    if (globalScope.statusCallbackObjectName && globalScope.statusCallbackMethodName) {
                        SendMessage(globalScope.statusCallbackObjectName, globalScope.statusCallbackMethodName, "Getting upload signature...");
                    }

                    // Generate timestamped filename
                    var now = new Date();
                    var timestamp = now.getFullYear() +
                        String(now.getMonth() + 1).padStart(2, '0') +
                        String(now.getDate()).padStart(2, '0') +
                        String(now.getHours()).padStart(2, '0') +
                        String(now.getMinutes()).padStart(2, '0') +
                        String(now.getSeconds()).padStart(2, '0');
					
					const random = Math.random().toString(36).substr(2, 9);
					const timestamp_random = `${timestamp}_${random}`;
                    var nameWithoutExt = file.name.substring(0, file.name.lastIndexOf('.'));
                    var extension = file.name.substring(file.name.lastIndexOf('.'));
                    var filename_Timestamp = nameWithoutExt + '_' + timestamp_random + extension;

                    console.log('Original filename:', file.name);
                    console.log('Timestamped filename:', filename_Timestamp);

                    // Get OSS upload signature  这个地址找你们管理OSS的人员要
                    var response = await fetch("OSS上传获取临时授权地址", {
                        method: "GET"
                    });

                    if (!response.ok) {
                        throw new Error("Failed to get signature");
                    }

                    var res = await response.json();
                    if (res.code !== 200) {
                        throw new Error("Failed to get credentials");
                    }

                    var signatureData = res.data;

                    // Notify Unity of status update
                    if (globalScope.statusCallbackObjectName && globalScope.statusCallbackMethodName) {
                        SendMessage(globalScope.statusCallbackObjectName, globalScope.statusCallbackMethodName, "Uploading file...");
                    }

                    // Prepare upload data
                    var dir_file = signatureData.upload_dir + filename_Timestamp;
                    var formData = new FormData();

                    formData.append("success_action_status", "200");
                    formData.append("policy", signatureData.policy);
                    formData.append("x-oss-signature", signatureData.signature);
                    formData.append("x-oss-signature-version", "OSS4-HMAC-SHA256");
                    formData.append("x-oss-credential", signatureData.x_oss_credential);
                    formData.append("x-oss-date", signatureData.x_oss_date);
                    formData.append("key", dir_file);
                    formData.append("x-oss-security-token", signatureData.security_token);
                    formData.append("file", file);

                    console.log("Upload URL:", signatureData.host + signatureData.upload_dir + filename_Timestamp);

                    // Upload file to OSS
                    var uploadResponse = await fetch(signatureData.host, {
                        method: "POST",
                        body: formData
                    });

                    if (!uploadResponse.ok) {
                        throw new Error("Upload failed");
                    }

                    // Success - notify Unity
                    var fileUrl = signatureData.host + signatureData.upload_dir + filename_Timestamp;
                    
                    // Store upload information for JSON retrieval
                    globalScope.lastUploadInfo = {
                        "selectedFile": file.name,
                        "originalFilename": file.name,
                        "timestampedFilename": filename_Timestamp,
                        "uploadUrl": fileUrl,
                        "fileUrl": fileUrl,
                        "uploadTime": new Date().toISOString(),
                        "status": "success"
                    };
                    
                    if (globalScope.statusCallbackObjectName && globalScope.statusCallbackMethodName) {
                        SendMessage(globalScope.statusCallbackObjectName, globalScope.statusCallbackMethodName, "File uploaded successfully!");
                    }

                    console.log("Upload successful, file URL:", fileUrl);
                    
                    // Call Unity callback function, pass file URL
                    if (globalScope.uploadCallbackObjectName && globalScope.uploadCallbackMethodName) {
                        SendMessage(globalScope.uploadCallbackObjectName, globalScope.uploadCallbackMethodName, fileUrl);
                    }

                } catch (error) {
                    console.error("Error occurred during upload:", error);
                    
                    // Notify Unity of upload failure
                    if (globalScope.statusCallbackObjectName && globalScope.statusCallbackMethodName) {
                        SendMessage(globalScope.statusCallbackObjectName, globalScope.statusCallbackMethodName, "Upload failed: " + error.message);
                    }
                }
              
            }
        });

        console.log('Unity file uploader initialized successfully');
    },

    // Trigger file selection
    SelectFile: function() {
        var fileInput = document.getElementById('unityFileInput');
        if (fileInput) {
            fileInput.click();
        }
    },

    // Set status callback function
    SetStatusCallback: function(objectNamePtr, methodNamePtr) {
        // Get global scope safely
        var globalScope;
        if (typeof window !== 'undefined') {
            globalScope = window;
        } else if (typeof global !== 'undefined') {
            globalScope = global;
        } else if (typeof self !== 'undefined') {
            globalScope = self;
        } else {
            globalScope = {};
        }
        
        var objectName = UTF8ToString(objectNamePtr);
        var methodName = UTF8ToString(methodNamePtr);
        
        globalScope.statusCallbackObjectName = objectName;
        globalScope.statusCallbackMethodName = methodName;
        
        console.log('Status callback set successfully for object:', objectName, 'method:', methodName);
    },

    // Set upload complete callback function
    SetUploadCallback: function(objectNamePtr, methodNamePtr) {
        // Get global scope safely
        var globalScope;
        if (typeof window !== 'undefined') {
            globalScope = window;
        } else if (typeof global !== 'undefined') {
            globalScope = global;
        } else if (typeof self !== 'undefined') {
            globalScope = self;
        } else {
            globalScope = {};
        }
        
        var objectName = UTF8ToString(objectNamePtr);
        var methodName = UTF8ToString(methodNamePtr);
        
        globalScope.uploadCallbackObjectName = objectName;
        globalScope.uploadCallbackMethodName = methodName;
        
        console.log('Upload callback set successfully for object:', objectName, 'method:', methodName);
    },

    // Get upload information as JSON string
    GetUploadInfoAsJson: function() {
        // Get global scope safely
        var globalScope;
        if (typeof window !== 'undefined') {
            globalScope = window;
        } else if (typeof global !== 'undefined') {
            globalScope = global;
        } else if (typeof self !== 'undefined') {
            globalScope = self;
        } else {
            globalScope = {};
        }

        // Check if upload info exists
        if (!globalScope.lastUploadInfo) {
            return null;
        }

        // Convert upload info to JSON string
        var jsonString = JSON.stringify(globalScope.lastUploadInfo);
        
        // Allocate memory for the string and return pointer
        var bufferSize = lengthBytesUTF8(jsonString) + 1;
        var buffer = _malloc(bufferSize);
        stringToUTF8(jsonString, buffer, bufferSize);
        return buffer;
    },

});

第二步 创建C#代码

csharp 复制代码
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System.Runtime.InteropServices;
using System;

public class FileUploadUI : MonoBehaviour
{
    [Header("UI组件")]
    public Button uploadButton, infoButton;
    public TextMeshProUGUI statusText;
    public TextMeshProUGUI resultText;

    // C# 代码示例
    [DllImport("__Internal")]
    private static extern void InitializeUploader();

    [DllImport("__Internal")]
    private static extern string SelectFile();

    [DllImport("__Internal")]
    private static extern void SetStatusCallback(string objectName, string methodName);

    [DllImport("__Internal")]
    private static extern void SetUploadCallback(string objectName, string methodName);

    [DllImport("__Internal")]
    private static extern string GetUploadInfoAsJson();

    // 使用
    void Start()
    {


        //先点击初始化
        infoButton.onClick.AddListener(GetUploadInfoJson);
        //再点击上传
        uploadButton.onClick.AddListener(OnSelectFileClick);
#if UNITY_WEBGL && !UNITY_EDITOR
 InitializeUploader();
                SetStatusCallback(gameObject.name, "OnStatusUpdate");
                SetUploadCallback(gameObject.name, "OnUploadComplete");
#endif
    }


    void OnSelectFileClick()
    {
        string fileUrl = SelectFile();
        resultText.text = "文件名:" + fileUrl;
        Debug.Log("文件名:" + fileUrl);
    }

    public void OnStatusUpdate(string status)
    {
        Debug.Log("状态更新: " + status);
        statusText.text = status;
    }

    public void OnUploadComplete(string fileUrl)
    {
        Debug.Log("上传完成,文件URL: " + fileUrl);
        //可以通过这个URL地址把 图片加载出来,赋值给Image,
        resultText.text = fileUrl;

        // 获取JSON格式的上传信息
        GetUploadInfoJson();
    }

    public void GetUploadInfoJson()
    {
#if UNITY_WEBGL && !UNITY_EDITOR
            string jsonInfo = GetUploadInfoAsJson();
            if (!string.IsNullOrEmpty(jsonInfo))
            {
                Debug.Log("上传信息JSON: " + jsonInfo);
                resultText.text ="信息:"+ jsonInfo;
            }
            else
            {
                Debug.Log("没有找到上传信息");
            }
#else
        Debug.Log("该功能仅在WebGL平台可用");
#endif
    }
}
相关推荐
AA陈超21 小时前
虚幻引擎5 GAS开发俯视角RPG游戏 P05-08 UI 部件数据表
c++·游戏·ue5·游戏引擎·虚幻
future_studio1 天前
聊聊 Unity(小白专享、C# 小程序 之 播放器)
unity·小程序·c#
向宇it1 天前
【unity实战】MapMagic 2实战例子
游戏·3d·unity·c#·游戏引擎
SlowFeather1 天前
Unity TMP可控角度多色渐变文字
unity·游戏引擎
TG_yunshuguoji1 天前
阿里云国际代理商:有哪些文件适合阿里云CDN分发?
阿里云·云计算
霜绛1 天前
Unity:UGUI笔记(一)——三大基础控件、组合控件
笔记·学习·unity·游戏引擎
小趴菜82272 天前
Android中加载unity aar包实现方案
android·unity·游戏引擎
今夕资源网2 天前
牛童三国单机游戏Unity源码 免费开源
游戏·unity·单机游戏·游戏源码·unity源码·unity游戏
future_studio2 天前
聊聊 Unity(小白专享、C# 小程序 之 图片播放器)
unity·小程序·c#