WWW类
WWW类是什么
//WWW是Unity提供的简单的访问网页的类
//我们可以通过该类上传和下载一些资源
//在使用http是,默认的请求类型是get,如果想要用post上传需要配合WWWFrom类使用
//它主要支持的协议:
//1.http://和https:// 超文本传输协议
//2.ftp://文件传输协议(但仅限于匿名下载)
//3.file://本地文件传输协议 可以使用该协议异步加载本地文件(PC,IOS和Android都支持)
//本节课主要使用WWW类来进行数据的下载或加载
//注意
//1.该类一般配合协同程序使用
//2.该类在较新的Unity版本中会提示过时了,但仍可使用,新版本将其功能整合进了UnityWebRequest类中
WWW中的常用方法和变量
//WWW www = new WWW("http://172.41.2.6/HTTP_Server/测试图片.png");
//2.GetAudioClip(),从下载数据返回一个音效切片AudioClip对象
//www.GetAudioClip();
//3.LoadImageIntoTexture:用下载数据中的图像替换现有的一个Texture2D对象
//Texture2D tex = new Texture2D(100, 100);
//www.LoadImageIntoTexture(tex);
//4.LoadFromCacheOrDownload:从缓存加载ab包对象,如果该包不在缓存则自动下载到缓存,以便以后直接从本地缓存中获取
//WWW.LoadFromCacheOrDownload("http://172.41.2.6/HTTP_Server/test.assetbundle", 1);
WWW加载Http,Ftp和本地资源
#endregion
#region 1.下载http服务器上的内容
StartCoroutine(DownLoadHttp());
#endregion
#region 2.下载ftp服务器上的内容(ftp服务器一定要支持匿名账户)
StartCoroutine(DownLoadFtp());
#endregion
#region 3.本地内容加载(一般移动平台加载内容都会使用这种格式)
StartCoroutine(DownLoadLocalFile());
#endregion
}
IEnumerator DownLoadHttp()
{
//1.创建www对象
WWW www = new WWW("https://img-blog.csdnimg.cn/0880c070ead14668b585e0036c29f7a4.jpg");
//2.等待加载结束
while (!www .isDone)
{
print(www.bytesDownloaded);
print(www.progress);
yield return null;
}
print(www.bytesDownloaded);
print(www.progress);
//3.使用加载结束后的资源
if (www.error ==null)
{
image.texture = www.texture;
}
}
IEnumerator DownLoadFtp()
{
//1.创建www对象
WWW www = new WWW("ftp://DamnF@127.0.0.1/文本格式.jpg");
//2.等待加载结束
while (!www.isDone)
{
print(www.bytesDownloaded);
print(www.progress);
yield return null;
}
print(www.bytesDownloaded);
print(www.progress);
//3.使用加载结束后的资源
if (www.error == null)
{
image.texture = www.texture;
}
}
IEnumerator DownLoadLocalFile()
{
//1.创建www对象
WWW www = new WWW("file://"+Application .streamingAssetsPath +"/test.png");
//2.等待加载结束
while (!www.isDone)
{
print(www.bytesDownloaded);
print(www.progress);
yield return null;
}
print(www.bytesDownloaded);
print(www.progress);
//3.使用加载结束后的资源
if (www.error == null)
{
image.texture = www.texture;
}
}
WWWForm类
WWWForm类是什么
在 Unity 中,WWWForm
类主要用于与 WWW
类配合,构建并发送包含表单数据的 HTTP POST 请求,例如向服务器提交用户输入、上传文件等。尽管 WWW
类在 Unity 2017.1 及后续版本中已被标记为过时(推荐使用 UnityWebRequest
),但了解 WWWForm
的用法仍有助于理解旧项目或历史代码。
WWWForm类中的常用方法和变量
1. 构造函数
WWWForm form = new WWWForm(); // 创建空表单
2. 常用方法
方法名 | 作用 |
---|---|
AddField(string key, string value) | 添加文本类型的表单字段(键值对),用于提交普通字符串数据。 |
AddBinaryData(string key, byte[] data, string fileName, string mimeType) | 添加二进制数据(如文件),fileName 为文件名(影响服务器解析),mimeType 为文件的 MIME 类型(如 image/jpeg )。 |
headers | 获取或设置请求头(Dictionary<string, string> ),可添加自定义请求头(如 User-Agent )。 |
WWW结合WWWForm对象异步上传数据
#region 知识点三 WWW结合WWWForm对象来异步上传数据
StartCoroutine(UpLoadData());
#endregion
}
IEnumerator UpLoadData()
{
WWWForm data = new WWWForm();
//上传的数据 对应的后端程序 必须要有处理的规则 才能生效
data.AddField("Name", "DamnF", Encoding.UTF8);
data.AddField("Age", 99);
data.AddBinaryData("file", File.ReadAllBytes(Application.streamingAssetsPath + "/test.png"));
WWW www = new WWW("http://172.41.2.6/HTTP_Server/", data);
yield return www;
if(www.error ==null)
{
print("上传成功");
//www.bytes
}
else
{
print("上传失败"+www.error);
}
}
将WWW类和WWWForm类用单例模式封装到WWWMgr模块中
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class WWWMgr : MonoBehaviour
{
private static WWWMgr instance = new WWWMgr();
public static WWWMgr Instance => instance;
private string HTTP_SERVER_PATH = "http://172.41.2.6/HTTP_Server/";
private void Awake()
{
instance = this;
DontDestroyOnLoad(this.gameObject);
}
public void LoadRes<T>(string path, UnityAction<T> action) where T : class
{
StartCoroutine(LoadResAsync<T>(path, action));
}
private IEnumerator LoadResAsync<T>(string path, UnityAction<T> action) where T : class
{
WWW www = new WWW(path);
yield return www;
if (www.error == null)
{
//根据T泛型的类型 决定使用哪种类型的资源 传递给外部
if (typeof(T) == typeof(AssetBundle))
{
action?.Invoke(www.assetBundle as T);
}
else if (typeof(T) == typeof(Texture))
{
action?.Invoke(www.texture as T);
}
else if (typeof(T) == typeof(AudioClip))
{
action?.Invoke(www.GetAudioClip() as T);
}
else if (typeof(T) == typeof(string))
{
action?.Invoke(www.text as T);
}
else if (typeof(T) == typeof(byte[]))
{
action?.Invoke(www.bytes as T);
}
}
else
{
Debug.LogError("加载资源出错了" + www.error);
}
}
public void SendMsg<T>(BaseMsg msg,UnityAction<T>action)where T:BaseMsg
{
StartCoroutine(SendMsgAsync<T>(msg, action));
}
private IEnumerator SendMsgAsync<T>(BaseMsg msg,UnityAction <T>action)where T:BaseMsg
{
//消息发送
WWWForm data = new WWWForm();
//准备要发送的消息数据
data.AddBinaryData("Msg", msg.Writing());
WWW www = new WWW(HTTP_SERVER_PATH, data);
//我们也可以直接传递 2进制字节数组 只要和后端制定好规则 怎么传都是可以的
//WWW www = new WWW(HTTP_SERVER_PATH, msg.Writing());
//异步等待 发送结束 才会继续执行后面的代码
yield return www;
//发送完毕后 收到响应
//认为后端发回来的内容也是一个继承自BaseMsg类的字节数组对象
if(www.error ==null)
{
//先解析 ID和消息长度
int index = 0;
int msgID = BitConverter.ToInt32(www.bytes, index);
index += 4;
int msgLength = BitConverter.ToInt32(www.bytes, index);
index += 4;
//反序列化 BaseMsg
BaseMsg baseMsg = null;
switch (msgID)
{
case 1001:
baseMsg = new PlayerMsg();
baseMsg.Reading(www.bytes, index);
break;
}
if (baseMsg != null)
action?.Invoke(baseMsg as T);
else
Debug.LogError("发消息出现问题" + www.error);
}
}
}
测试
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
public class Lesson29_Test : MonoBehaviour
{
public RawImage image;
// Start is called before the first frame update
void Start()
{
//只要保证一运行时 进行该判断 进行动态创建
if(WWWMgr.Instance ==null)
{
GameObject obj = new GameObject("WW");
obj.AddComponent<WWWMgr>();
}
//在任何地方使用WWWMgr都没问题
WWWMgr.Instance.LoadRes<Texture>("https://img-blog.csdnimg.cn/0880c070ead14668b585e0036c29f7a4.jpg", (obj) =>
{
//使用加载结束的资源
image.texture = obj;
});
WWWMgr.Instance.LoadRes<byte[]>("https://img-blog.csdnimg.cn/0880c070ead14668b585e0036c29f7a4.jpg", (obj) =>
{
//把得到的字节数组存储到本地
print(Application.persistentDataPath);
File.WriteAllBytes(Application.persistentDataPath + "/www图片.png", obj);
});
}
// Update is called once per frame
void Update()
{
}
}