本文节选自洪流学堂公众号技术专栏《大话Unity2019》,未经允许不可转载。

洪流学堂公众号回复专栏,查看更多专栏文章。


洪流学堂,让你快人几步。你好,我是郑洪智。

大智:“昨天我们初步了解了UnityWebRequest是做什么用的以及如何使用,今天我们来仔细看一下昨天代码中的几个部分。”

using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;public class GetFileByWebRequest : MonoBehaviour
{IEnumerator Start(){var uri = new System.Uri(Path.Combine(Application.streamingAssetsPath, "data.json"));var request = UnityWebRequest.Get(uri.AbsoluteUri);yield return request.SendWebRequest();if (request.isNetworkError || request.isNetworkError){Debug.Log(request.error);}else{Debug.Log(request.downloadHandler.text);}}
}

我们从上到下来分析这几行代码。

Uri类

首先我们用到了System.Uri这个类,这个类可以帮助我们更好的构造uri,特别是在请求本地的file文件时。在请求本地文件时,不同的平台使用的Uri略有不同。

如果不使用Uri类时,各个平台所需要的Uri的字符串示例如下:

  • Windows平台 file:///D:/DATA/StreamingAssets/data.json
  • WebGl平台 http://localhost/StreamingAssets/data.json
  • Android平台 jar:file:///data/app/xxx!/assets/data.json

使用Uri类之后,就可以自动帮我们拼接好这些Uri的字符串,一定要记得:
var uri = new System.Uri(Path.Combine(Application.streamingAssetsPath, "data.json"));

UnityWebRequest

有了Uri以后呢,我们就可以使用UnityWebRequest来进行请求了。

虽然这个叫做WebRequest,但是要记住还可以请求本地的文件哦。

UnityWebRequest详解

UnityWebRequest封装了网络请求,支持http、https、file、和匿名ftp协议的请求以及处理。

这个类替代了WWW类,相对WWW类使用起来更复杂一些,但是功能和性能也更强大了。

UnityWebRequest类将一个请求分解为了3部分:

  • 提供请求时的输出,传输给服务器
  • 从服务器接收数据
  • 控制HTTP的请求流程

UnityWebRequest 由三个元素组成。

  • UploadHandler 处理数据 将数据发送到服务器 的对象
  • DownloadHandler 从服务器接收数据 的对象
  • UnityWebRequest 负责 HTTP 通信流量控制来管理上面两个对象的对象。

来说明这些对象之间的关系,如下所示。

对于一次请求,通常的代码流程是:

  • 创建一个UnityWebRequest对象
  • 配置UnityWebRequest对象
    • 设置请求的header
    • 设置HTTP的方法(比如GET,POST,HEAD等,自定义HTTP方法除了Android平台,其他平台也都支持)
  • (可选)创建一个UploadHandler附加到这个UnityWebRequest对象上面
    • 提供上传的数据
    • 提供上传的HTTP表单
  • (可选)创建一个DownloadHandler附加到这个UnityWebRequest对象上面,如果需要获取返回数据一定要创建
  • 发送Send这个请求
    • 如果是在一个协程里,可以使用yield来返回SendWebRequest(),用于等待请求完成。需要注意的是:如果你之前习惯使用www,一定要注意这个UnityWebRequest在调用SendWebRequest()方法之后才会真正执行请求。
  • (可选)从DownloadHandler里面读取接收到的数据
  • (可选)从UnityWebRequest对象读取error信息、HTTP状态码、相应头等信息。

UnityWebRequest捷径

小新:“这个UnityWebRequest有点太复杂了吧?没有简单的方法么?”
大智:“这个当然是有的,下面我们来看看之前代码中使用到的Get方法。”

使用Get获取数据

获取简单的文本或者二进制数据,可以使用UnityWebRequest.Get方法。这个方法的参数非常简单,只需要传入Uri即可,和之前的WWW类很类似,可以替代WWW类使用:

// 被抛弃的WWW
WWW myWww = new WWW("http://www.myserver.com/foo.txt");
// 使用起来很类似
UnityWebRequest myWr = UnityWebRequest.Get("http://www.myserver.com/foo.txt");

一般使用的方法如下:

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;public class MyBehaviour : MonoBehaviour {void Start() {StartCoroutine(GetText());}IEnumerator GetText() {UnityWebRequest www = UnityWebRequest.Get("http://www.my-server.com");yield return www.SendWebRequest();if(www.isNetworkError || www.isHttpError) {Debug.Log(www.error);}else {// Show results as textDebug.Log(www.downloadHandler.text);// Or retrieve results as binary databyte[] results = www.downloadHandler.data;}}
}

结合协程使用(Coroutine)

之前在69节学习过使用协程,但是这里你会发现使用的方法不太一样了,这里使用的是yield return request.SendWebRequest()

为什么可以这么写呢?

我可以先告诉你作用是什么:那就是可以等待请求完成后才继续执行。

之前我们学协程的时候使用过

yield return new WaitForSeconds(3);

也就是3秒后才继续执行。

在这里呢,UnityWebRequest的请求同样可以通过协程的yield return来等待请求执行完毕,但是不会阻塞主线程。

有BOM的问题

假设我们获取到数据后要使用json解析,如果你的文件中有bom,就会出现问题。

using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;[System.Serializable]
public class Npc
{public int Id;public string 名称;public float 血量;public float 攻击力;public float 防御力;
}public class Npcs
{public Npc[] npcs;
}public class GetFileByWebRequest : MonoBehaviour
{IEnumerator Start(){var uri = new System.Uri(Path.Combine(Application.streamingAssetsPath, "data.json"));var request = UnityWebRequest.Get(uri);Debug.Log(uri);var www = request.SendWebRequest();yield return www;if (request.isNetworkError || request.isNetworkError){Debug.Log(request.error);}else{var jsonStr = request.downloadHandler.text;Debug.Log(jsonStr);var npcs = JsonUtility.FromJson<Npcs>(jsonStr);Debug.Log(npcs.npcs.Length);}}
}

你可以尝试下如下的json文件:

{"npcs": [{"Id": 1,"名称": "小猴子","血量": 10,"攻击力": 1,"防御力": 1},{"Id": 2,"名称": "大猴子","血量": 100,"攻击力": 2,"防御力": 2},{"Id": 3,"名称": "孙猴子","血量": 999999,"攻击力": 9999,"防御力": 9999}]
}

如果使用utf8+bom的编码方式,就会报错:

所以一定一定要使用无BOM的UTF8编码的文件。

总结

  • UnityWebRequest.Get方法是最简单的,可以代替www使用
  • UnityWebRequest对象需要调用SendWebRequest之后才会执行请求
  • 一定一定要使用无BOM的UTF8编码的文件

今日思考题

大智:“先试着使用上面的代码,获取之前的文件数据试一试!”
小新:“好嘞!”
大智:“收获别忘了分享出来!也别忘了分享给你学Unity的朋友,也许能够帮到他。”


洪流学堂公众号回复专栏,查看更多专栏文章。

《大话Unity2019》,大智带小新学Unity2019的有趣经历,让你学Unity更简单。

[专栏精选]UnityWebRequest详解相关推荐

  1. unity3d 切换网络_Unity3d新网络请求方式UnityWebRequest详解

    Unity将要逐步放弃www网络请求api,新的api请求方式来临:UnityWebRequestThe,也正是本篇文章要给大家介绍的重点,那就是UnityWebRequestThe的使用详解. 旧的 ...

  2. 网络工程师精选习题详解(一)

    请点击↑关注.收藏,本博客免费为你获取精彩知识分享!有惊喜哟!! 1.在IPv4地址192.168.2.0/24中,表示主机的二进制位数是(  )位. A.8    B.16    C.24     ...

  3. 网络工程师精选习题详解(二)

    请点击↑关注.收藏,本博客免费为你获取精彩知识分享!有惊喜哟!! 201.通常使用()为IP数据报进行加密. A.IPSec     B.PP2P    C.HTTPS     D.TLS 答案:A ...

  4. 【专栏独家】详解微信朋友圈广告:会不会成为腾讯的新印钞机?

    微信这一国内最火热的社交工具,在1月21日推出了类似Facebook.Twitter 类似的信息流广告.号称依据用户细分信息与大数据,为广告主提供精准的广告投放.目前收费标准也是比较高的,基本500万 ...

  5. 【docker专栏5】详解docker镜像管理命令

  6. TCP/IP协议专栏——MAC地址详解——网络入门和工程维护必看

    以太帧格式 前导同步符:共8字节,由7个字节的前同步信号和一个分界符开始字节构成. DA/SA:共6个字节,前3个字节代表供应商代码,后3个字节代表厂商序列号. TPID:标记协议标识符,2个字节,值 ...

  7. 多线程怎么保证数据安全_「软帝学院」Java挑战者专栏:多线程详解2

    软帝学院笔记Day21 多线程(单例设计模式)(掌握) 单例设计模式:保证类在内存中只有一个对象. 如何保证类在内存中只有一个对象呢? (1)控制类的创建,不让其他类来创建本类的对象.private ...

  8. Shell语法详解专栏目录

    Shell语法详解专栏 1. [Shell详解-1]:概论.注释 2. [Shell详解-2]:变量.默认变量.数组 3. [Shell详解-3]:expr命令.read命令 4. [Shell详解- ...

  9. 【专栏精选】Unity中的HTTP网络通信

    本文节选自洪流学堂公众号技术专栏<大话Unity2019>,未经允许不可转载. 洪流学堂公众号回复专栏,查看更多专栏文章. 洪流学堂,让你快人几步.你好,我是郑洪智. 大智:"小 ...

最新文章

  1. CUDA C编程接口技术分析
  2. ios中的自动释放池
  3. 北京大学纳家勇治研究组在《美国国家科学院院刊》发文阐明时序记忆的神经机制
  4. 常用的HTML标签和属性解释
  5. 运用神经网络方法找寻集成学习中的最优权重
  6. 【C语言学习】国嵌21__指针基础
  7. 38Exchange 2010升级到Exchange 2013-安装第二台CAS2013
  8. .Net的 Web项目的打包过程
  9. MongoDB使用过程中的报错处理(持续更新)
  10. 【贪心】hdu5969 最大的位或
  11. 如何利用缓存提高asp.net网站访问速度
  12. java 数据库编程(一)JDBC连接Sql Server数据库
  13. 建立强有力的人脉关系
  14. 海康sip服务器是什么意思_海康摄像头入门
  15. git archive使用笔记
  16. 搜索引擎的高级搜索语法指令
  17. 原生js与css3实现简单翻页动画
  18. 匿名发脉脉的拼多多员工,是如何被发现的?背后真相令人发指...
  19. cdr软件百度百科_coreldraw是干嘛的?能做什么?cdr软件在哪儿下载?
  20. Matlab——m_map指南(3)——实例

热门文章

  1. Python打印到文件
  2. ADO.NET Entity Framework学习笔记(4)ObjectQuery对象
  3. 5-条件(如果是这样该怎么办?)
  4. 演示<jsp:forward>动作元素
  5. java中key的作用_key word ‘final’ 在java 中作用
  6. 5去掉button按钮的点击样式_各种好看的小按钮合集,纯css编写,最近在学习时遇到的,记录成为笔记...
  7. java里面怎么添加表约束_alter table添加表约束
  8. 以太坊智能合约Java_以太坊:调用已部署的智能合约
  9. MySQL函数少传参数_Mysql中的少用函数
  10. as cast float server sql_SQL语言在数据工程(Data Engineering)中的运用(一)