[游戏开发][Unity]UnityWebRequest使用大全
首先记录个小问题
使用new UnityWebRequest的方式,最终的downloadHandler是个null
使用UnityWebRequest.Get的方式,最终的downloadHandler会是DownloadHandlerBuffer
从网站或本地下载内容,包括文本或二进制数据
IEnumerator downloadfile(string path)
{UnityWebRequest uwr = UnityWebRequest.Get(path);yield return uwr.SendWebRequest();if (uwr.result == UnityWebRequest.Result.Success){//加载文本Debug.Log("Success " + uwr.downloadHandler.text);//加载二进制数据//Debug.Log("Success " + uwr.downloadHandler.data);}elseDebug.LogError(uwr.error);
} 从网站或本地下载贴图
IEnumerator downloadfile(string path)
{UnityWebRequest uwr = UnityWebRequest.Get(path);yield return uwr.SendWebRequest();if (uwr.result == UnityWebRequest.Result.Success){//加载贴图Texture2D tex2D = DownloadHandlerTexture.GetContent(uwr);}elseDebug.LogError(uwr.error);
} 从网站或本地下载Assetbundle
IEnumerator downloadfile(string path)
{UnityWebRequest uwr = UnityWebRequest.Get(path);yield return uwr.SendWebRequest();if (uwr.result == UnityWebRequest.Result.Success){//加载ABAssetBundle ab = DownloadHandlerAssetBundle.GetContent(uwr)}elseDebug.LogError(uwr.error);
} 将表单发送到 http 服务器 (post)
IEnumerator downloadfile(string path)
{List<IMultipartFormSection> form = new List<IMultipartFormSection>();form.Add(new MultipartFormDataSection("fileld1=A&field2=B"));form.Add(new MultipartFormFileSection("data", "file.txt"));UnityWebRequest uwr = UnityWebRequest.Post(path,form);yield return uwr.SendWebRequest();if (uwr.result == UnityWebRequest.Result.Success)Debug.Log("Success " + uwr.downloadHandler.text);elseDebug.LogError(uwr.error);
} 将原始数据上传到 http 服务器 (put)
IEnumerator Upload()
{byte[] myData = System.Text.Encoding.UTF8.GetBytes("Chinar的测试数据");using (UnityWebRequest uwr = UnityWebRequest.Put("http://www.baidu.com", myData)){yield return uwr.SendWebRequest();if (uwr.result == UnityWebRequest.Result.Success)Debug.Log("Success " + uwr.downloadHandler.text);elseDebug.LogError(uwr.error);}
}
四、案例
一、断点续传
记录已经下载到的本地文件大小,向资源服务器发送请求时,通过请求头实现拿到剩下需要下载的内容,然后接着下载
确保对同一个资源文件的下载操作,就不存在资源会下载错误的情况,如果你在断点续传的阶段发现资源服务器上的资源已经更新,那就得删除之前下载的文件然后重新下载。
using System;
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;public class ChinarBreakpointRenewal : MonoBehaviour
{private bool _isStop; //是否暂停public Slider ProgressBar; //进度条public Text SliderValue; //滑动条值public Button startBtn; //开始按钮public Button pauseBtn; //暂停按钮string Url = "https://downsc.chinaz.net/Files/DownLoad/sound1/201808/10447.wav";/// <summary>/// 初始化UI界面及给按钮绑定方法/// </summary>void Start(){//初始化进度条和文本框ProgressBar.value = 0;SliderValue.text = "0.0%";//开始、暂停按钮事件监听startBtn.onClick.AddListener(OnClickStartDownload);pauseBtn.onClick.AddListener(OnClickStop);}//开始下载按钮监听事件public void OnClickStartDownload(){//开启协程 *注意真机上要用Application.persistentDataPath路径*StartCoroutine(DownloadFile(Url, Application.streamingAssetsPath + "/MP4/test.mp4", CallBack));}/// <summary>/// 协程:下载文件/// </summary>/// <param name="url">请求的Web地址</param>/// <param name="filePath">文件保存路径</param>/// <param name="callBack">下载完成的回调函数</param>/// <returns></returns>IEnumerator DownloadFile(string url, string filePath, Action callBack){UnityWebRequest huwr = UnityWebRequest.Head(url); //使用Head方法可以获取到文件的全部长度yield return huwr.SendWebRequest();//发送信息请求//判断请求或系统是否出错if (huwr.isNetworkError || huwr.isHttpError) {Debug.Log(huwr.error); //出现错误 输出错误信息}else{long totalLength = long.Parse(huwr.GetResponseHeader("Content-Length")); //首先拿到文件的全部长度string dirPath = Path.GetDirectoryName(filePath);//获取文件的上一级目录if (!Directory.Exists(dirPath)) //判断路径是否存在{Directory.CreateDirectory(dirPath);//不存在创建}/*作用:创建一个文件流,指定路径为filePath,模式为打开或创建,访问为写入* 使用using(){}方法原因: 当同一个cs引用了不同的命名空间,但这些命名控件都包括了一个相同名字的类型的时候,可以使用using关键字来创建别名,这样会使代码更简洁。注意:并不是说两个名字重复,给其中一个用了别名,另外一个就不需要用别名了,如果两个都要使用,则两个都需要用using来定义别名的* using(类){} 括号中的类必须是继承了IDisposable接口才能使用否则报错* 这里没有出现不同命名空间出现相同名字的类属性可以不用using(){}*/using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write)){long nowFileLength = fs.Length; //当前文件长度,断点前已经下载的文件长度。Debug.Log(fs.Length);//判断当前文件是否小于要下载文件的长度,即文件是否下载完成if (nowFileLength < totalLength){Debug.Log("还没下载完成");/*使用Seek方法 可以随机读写文件* Seek() ----------有两个参数 第一参数规定文件指针以字节为单位移动的距离。第二个参数规定开始计算的位置* 第二个参数SeekOrigin 有三个值:Begin Current End* fs.Seek(8,SeekOrigin.Begin);表示 将文件指针从开头位置移动到文件的第8个字节* fs.Seek(8,SeekOrigin.Current);表示 将文件指针从当前位置移动到文件的第8个字节* fs.Seek(8,SeekOrigin.End);表示 将文件指针从最后位置移动到文件的第8个字节*/fs.Seek(nowFileLength, SeekOrigin.Begin); //从开头位置,移动到当前已下载的子节位置UnityWebRequest uwr = UnityWebRequest.Get(url); //创建UnityWebRequest对象,将Url传入uwr.SetRequestHeader("Range", "bytes=" + nowFileLength + "-" + totalLength);//修改请求头从n-m之间uwr.SendWebRequest(); //开始请求if (uwr.isNetworkError || uwr.isHttpError) //如果出错{Debug.Log(uwr.error); //输出 错误信息}else{long index = 0; //从该索引处继续下载while (nowFileLength < totalLength) //只要下载没有完成,一直执行此循环{if (_isStop) break;//如果停止跳出循环yield return null;byte[] data = uwr.downloadHandler.data;if (data != null){long length = data.Length - index;fs.Write(data, (int)index, (int)length); //写入文件index += length;nowFileLength += length;ProgressBar.value = (float)nowFileLength / totalLength;SliderValue.text = Math.Floor((float)nowFileLength / totalLength * 100) + "%";if (nowFileLength >= totalLength) //如果下载完成了{ProgressBar.value = 1; //改变Slider的值SliderValue.text = 100 + "%";/*这句话的作用是:如果callBack方法不为空则执行Invoke* 注意:* 1.这里的Invoke可不是Unity的Invoke延迟调用的用法,参考文章:https://blog.csdn.net/liujiejieliu1234/article/details/45312141 从文章中我们可以看到,C#中的Invoke是为了防止winform中子主线程刚开始创建对象时,子线程与主线程并发修改主线程尚未创建的对象属性。* 因为unity这里只有主线程没有用到子线程可以直接写callBack();*/callBack?.Invoke();break;}}}}}}}}/// <summary>/// 下载完成后的回调函数/// </summary>void CallBack(){Debug.Log("下载完成");}/// <summary>/// 暂停下载/// </summary>public void OnClickStop(){if (_isStop){pauseBtn.GetComponentInChildren<Text>().text = "暂停下载";Debug.Log("继续下载");_isStop = !_isStop;OnClickStartDownload();}else{pauseBtn.GetComponentInChildren<Text>().text = "继续下载";Debug.Log("暂停下载");_isStop = !_isStop;}}
}
相关文章:
[游戏开发][Unity]UnityWebRequest使用大全
首先记录个小问题 使用new UnityWebRequest的方式,最终的downloadHandler是个null 使用UnityWebRequest.Get的方式,最终的downloadHandler会是DownloadHandlerBuffer 从网站或本地下载内容,包括文本或二进制数据 IEnumerator downloadfile(st…...
如何使用Fiddler对手机进行弱网测试?(干货教程)
1.首先,fiddler连接手机 1)Tools->Options->Connections->设置端口8888,勾选Allow remote computers to connect 2)配置手机 注:手机和电脑需要在同一局域网下 手机进入网络详情,将代理改为手动 设置主机名、端口 主机…...
专业科普:什么是单片机?
一、什么是单片机 单片机诞生于20世纪70年代末,它是指一个集成在一块芯片上的完整计算机系统。单片机具有一个完整计算机所需要的大部分部件:CPU、内存、内部和外部总线系统,目前大部分还会具有外存。同时集成诸如通讯接口、定时器ÿ…...
深度学习-第T11周——优化器对比实验
深度学习-第T11周——优化器对比实验 深度学习-第T11周——优化器对比实验一、前言二、我的环境三、前期工作1、导入数据集2、查看图片数目3、查看数据 四、数据预处理1、 加载数据1、设置图片格式2、划分训练集3、划分验证集4、查看标签 2、数据可视化3、检查数据4、配置数据集…...
基于Dlib的疲劳检测系统
需要源码的朋友可以私信我 基于Dlib的疲劳检测系统 1、设计背景及要求2、系统分析3、系统设计3.1功能结构图3.2基于EAR、MAR和HPE算法的疲劳检测3.2.1基于EAR算法的眨眼检测3.2.2基于MAR算法的哈欠检测3.3.3基于HPE算法的点头检测 4、系统实现与调试4.1初步实现4.2具体实现过程…...
three.js通过CubeTexture加载环境贴图,和RGBELoader加载器加载hdr环境贴图
一、使用CubeTexture进行环境贴图 1.CubeTexture使用介绍 Three.js中可以通过使用CubeTexture进行环境贴图,CubeTexture需要将6张图片(正面、反面、上下左右)包装成一个立方体纹理。下面是一个简单的例子: 首先需要加载六张贴图…...
pycharm中Terminal输入sqlite3,出现无法将sqlite项识别为cmdlet**的解决方法
前提:本机上已安装sqlite3,安装详见:pycharm社区版中安装配置sqlite3_Sunshine_0426的博客-CSDN博客 问题: cmd命令行中或pycharm中Terminal行输入sqlite3 db.sqlite3命令后,出现“无法将“sqlite3”项识别为 cmdlet…...
VSCode 安装配置教程详解包含c++环境配置方法
vscode安装教程及c环境配置详解 vscode下载安装下载C扩展插件VScode C环境配置配置环境变量检查 MinGW 安装配置编译器:配置构建任务检查是否安装了编译器配置完毕 vscode下载安装 地址:官网下载地址 直接打开下载好的.exe文件进行安装即可࿰…...
Baumer工业相机堡盟工业相机如何通过BGAPISDK将图像放大缩小显示(C#)
Baumer工业相机堡盟工业相机如何通过BGAPISDK将图像放大缩小显示(C#) Baumer工业相机Baumer工业相机BGAPISDK和图像放大缩小的技术背景Baumer工业相机通过BGAPISDK将相机图像图像放大缩小功能1.引用合适的类文件2.通过BGAPISDK将相机图像图像放大缩小功能…...
8.1 PowerBI系列之DAX函数专题-进阶-解决列排序对计算的影响
需求 下列矩阵中,在月份列不按照原始数据的month_no排列时,能正确计算销售额占比,但是当月份按照month_no排序时就会出错,需要解决这个问题。 实现 month % divide([amount],calculate([amount],all(date[month desc]))) //排…...
Java的第十二篇文章——集合
目录 第十二章 集合 学习目标 1. 集合框架的由来 2. 集合框架的继承体系 3. Collection接口 3.1 Collection接口的常用方法 4. Iterator接口 4.1 Iterator接口的抽象方法 4.2 获取迭代器接口实现类 4.3 迭代器的实现原理 4.4 并发修改异常 4.5 集合存储自定义对象并…...
docker 镜像制作 与 CI/CD
目录 镜像到底是什么? 使用docker创建镜像 步骤: 1、编辑Dockerfile(Dockerfile是docker制作镜像的配方文件) 2、编辑requirements.txt文件 3、编辑app.py文件,我们的程序文件 4、生成镜像文件 5、查看生成的镜…...
Spring Boot 异常报告器解析
基于Spring Boot 3.1.0 系列文章 Spring Boot 源码阅读初始化环境搭建Spring Boot 框架整体启动流程详解Spring Boot 系统初始化器详解Spring Boot 监听器详解Spring Boot banner详解Spring Boot 属性配置解析Spring Boot 属性加载原理解析Spring Boot 异常报告器解析 创建自定…...
瑞亚太空活动公司RSA与英国国防与安全加速器达成量子项目合作
(图片来源:网络) 瑞亚太空活动公司(RSA)与英国国防与安全加速器(DASA)签署了合作协议,主要开发名为“无限交换”的可操纵量子真空的技术项目。这是RSA在英国签订的第一份合同&…...
Shapley值法介绍及实例计算
Shapley值法介绍及实例计算 为解决多个局中人在合作过程中因利益分配而产生矛盾的问题,属于合作博弈领域。应用 Shapley 值的一大优势是按照成员对联盟的边际贡献率将利益进行分配,即成员 i 所分得的利益等于该成员为他所参与联盟创造的边际利益的平均值…...
不用手动改 package.json 的版本号
“为什么package.json 里的版本还是原来的,有没有更新?”,这个时候我意识到,我们完全没有必要在每次发布的时候还特意去关注这个仓库的版本号,只要在发布打tag的时候同步一下即可 node.js 部分,我们得有一个…...
gitlab Can‘t update,dev has no tracked branch
代码仓库迁移到gitlab后本地更改仓库地址后 拉取代码报错: Can’t update,dev has no tracked branch: 解决办法: 在当前项目的目录下运行命令: git branch -u git dev --set-upstream-toorigin/dev第一个dev是本地分支名字&…...
sql批量操作
SQl: 1,在某一字段后批量增加内容:UPDATE 表名 SET 字段 CONCAT(字段,要增加的内容) 例:UPDATE b8_niuniu_permission SET game_ids CONCAT(game_ids,,3) (或者后面可以加where条件) 2,批量修改某一字段…...
数据库监控与调优【九】—— 索引数据结构
索引数据结构-B-Tree索引、Hash索引、空间索引、全文索引 二叉树查找 对于相同深度的节点,左侧的节点总是比右侧的节点小。在搜索时,如果要搜索的值key大于根节点(图中6),就会在右侧子树里查找;key小于根…...
哈工大计算机网络传输层详解之:流水线机制与滑动窗口协议
哈工大计算机网络传输层详解之:流水线机制与滑动窗口协议 哈工大计算机网络课程传输层协议详解之:可靠数据传输的基本原理哈工大计算机网络课程传输层协议详解之:TCP协议哈工大计算机网络课程传输层协议详解之:拥塞控制原理剖析 …...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
