前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Unity3D网络通讯(二)--UnityWebRequest及JsonUtility请求Http Restful

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

作者头像
Vaccae
发布2020-09-10 16:30:59
1.8K0
发布2020-09-10 16:30:59
举报
文章被收录于专栏:微卡智享微卡智享微卡智享

前言

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

}

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-09-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微卡智享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • WeatherForecast类
  • UIScripts
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档