前言
上一篇《Unity3D网络通讯(一)--Asp.Net Core WebApi创建发布注意事项》已经把Asp.Net Core的WebApi搭建出来了,今天这篇就来看一下Unity3D使用UnityWebRequest和JsonUnity实现Api接口的通讯。
Unity3D Restful通讯
微卡智享
01
创建项目
新建了一个TransDemo的项目,这次用的是Unity最新的版本2020.1.2f1c1。
因为只是做网络通讯,所以创建的是一个2D的项目,然后左边放了一个Text显示通讯的数据,右边最上面是InputField的url输入框,下面的InputField是参数的输入框,然后我们再新建了四个按钮,分别是Get、GetParm、Post、Json。
02
创建脚本
WeatherForecast类
首先把上一篇NetCore的天气类(WeatherForecast)直接拷贝过来后,我们再改造一下
代码语言:javascript复制using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class WeatherData
{
public WeatherForecast[] array;
}
[System.Serializable]
public class WeatherForecast
{
public DateTime Date;
public int TemperatureC;
public int TemperatureF;
public string Summary;
}
上面的代码里,首先我们把类上面的属性标签上写上[System.Serializable],代表可以用JsonUtility使用,还有就是定义的属性,如Summary没有赋默认值,这个忘了在哪个文章中看到了,所以我这也就都去掉了。
然后又定义了一个新的类WeatherData,里面定义了WeatherForecast[]的数组,创建这个的原因这里要说一下,Unity3D的JsonUtility组件本身不像NewtonsoftJson那么强大,返回的List<T>的数组Json直接用JsonUtility是反序列化不了的,所以我们这里又增加了一个类,定义了一个WeatherForecat[]的属性。
UIScripts
新建了UIScripts脚本,然后我们把一个Text,两个InputField,四个Button分别定义好。上图中[Header]和[Space]的标签就是在组件栏里显示的好看一点。
将UIScripts脚本挂到Canvas上,然后把对应的组件用鼠标拖拽到定义的组件上,上面红线可以看到,在脚本中定义的Header和Space就是把这个布局变的更规整一些。这样基础工作基本都做完了,接下来就看看具体的实现。
03
JsonUtility的使用
JsonUtility的使用也非常简单,主要的就是两个方法ToJson和FromJson。
脚本中定义一个JsonConvert()的协程方法,实例化一个新的WeatherForecast并赋值后,首先通过JsonUtility序列化,再过3秒后返序列化回来。
然后在btnjson按钮中增加点击监听事件,当点击后直接调用刚才创建JsonConvert事件。
使用效果
04
Get的使用
代码语言:javascript复制 IEnumerator GetRequest(string url)
{
using (UnityWebRequest request = UnityWebRequest.Get(url))
{
Debug.Log("trans");
yield return request.SendWebRequest();
if (request.isNetworkError || request.isHttpError)
{
txtshow.text = request.error;
}
else
{
string resjson = request.downloadHandler.text;
resjson = "{"array":" resjson "}";
txtshow.text = resjson;
WeatherData lists = JsonUtility.FromJson<WeatherData>(resjson);
StringBuilder sb = new StringBuilder();
foreach (WeatherForecast item in lists.array)
{
sb.Append("Date:" item.Date " Summary:" item.Summary " TemperatureF:"
item.TemperatureF "TemperatureC:" item.TemperatureC "rn");
}
yield return new WaitForSeconds(3f);
txtshow.text = sb.ToString();
}
}
}
上面是Get的主要调用代码,也是用的协程处理的。
主要想强调的就是上面红框这里,我们当请求成功返回的文本中的格式是一个List<T>数组的Json,前面说过了JsonUtility是直接解析不了的,所以我们定义了一个WeatherData的类,里面的加了一个WeatherForecast的数组定义为array,上面的resjson的字符串我们也改造成这样的方式,再通过FromJson<WeatherData>来反序列化的。
上面的图就是Get方法,和Get带参数的方法调用。
使用效果
05
POST的使用
代码语言:javascript复制 IEnumerator PostRequest(string url, string data)
{
using (UnityWebRequest request = new UnityWebRequest(url,"POST"))
{
request.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(data));
request.SetRequestHeader("content-type", "application/json;charset=utf-8");
request.downloadHandler = new DownloadHandlerBuffer();
yield return request.SendWebRequest();
if (request.isNetworkError || request.isHttpError)
{
txtshow.text = request.error;
}
else
{
string resjson = request.downloadHandler.text;
resjson = "{"array":" resjson "}";
txtshow.text = resjson;
WeatherData lists = JsonUtility.FromJson<WeatherData>(resjson);
StringBuilder sb = new StringBuilder();
foreach (WeatherForecast item in lists.array)
{
sb.Append("Date:" item.Date " Summary:" item.Summary " TemperatureF:"
item.TemperatureF "TemperatureC:" item.TemperatureC "rn");
}
yield return new WaitForSeconds(3f);
txtshow.text = sb.ToString();
}
}
}
上面是POST使用的核心代码,这块测试倒是花了不少的时间,开始想用的是WWWForm的方式,然后不停地调试总是请求不对,最后才改为使用UploadHandlerRaw的方式进行Post的通讯,直接成功。
还是在Start()方法中加入btnpost的点击方法。
使用效果
UIScripts完整代码
代码语言:javascript复制using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class UIScripts : MonoBehaviour
{
[Header("按钮")]
public Button btnget;
public Button btngetparm;
public Button btnjson;
public Button btnpost;
[Space]
[Header("显示")]
public Text txtshow;
[Space]
[Header("输入框")]
public InputField edturl;
public InputField edtparm;
// Start is called before the first frame update
void Start()
{
btnget.onClick.AddListener(()=>
{
Debug.Log(edturl.text);
string url = edturl.text;
StartCoroutine(GetRequest(url));
});
btngetparm.onClick.AddListener(()=>
{
string url = edturl.text;
string param = edtparm.text;
string allurl = url "/Info?Summary=" param;
StartCoroutine(GetRequest(allurl));
});
btnjson.onClick.AddListener(() => StartCoroutine(JsonConvert()));
btnpost.onClick.AddListener(() =>
{
WeatherForecast item = new WeatherForecast();
item.Summary = "Alvin";
item.Date = DateTime.Now;
item.TemperatureC = 10;
item.TemperatureF = 20;
string json = JsonUtility.ToJson(item);
string url = edturl.text "/Reg";
Debug.Log(url);
StartCoroutine(PostRequest(url, json));
});
}
IEnumerator JsonConvert()
{
WeatherForecast item = new WeatherForecast();
item.Summary = "Alvin";
item.Date = DateTime.Now;
item.TemperatureC = 10;
item.TemperatureF = 20;
string json = JsonUtility.ToJson(item);
txtshow.text = json;
yield return new WaitForSeconds(3f);
WeatherForecast newitem = JsonUtility.FromJson<WeatherForecast>(json);
string showtext = "Summary:" newitem.Summary " Date:" newitem.Date
" C:" newitem.TemperatureC " F:" newitem.TemperatureF;
txtshow.text = showtext;
}
IEnumerator GetRequest(string url)
{
using (UnityWebRequest request = UnityWebRequest.Get(url))
{
Debug.Log("trans");
yield return request.SendWebRequest();
if (request.isNetworkError || request.isHttpError)
{
txtshow.text = request.error;
}
else
{
string resjson = request.downloadHandler.text;
resjson = "{"array":" resjson "}";
txtshow.text = resjson;
WeatherData lists = JsonUtility.FromJson<WeatherData>(resjson);
StringBuilder sb = new StringBuilder();
foreach (WeatherForecast item in lists.array)
{
sb.Append("Date:" item.Date " Summary:" item.Summary " TemperatureF:"
item.TemperatureF "TemperatureC:" item.TemperatureC "rn");
}
yield return new WaitForSeconds(3f);
txtshow.text = sb.ToString();
}
}
}
IEnumerator PostRequest(string url, string data)
{
using (UnityWebRequest request = new UnityWebRequest(url,"POST"))
{
request.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(data));
request.SetRequestHeader("content-type", "application/json;charset=utf-8");
request.downloadHandler = new DownloadHandlerBuffer();
yield return request.SendWebRequest();
if (request.isNetworkError || request.isHttpError)
{
txtshow.text = request.error;
}
else
{
string resjson = request.downloadHandler.text;
resjson = "{"array":" resjson "}";
txtshow.text = resjson;
WeatherData lists = JsonUtility.FromJson<WeatherData>(resjson);
StringBuilder sb = new StringBuilder();
foreach (WeatherForecast item in lists.array)
{
sb.Append("Date:" item.Date " Summary:" item.Summary " TemperatureF:"
item.TemperatureF "TemperatureC:" item.TemperatureC "rn");
}
yield return new WaitForSeconds(3f);
txtshow.text = sb.ToString();
}
}
}
}
完