Unity3D网络通讯(二)--UnityWebRequest及JsonUtility请求Http Restful

2020-09-10 16:30:59 浏览数 (1)

前言

上一篇《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();
            }
        }
    }

}

0 人点赞