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

学更好的别人,

做更好的自己。

——《微卡智享》

本文长度为4250,预计阅读9分钟

前言

上一篇《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)直接拷贝过来后,我们再改造一下

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的使用

    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 + "\r\n");
                }
                yield return new WaitForSeconds(3f);
                txtshow.text = sb.ToString();
            }
        }
    }

上面是Get的主要调用代码,也是用的协程处理的。

主要想强调的就是上面红框这里,我们当请求成功返回的文本中的格式是一个List<T>数组的Json,前面说过了JsonUtility是直接解析不了的,所以我们定义了一个WeatherData的类,里面的加了一个WeatherForecast的数组定义为array,上面的resjson的字符串我们也改造成这样的方式,再通过FromJson<WeatherData>来反序列化的。

上面的图就是Get方法,和Get带参数的方法调用。

使用效果

05

POST的使用

    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 + "\r\n");
                }
                yield return new WaitForSeconds(3f);
                txtshow.text = sb.ToString();
            }
        }
    }

上面是POST使用的核心代码,这块测试倒是花了不少的时间,开始想用的是WWWForm的方式,然后不停地调试总是请求不对,最后才改为使用UploadHandlerRaw的方式进行Post的通讯,直接成功。

还是在Start()方法中加入btnpost的点击方法。

使用效果

UIScripts完整代码

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 + "\r\n");
                }
                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 + "\r\n");
                }
                yield return new WaitForSeconds(3f);
                txtshow.text = sb.ToString();
            }
        }
    }


}


扫描二维码

获取更多精彩

微卡智享

「 往期文章 」

Unity3D网络通讯(一)--Asp.Net Core WebApi创建发布注意事项

Unity3D使用Cinemachine配合Timeline实现运镜效果

学习|Unity3D使用协程实现减速停车效果

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vaccae

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值