Unity对接后台和加载图片

1、前言

        在unity中与后台对接,用await在web端暂时还不支持,所以,协程成为比较好的通用方式,以下适用除post访问外的所有对接

2、对接后台
2.1、安装插件

        首先我们需要用到Newtonsoft.dll,如果没有这个.dll的请跟着我一起装上,我们先创建一个脚本WebRequest.cs,然后双击脚本打开VS2022

在上面一排工具栏中,点击“工具”选项

 选择NuGet包管理器-管理解决方案的NuGet程序包,这时会弹出一个窗口

点击”浏览“

排在第一的就是我们需要用的插件,插件轻量好用

点击这个后,右侧小窗弹出窗口,像我这样勾选,然后安装

 安装完成后,我们回到脚本页面,右键打开所在的文件夹

我们返回工程目录,在Packages这个文件夹下有一个Newtonsoft文件夹,这个就是我们的插件

点进文件夹后有许多net版本,个人比较推荐netstandard2.0

 将netstandard2.0下的Newtonsoft.Json.dll拖入我们的工程里,下面开始我们的正文

2.2、代码

        回到正题,我们创建好WebRequest.cs后,结构是这样

using Newtonsoft.Json.Linq;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;

public class WebRequest : MonoBehaviour
{
    public string address;
    // Start is called before the first frame update
    void Start()
    {
        
    }
    /// <summary>
    /// 获取返回对象,如果不存在返回为null
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="path">路径</param>
    /// <param name="callback"></param>
    /// <returns></returns>
    public IEnumerator RequestURLWithArray(string path, System.Action<JObject> callback)
    {
        string paths = address + path;
        Debug.LogError("当前链接+++" + paths);
        //jishi();
        using (var request = UnityWebRequest.Get(paths))
        {
            // 发送HTTP请求并等待响应
            yield return request.SendWebRequest();

            // 检查是否有错误发生
            if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
            {
                Debug.LogError(request.error + "链接:" + paths);
                yield break;
            }
            if (!string.IsNullOrEmpty(request.downloadHandler.text))
            {

                callback(JObject.Parse(request.downloadHandler.text));
            }

        }
    }
}

由于是教学,我没有现有的后台接口,就用本地json代替,后台对接也只是换一下链接就能继续用

以上代码写完,我们在工程目录Assets下创建StreamingAssets文件夹,在StreamingAssets文件夹中创建“测试.json”,测试.json的数据结构如下:

{
"name":"11111",
"id":123456789,
"password":"123456789"
}

兄弟们一定一定要注意,json必须是utf8格式保存的,不然容易出现读取失败或者乱码等bug

一个非常简单的json,主要是测试用,打算搭一个登录界面来测试所以数据不多,如果兄弟们有大量数据的,也可以用这套东西,博主亲测,几十个接口+几百条数据,完美对接,延时基本上在几百ms,可以接受的

然后我们在WebRequest的Start里写获取,改写一下WebRequest

using Newtonsoft.Json.Linq;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;

public class WebRequest : MonoBehaviour
{
    public string address;
    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(RequestURLWithArray(Application.streamingAssetsPath + "/测试.json", (a) =>
        {
            Debug.Log($"name:{a["name"]} id: {a["id"]} password: {a["password"]}");
        }));
    }
    /// <summary>
    /// 获取返回对象,如果不存在返回为null
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="path">路径</param>
    /// <param name="callback"></param>
    /// <returns></returns>
    public IEnumerator RequestURLWithArray(string path, System.Action<JObject> callback)
    {
        string paths =  path;
        Debug.LogError("当前链接== " + paths);
        //jishi();
        using (var request = UnityWebRequest.Get(paths))
        {
            // 发送HTTP请求并等待响应
            yield return request.SendWebRequest();

            // 检查是否有错误发生
            if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
            {
                Debug.LogError(request.error + "链接:" + paths);
                yield break;
            }
            if (!string.IsNullOrEmpty(request.downloadHandler.text))
            {

                callback(JObject.Parse(request.downloadHandler.text));
            }

        }
    }
}

到这里就要注意,敲黑板划重点

我在这里写的输出,是转成JObject对象后以键对值的形式直接取得

Debug.Log($"name:{a["name"]} id: {a["id"]} password: {a["password"]}");

这里的键全部要和json中的变量对的上,才能获取到,当然,除了JObject外还有数组形式,那是另一种结构,我们等下再说

写完后保存,回到unity中,创建空对象 WebRequest将脚本挂在上面,开始运行

这时控制台就会输出我们想要的数据:

以上就是基础用法,不太建议这样用,如果是只有一个json或接口,可以像上述这样写,但是如果不止一个,而且数据多,我们就要换种形式读取

2.3、进阶用法

        接下来是进阶用法,我们先创建一个抽象类,这个类继承MonoBehaviour,并且要有一个封装好的JObject参数,一个虚方法init,用来处理收到的数据:

1、新建抽象类Dataabstract.cs

using Newtonsoft.Json.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class Dataabstract : MonoBehaviour
{
    public string path;
    protected JObject data;
    public JObject Data
    {
        get { return data; }
        set 
        { 
            if (value != null)
            {
                data = value;
                init();
            }
            else
            {
                Debug.LogError("获取失败,请检查链接地址");
            }
        }
    }
    protected virtual void init()
    {

    }
}

2、修改WebRequest.cs

using Newtonsoft.Json.Linq;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;

public class WebRequest : MonoBehaviour
{
    public string address = Application.streamingAssetsPath;
    public Dataabstract[] Dataabstracts;
    // Start is called before the first frame update
    void Start()
    {
        init();
    }
    void init()
    {
        for (int i = 0; i < Dataabstracts.Length; i++)
        {
            StartCoroutine(RequestURLWithArray(address+"/"+Dataabstracts[i].path, (a) =>
            {
                Dataabstracts[i].Data = a;
            }));
        }
    }
    /// <summary>
    /// 获取返回对象,如果不存在返回为null
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="path">路径</param>
    /// <param name="callback"></param>
    /// <returns></returns>
    public IEnumerator RequestURLWithArray(string path, System.Action<JObject> callback)
    {
        string paths =  path;
        Debug.LogError("当前链接== " + paths);
        //jishi();
        using (var request = UnityWebRequest.Get(paths))
        {
            // 发送HTTP请求并等待响应
            yield return request.SendWebRequest();

            // 检查是否有错误发生
            if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
            {
                Debug.LogError(request.error + "链接:" + paths);
                yield break;
            }
            if (!string.IsNullOrEmpty(request.downloadHandler.text))
            {
                callback(JObject.Parse(request.downloadHandler.text));
            }

        }
    }
}

3、新建测试类Test1,Test1继承抽象类Dataabstract重写init方法

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test1 : Dataabstract
{
    protected override void init()
    {
        Debug.Log($"name:{data["name"]} id: {data["id"]} password: {data["password"]}");
    }
}

回到unity中,新建空物体Test1,挂上Test1脚本,在面板上的path写上我们的json名字,请注意,一定要把          后缀带上,后缀带上,后缀带上

然后我们把Test1拖入WebRequest的Dataabstracts数组中

然后运行就可以看到我们拿到了数据

这样主要是应对大量不同的json或接口要读的, 这是这种格式的多样,下面我们来看另一种格式的json

2.4、另一种带数组的json读取

我们在StreamingAssets下再创建一种json,名字叫测试1.json,数据如下

{
  "data": [
    {
      "name": "123",
      "id": 1,
      "password": "爱上放大"
    },
    {
      "name": "456",
      "id": 2,
      "password": "各色地方"
    },
    {
      "name": "789",
      "id": 3,
      "password": "奥尔格和"
    }
  ]
}

新建Test2脚本

using Newtonsoft.Json.Linq;
using UnityEngine;
using UnityEngine.UI;

public class Test2 : Dataabstract
{
    public int index;
    [SerializeField] Text[] text;
    protected override void init()
    {
        JArray jArray = (JArray)data["data"];
        for (int i = 0; i < text.Length; i++)
        {
            text[i].text = jArray[index][text[i].name].ToString();
        }
    }
}

接下来我们回到unity,按我这样的结构创建好东西

把Test2挂到GameObject上,然后各GameObject的index分开,我这里的json有三组数据,所以我这里填的是0-2,这个作为索引去json中的data数组中找数据而已,将每个GameObject下的三个Text拖进Test2中的Text数组中

 然后把三个挂了Test2的GameObject拖进WebRequest中的数组中

直接运行就能看到结果 

可以看到,我们成功取到了数据,而且几乎没有延时,基本上是运行就有

2.5、总结

在面对如下简单的json时,我们用JObject去拿数据

{
  "name": "11111",
  "id": 123456789,
  "password": "123456789"
}

在面对如下稍微复杂的json时,我们用JArray取数据

{
  "data": [
    {
      "name": "123",
      "id": 1,
      "password": "爱上放大"
    },
    {
      "name": "456",
      "id": 2,
      "password": "各色地方"
    },
    {
      "name": "789",
      "id": 3,
      "password": "奥尔格和"
    }
  ]
}

而我们建的抽象类,只是用了一个简易版的观察者模式,去构建我们的通信模块,方便维护,降低耦合

3、加载图片
public void show(string url,Action<Sprite> ac)
{
    StartCoroutine(LoadImageFromUrl(url,ac));
}
IEnumerator LoadImageFromUrl(string url, Action<Sprite> ac)
{
    using (var request = UnityWebRequestTexture.GetTexture(url))
    {
        yield return request.SendWebRequest();

        if (request.result != UnityWebRequest.Result.Success)
        {
            Debug.Log(request.error);
        }
        else
        {
            Texture2D texture = DownloadHandlerTexture.GetContent(request);
            Sprite sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
            ac(sprite);
        }
    }
}

我们可以建一个脚本来测试这段代码,新建Test3

using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

public class Test3 : MonoBehaviour
{
    [SerializeField] Image im;
    private void Start()
    {
        show("https://img1.baidu.com/it/u=4049022245,514596079&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1701622800&t=c88ca2191a6df508642839cff923ed20", (a) =>
        {
            im.sprite = a;
        });
    }
    public void show(string url,Action<Sprite> ac)
    {
        StartCoroutine(LoadImageFromUrl(url,ac));
    }
    IEnumerator LoadImageFromUrl(string url, Action<Sprite> ac)
    {
        using (var request = UnityWebRequestTexture.GetTexture(url))
        {
            yield return request.SendWebRequest();

            if (request.result != UnityWebRequest.Result.Success)
            {
                Debug.Log(request.error);
            }
            else
            {
                Texture2D texture = DownloadHandlerTexture.GetContent(request);
                Sprite sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
                ac(sprite);
            }
        }
    }
}

回到unity,新建一个Image,把Test3挂上去,运行

 可以看到图片已经加载出来了,非常好用,当然这个图片如果多的话可以参考上面读json的形式改写,建立一个图片管理模块去专门加载图片,我们下期再见

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/215266.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

无人机语音中继电台 U-ATC118

简介 甚高频无线电中继通讯系统使用经过适航认证的机载电台连接数字网络传输模块&#xff0c;通过网络远程控制无缝实现无人机操作员与塔台直接语音通话。无人机操作员可以从地面控制站远程操作机载电台进行频率切换、静噪开关、PTT按钮&#xff0c;电台虚拟面板与真实面板布局…

zabbix配置snmp trap--使用snmptrapd和Bash接收器(缺zabbix_trap_handler.sh文中自取)--图文教程

1.前言 我的zabbix的版本是5.0版本&#xff0c;5.0的官方文档没有使用bash接收器的示例&#xff0c;6.0的官方文档有使用bash接收器的示例&#xff0c;但是&#xff0c;下载文件的链接失效&#xff1f;&#xff01; 这里讲解zabbix-server端配置和zabbix web端配置 2.zabbix-…

文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《考虑量化储热的多区域电–热综合能源系统优化调度》

标题 "考虑量化储热的多区域电–热综合能源系统优化调度" 可以分解为几个关键词和短语&#xff0c;我们逐步解读&#xff1a; 考虑量化储热&#xff1a; 考虑&#xff1a; 意味着在解决问题或进行研究时&#xff0c;会综合或纳入特定因素。量化&#xff1a; 将抽象的…

路由策略,gRPC 路由如何实现

目录 一、为啥我们要路由策略&#xff1a; 二、基于gRPC 路由策略 一、为啥我们要路由策略&#xff1a; 我们可以重新回到调用方发起 RPC 调用的流程。在 RPC 发起真实请求的时候&#xff0c;有一个步骤就是从服务提供方节点集合里面选择一个合适的节点&#xff08;就是我们…

【Linux】 OpenSSH_9.3p1 升级到 OpenSSH_9.5p1(亲测无问题,建议收藏)

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

node批量修改文件名称

示例目录 在终端中执行即可 node index.js // 第一步&#xff1a;引入 fs 文件系统模块 let fs require("fs"); // 读取目标文件夹名称 const dirName "./img"; // 文件后缀匹配规则 const reg /(?<[.])[a-z]/; // 统一文件名前缀 const fileNam…

SVG-椭圆弧-参数转换-计算公式-标准解读

文章目录 1.简介2.基本参数2.1.椭圆的表达2.2.参数变换2.3.注意事项 3.参考资料4.总结 1.简介 为了与其他路径段表示法保持一致&#xff0c; SVG 路径中的圆弧是根据曲线上的起点和终点定义的。椭圆弧的这种端点参数化。优点是它允许与其它路径一致的语法&#xff0c;其中所有…

22款奔驰GLE450升级香氛负离子 车载香薰功能

相信大家都知道&#xff0c;奔驰自从研发出香氛负离子系统后&#xff0c;一直都受广大奔驰车主的追捧&#xff0c;香氛负离子不仅可以散发出清香淡雅的香气外&#xff0c;还可以对车内的空气进行过滤&#xff0c;使车内的有害气味通过负离子进行过滤&#xff0c;达到车内保持清…

ASP.NET-BS结构的城市酒店入住信息管理系统的设计

2 理论基础 2.1 数据库技术 数据库技术应用中&#xff0c;经常用到的基本概念有&#xff1a;数据库&#xff08;DB&#xff09;、数据库管理系统&#xff08;DBMS&#xff09;、数据库系统&#xff08;DBS&#xff09;、数据库技术及数据模型。 数据库技术是研究数据库的结构、…

第二证券:科创板股票代码?

跟着中国经济的持续展开&#xff0c;出资商场也更加兴盛。科技立异是推动经济展开的基石&#xff0c;因此科技股在近年来的A股商场上备受瞩目。尤其是2019年7月22日&#xff0c;中国科创板正式开板&#xff0c;在A股商场上增添了一份新的亮点。本文将从多个视点深度解析科创板股…

终端安全管理软件是监控软件吗

有些人在后台问&#xff0c;终端安全管理软件是监控软件吗&#xff1f; 先回答&#xff0c;是监控软件。 因为它具有监控的功能&#xff0c;在很大程度上&#xff0c;是可以用来当做监控软件来用的。 终端安全管理软件是一种集中管理终端设备的软件工具&#xff0c;可以在企业…

线程中出现异常的处理

目录 前言 正文 1.线程出现异常的默认行为 2.使用 setUncaughtExceptionHandler() 方法进行异常处理 3.使用 setDefaultUncaughtExceptionHandler() 方法进行异常处理 4.线程组内处理异常 5.线程异常处理的优先性 总结 前言 在紧密交织的多线程环境中&#xff0c;异…

BearPi Std 板从入门到放弃 - 引气入体篇(2)(按键触发外部中断控制LED亮灭)

简介 基于 第一篇文章 的介绍&#xff0c; 我们新增按键的中断控制&#xff1b; 开发板 &#xff1a; Bearpi Std(小熊派标准板) 主芯片: STM32L431RCT6 LED : PC13 \ 推挽输出即可 \ 高电平点亮 KEY1 : PB2 \ 上拉 \ 按下下降沿触发(一次)/上下沿触发(两次&#xff0c;实现…

git常用命令小记

&#xff08;文章正在持续更新中&#xff09; git init - 在当前目录下初始化一个新的 Git 仓库。 git clone [url] - 克隆远程仓库到本地。 git add [file] - 将文件添加到暂存区。 git commit -m "commit message" - 将添加到暂存区的文件提交到本地仓库。 git pus…

python毕业设计论文选题管理系统b615y

毕业论文管理方式效率低下&#xff0c;为了提高效率&#xff0c;特开发了本毕业论文管理系统。本毕业论文管理系统主要实现的功能模块包括学生模块、导师模块和管理员模块三大部分&#xff0c;具体功能分析如下&#xff1a; &#xff08;1&#xff09;导师功能模块&#xff1a;…

Rust UI开发(五):iced中如何进行页面布局(pick_list的使用)?(串口调试助手)

注&#xff1a;此文适合于对rust有一些了解的朋友 iced是一个跨平台的GUI库&#xff0c;用于为rust语言程序构建UI界面。 这是一个系列博文&#xff0c;本文是第五篇&#xff0c;前四篇链接&#xff1a; 1、Rust UI开发&#xff08;一&#xff09;&#xff1a;使用iced构建UI时…

小红书营销4步骤,品牌需要经历哪些流程?

小红书平台是很多品牌首选的营销“主战场”。想要充分利用平台的优势&#xff0c;做好小红书营销&#xff0c;提升品牌市场认知度&#xff0c;打开产品销路&#xff0c;今天我们为大家分享下小红书营销4步骤&#xff0c;品牌需要经历哪些流程&#xff1f; 一、小红书营销四步法…

uniapp微信小程序解决绘制polygon结束时的问题

目录 一、前言 二、实现思路 三、结束标绘具体代码 1、在地图展示工具栏处判断工具按钮是否展示v-if"item.isshow" 2、data声明的工具按钮中新增结束标绘按钮 3、在按钮的点击事件中新增结束标绘的判断 4、判断绘制的线段个数是否大于等于三条&#xff0c;当满…

qiankun: 关于ElementUI字体图标加载不出来的问题

问题描述&#xff1a; 子应用使用的是vueelementUI&#xff0c;在项目main.js中需要引入elementUI的样式文件。elementUI的样式文件中有字体文件的引用&#xff0c;是以相对路径的形式写在css文件中的&#xff0c; 本来独立部署项目访问是没问题的&#xff0c;问题出现在以qi…

(03)vite 处理 css

文章目录 系列全集vite 处理css流程vite如何解决协同开发&#xff0c;样式重复覆盖的问题&#xff1f;使用less通过配置&#xff0c;更改vite的css默认行为 系列全集 &#xff08;01&#xff09;vite 从启动服务器开始 &#xff08;02&#xff09;vite环境变量配置 &#xff…