unity webgl 系列:从本地硬盘上传文件到webgl沙盒中

  • 沙盒:浏览器的安全机制,浏览器内的进程不能直接访问本地计算机中的硬盘等硬件或数据。必须通过js作为中间层实现。
  • 需求:通过一个按钮,点击后选择文件传到webgl进程中。
  • 前置说明:需要有webgl模版等基础配备,已经可以发布webgl程序。
  • 借鉴:http://t.csdnimg.cn/p7de5

一、在__Internal.jslib中添加如下代码块

mergeInto(LibraryManager.library, 
{LoadFile:function (gameobjectName,fitter) {var gameobjectNameStr=Pointer_stringify(gameobjectName);var fitterStr=Pointer_stringify(fitter);console.log("GetSelectFileURL");console.log("需要被发送的物体名称转化:");console.log(gameobjectNameStr);console.log("需要筛选文件类型转化:");console.log(fitterStr);var fileInput = document.getElementById("load");//通过id获取创建好的input元素if(!fileInput){var fileInput = document.createElement('input');//创建input元素console.log("创建input元素");fileInput.setAttribute('id', "load");//给创建的input设置idfileInput.setAttribute('type', 'file');fileInput.setAttribute('style','display:none;');fileInput.setAttribute('style','visibility:hidden;'); fileInput.setAttribute('multiple', '');fileInput.disabled=true;//使input元素不可点击,否则会导致页面上所有位置都可唤起文件对话框document.body.appendChild(fileInput);}fileInput.accept=fitterStr;fileInput.disabled=false;//设置input可点击,否则无法通过click()打开文件对话框fileInput.click()//打开文件对话框fileInput.onclick = function (event) {this.value = null;};fileInput.onchange = function (event) {//如果需要在unity中获取文件内容,在onchange中获取后通过SendMessage()传回给unityvar files = event.target.files;var res={Path:URL.createObjectURL(files[0]),FileName:files[0].name};gameInstance.SendMessage(gameobjectNameStr, 'FileDialogResult', JSON.stringify(res));}document.onmouseup = function() {fileInput.click();document.onmouseup = null;}fileInput.disabled=true;//结束时再次设置input不可点击,保证点击其他位置无法打开文件对话框//确保只有点击按钮2时才能打开文件对话框},
});

代码说明

该js脚本中,LoadFile函数名,接收一个游戏物体名称和过滤文件格式字符串。

游戏物体名称用于在该js函数中发送广播,叫该游戏物体执行指定挂在在该物体mono脚本上的指定方法。

注意所有C#传给js的字符串都需要用Pointer_stringify过一遍,才能转化成js识别的字符串。

主要逻辑为:js动态创建一个元素,设置交互属性,定义选择文件事件函数,在函数内部用:

gameInstance.SendMessage(gameobjectNameStr, 'FileDialogResult', JSON.stringify(res));

其中,gameInstance是unity运行实例,有的叫unityInstance或者别的东西,具体看自己js模版中定义的变量。gameobjectNameStr:转化过后的游戏物体名称;FileDialogResult:游戏物体上的需要被执行的函数;JSON.stringify(res):该函数接收的一个参数,这里我封装为一个json对象可以传递多个参数,传过去后解析为一个文件信息类。

二、调用

在ui按钮中挂载脚本,这里文件格式以表格为例:

    public class JSFileInfo{public string Path { get; set; }public string FileName { get; set; }}
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Networking;public class LoadExlBtn : MonoBehaviour
{public string fileFullPath;[DllImport("__Internal")]private static extern void LoadFile(string gameobjectName,string fitter);public void Add_File(){if (Application.platform == RuntimePlatform.WebGLPlayer){LoadFile(gameObject.name,".xls,.xlsx");//web端调用方法}}public void FileDialogResult(string JsFileInfoStr){Debug.Log(JsFileInfoStr);JSFileInfo jsFileInfo = JsonConvert.DeserializeObject<JSFileInfo>(JsFileInfoStr);Debug.Log(jsFileInfo.Path);Debug.Log(jsFileInfo.FileName);StartCoroutine(LoadData(jsFileInfo,null));}IEnumerator LoadData(JSFileInfo jsFileInfo,Action<FileStream> action){UnityWebRequest request = UnityWebRequest.Get(jsFileInfo.Path);//创建文件夹string dirPath = Path.Combine(Application.persistentDataPath, "Exls");Debug.Log("将被存至目录:"+dirPath);if (!Directory.Exists(dirPath)){Directory.CreateDirectory(dirPath);}string fullPath = Path.Combine(dirPath, jsFileInfo.FileName);request.downloadHandler = new DownloadHandlerFile(fullPath);//路径+文件名Debug.Log("复制到沙盒ing");yield return request.SendWebRequest();if (request.result==UnityWebRequest.Result.Success){Debug.Log("复制到沙盒完成");fileFullPath = fullPath;FileStream fs = new FileStream(fullPath, FileMode.Open);Debug.Log(fs.Length);//byteDebug.Log(fs.Name);//路径+名if (action!=null){action(fs);}fs.Close();FileInfo f = new FileInfo(fullPath);Debug.Log(f.Name);}else{Debug.Log(request.error);}  }}

主要逻辑:

  1. 编辑器中添加按钮监听Add_File()
  2. 调用外部js中的LoadFile,传入本按钮名称、文件过滤格式。
  3. 在js中创建点击元素,模拟点击,获取文件对于浏览器沙盒来说的url(是blob:xxx的形式),广播消息给这个按钮的FileDialogResult。
  4. 在FileDialogResult中开协程用UnityWebRequest将文件存到浏览器沙盒中的persistentDataPath。
  5. (如果是图片文字等简单的东西可以不用存为实体文件,直接用api)
    IEnumerator LoadTexture2D(string url, Action<Texture2D> taskCompletedCallBack){UnityWebRequest request = UnityWebRequestTexture.GetTexture(url);yield return request.SendWebRequest();if (request.isHttpError || request.isNetworkError){ }else{var texture = DownloadHandlerTexture.GetContent(request);taskCompletedCallBack(texture);}}
  6. 在yield return request.SendWebRequest()后打开文件流处理文件逻辑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/634870.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习从入门到不想放弃-6

这节要讲完距离基础部分就真完事了,不继续在基础中求得基础了,我发现也没人看 书接前文深度学习从入门到不想放弃-5 (qq.com) 前文书写到要合理的设计特征是什么概念,我们再拿两个例子复习一下 比如一个卖车网站,上节我们讲过对物体识别可以用RGB来表示颜色的维度,…

大数据开发之Hadoop(完整版+练习)

第 1 章&#xff1a;Hadoop概述 1.1 Hadoop是什么 1、Hadoop是一个由Apache基金会所开发的分布式系统基础架构。 2、主要解决&#xff0c;海量数据的存储和海量数据的分析计算问题。 3、Hadoop通常是指一个更广泛的概念-Hadoop生态圈 1.2 Hadoop优势&#xff08;4高&#xf…

第9章-第1节-关于Java中properties配置文件的介绍

properties类也是基于流&#xff0c;不算很难&#xff0c;下面直接上代码&#xff1a; Dogcom.entity.Dog Catcom.entity.Cat Pigcom.entity.Pig Birdcom.entity.Bird ... Properties properties new Properties(); //配置文件读取对象 properties.load(new FileInputStream…

linux云服务器 如何将数据盘挂载到系统盘上面?

先认识认识下面几个常用命令 lsblk 命令&#xff1a;查看设备列表&#xff0c;也就是能看到系统盘和数据盘一般为&#xff1a;vda&#xff08;系统盘&#xff09;、vdb&#xff08;数据盘&#xff09;等等 lsblk"ls" 是 "list" 的缩写&#xff1a; lsblk…

【C语言深度剖析——第四节(关键字4)】《C语言深度解剖》+蛋哥分析+个人理解

追求本质&#xff0c;不断进步 本文由睡觉待开机原创&#xff0c;转载请注明出处。 本内容在csdn网站首发 欢迎各位点赞—评论—收藏 如果存在不足之处请评论留言&#xff0c;共同进步&#xff01; 这里写目录标题 一、空间的申请1.变量定义1.1变量定义的概念&#xff1a;1.2变…

小程序 常用组件

文章目录 常见组件viewtextimageswipernavigatorrich-textnodes属性 buttoniconfromradiocheckbox 常见组件 重点讲解⼩程序中常⽤的布局组件 view,text,rich–text,button,image,navigator,icon,swiper,radio,checkbox。 等 view 代替 原来的 div 标签 <view hover-clas…

C语言基础语法跟练 day4

41、牛牛有一个半径为 r 的球&#xff0c;他想知道这个球的体积。 #include <stdio.h> #include<math.h> int main() {float r;scanf("%f",&r);float v (4.0/3)*3.14*pow(r,3);printf("%.2f",v);return 0; } 42、小乐乐比较懒惰&#x…

GPT应用程序上线注意的问题

在将GPT应用程序上线之前&#xff0c;有一些重要的问题需要注意&#xff0c;以确保应用程序的成功运行、用户满意度和合规性。以下是一些建议&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 合规性和…

SpringCloud OpenFegin 传递Date类型的参数时,接收端多出14个小时的问题

SpringCloud OpenFegin 传递Date类型的参数时&#xff0c;接收端多出14个小时的问题 1. OpenFegin写法 入参&#xff1a; “startTime”: “2024-01-16 00:00:00”, “endTime”: “2024-01-18 23:59:59”, GetMapping("/queryDisposalComplete")JsonResult<Ma…

海盗王NPC出售物品解析器

在编辑或者查看NPC出售物品的时候&#xff0c;需要了解它到底出售了那些物品。 当物品很多的时候&#xff0c;就很难一个一个地去查了。 想到之前有做过一个物品编辑器&#xff0c;于是就想在那个基础上再增加一个NPC物品分析器功能。 实现如下&#xff1a; 将NPC的出售列表直接…

Android现代开发推荐 | Android Showcase 2.0

Android现代开发推荐 | Android Showcase 2.0 Android Showcase是一个完整的Android应用程序示例&#xff0c;它使用了现代的Android应用程序开发方法&#xff0c;集成了流行的开发工具、库和代码检查工具&#xff0c;以及强大的测试框架和持续集成&#xff08;CI&#xff09;…

《WebKit 技术内幕》之四(3): 资源加载和网络栈

3. 网络栈 3.1 WebKit的网络设施 WebKit的资源加载其实是交由各个移植来实现的&#xff0c;所以WebCore其实并没有什么特别的基础设施&#xff0c;每个移植的网络实现是非常不一样的。 从WebKit的代码结构中可以看出&#xff0c;网络部分代码的确比较少的&#xff0c;它们都在…

AI 编程的机会和未来:从 Copilot 到 Code Agent

大模型的快速发展带来了 AI 应用的井喷。统计 GPT 使用情况&#xff0c;编程远超其他成为落地最快、使用率最高的场景。如今&#xff0c;大量程序员已经习惯了在 AI 辅助下进行编程。数据显示&#xff0c;GitHub Copilot 将程序员工作效率提升了 55%&#xff0c;一些实验中 AI …

Redis多线程模型探究

在技术快速发展的当下&#xff0c;Redis以其高效的单线程模型在众多数据库技术中脱颖而出。 这项被设计来高速读写内存数据的技术&#xff0c;如今却在面临多核心时代的挑战下&#xff0c;开始拥抱多线程。 这篇文章将带你了解Redis的单线程之路&#xff0c;解读它为何能在多线…

IDA Pro 7.7和8.3共用方案

1.问题 IDA 8.3版本放出来后&#xff0c;我安装之后&#xff0c;把之前用的正好的7.7给卸载了&#xff0c;然后发现&#xff1a;IDA 8.3版本只能反编译x86和x64两个架构&#xff0c;而我又是arm和arm64的重度用户&#xff0c;只能把旧版下载回来。问题就出现在这里。 &#x…

Autosar信息安全入门系列01-SecOC基础介绍

本文框架 1. 概述2. SecOC基本概念2.1 SecOC是什么&#xff1f;2.2 新鲜度值与MAC值2.3 SecOC报文格式 3. SecOC报文发送及接收逻辑3.1 SecOC报文的发送3.2 SecOC报文的接收 1. 概述 本文为Autosar通信入门系列介绍&#xff0c;如您对AutosarMCAL配置&#xff0c;通信&#xf…

【开源】基于JAVA语言的免税店商城管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、系统设计2.1 功能模块设计2.2 研究方法 三、系统展示四、核心代码4.1 查询免税种类4.2 查询物品档案4.3 新增顾客4.4 新增消费记录4.5 审核免税 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的免税店商城管理系…

AI嵌入式K210项目(15)-安全散列算法加速器

文章目录 前言一、什么是SHA256&#xff1f;实验原理 二、K210的安全散列算法加速器三、实验过程总结 前言 K210内置了丰富的加速器&#xff0c;包括神经网络处理器 (KPU)&#xff0c;AES(高级加密加速器)&#xff0c;APU 麦克风阵列语音数据加速计算处理器&#xff0c;现场可…

2024--Django平台开发-订单项目管理用户认证+动态菜单+权限控制(十三)

day13 订单管理项目开发 1.表结构设计 1.1 abstract类 from django.db import modelsclass ActiveBaseModel(models.Model):active models.SmallIntegerField(verbose_name"状态", default1, choices((1, "激活"), (0, "删除"),))class Meta:…

交叉编译工具 aarch64-linux-gnu-gcc 的介绍与安装

AArch64 是随 ARMv8 ISA 一起引入的 64 位架构&#xff0c;用于执行 A64 指令的计算机。而且在 AArch64 状态下执行的代码只能使用 A64 指令集。&#xff0c;而不能执行 A32 或 T32 指令。但是&#xff0c;与 AArch32 中不同&#xff0c;在64位状态下&#xff0c;指令可以访问 …