Unity对接后台和加载图片

news2025/6/8 21:21:36
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的形式改写,建立一个图片管理模块去专门加载图片,我们下期再见

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue权限管理解决方案

一. 什么是权限管理 权限控制是确保用户只能访问其被授权的资源和执行其被授权的操作的重要方面。而前端权限归根结底是请求的发起权&#xff0c;请求的发起可能有下面两种形式触发 页面加载触发页面上的按钮点击触发 总体而言&#xff0c;权限控制可以从前端路由和视图两个…

QProcess 启动 进程 传参数 启动控制台进程 传参

目录 QProcess 启动外部程序的两种方式 依赖式 分离式&#xff1a; 启动进程前的预处理 设置启动路径 设置启动命令参数 设置启动工作目录 设置启动所需环境&#xff1a; 启动的状态 code smple: QProcess 控制台进程 QProcess启动控制台不显示窗口 注意&#xff1a;…

jvm基本概念,运行的原理,架构图

文章目录 JVM(1) 基本概念:&#xff08;2&#xff09;运行过程 今天来和大家聊聊jvm&#xff0c; JVM (1) 基本概念: JVM 是可运行Java代码的假想计算机&#xff0c;包括一套字节码指令集、一组寄存器、一个栈一个垃圾回收&#xff0c;堆 和 一个存储方法域。JVM 是运行在操作…

9.ROS的TF坐标变换(三):坐标系关系查看与一个案例

1 查看目前的坐标系变化 我们先安装功能包&#xff1a; sudo apt install ros-melodic-tf2-tools安装成功&#xff01; 我们先启动上次的发布坐标变换的节点&#xff1a; liuhongweiliuhongwei-Legion-Y9000P-IRX8H:~/Desktop/final/my_catkin$ source devel/setup.bash liuho…

cyclictest 交叉编译与使用

目录 使用版本问题编译 numactl编译 cyclictest使用参考 cyclictest 主要是用于测试系统延时&#xff0c;进而判断系统的实时性 使用版本 rt-tests-2.6.tar.gz numactl v2.0.16 问题 编译时&#xff0c;需要先编译 numactl &#xff0c;不然会有以下报错&#xff1a; arm-…

Linux:优化原则

web系统的优化原则&#xff1a; 从单机到集群 对Linux系统自身的优化原则&#xff1a;

TCP报文解析

1.端口号 标记同一台计算机上的不同进程 源端口&#xff1a;占2个字节&#xff0c;源端口和IP的作用是标记报文的返回地址。 目的端口&#xff1a;占2个字节&#xff0c;指明接收方计算机上的应用程序接口。 TCP报头中的源端口号和目的端口号同IP报头中的源IP和目的IP唯一确定一…

【QT】Windows环境下,cmake引入QML

这里使用的QT库为5.7版本。 1、添加环境变量 QT库根目录环境变量 QTDIR QT库平台插件环境变量 QT_PLUGIN_PATH QML支持环境变量 QML2_IMPORT_PATH &#xff08;该环境变量仅在需要使用QML时添加&#xff09; QT库动态库环境变量&#xff0c;bin目录下包含了QT程序运行所需的dl…

电子学会C/C++编程等级考试2022年03月(四级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:拦截导弹 某国为了防御敌国的导弹袭击, 发展出一种导弹拦截系统。 但是这种导弹拦截系统有一个缺陷: 虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。 某天, 雷达捕捉到敌国的导弹来袭。…

第十一届蓝桥杯青少组省赛Python中高级组真题及赏析

练习最好的办法就是实战。拿真题来做&#xff0c;不是解析是赏析。带着欣赏的眼光看&#xff0c;题目不但不难&#xff0c;反倒增加不少乐趣。接下来揭开第十一届蓝桥杯青少组省赛python编程题的神秘面纱&#xff0c;我们来一一赏析&#xff0c;看难不难。 选择题 选择题都比较…

C++核心编程——类与对象基础

C核心编程——类与对象基础 类与对象封装构造函数普通构造拷贝构造初始化成员列表&#xff08;补充&#xff09; 析构函数对象数组对象指针指向对象的指针指向对象成员的指针this指针 静态成员静态数据成员静态成员函数 友元普通函数做友元函数友元成员函数友元类 类与对象 C面…

深度学习常见回归分支算法逐步分析,各种回归之间的优缺点,适用场景,举例演示

文章目录 1、线性回归&#xff08;Linear Regression&#xff09;1.1 优点1.2 缺点1.3 适用场景1.4 图例说明 2、多项式回归&#xff08;Polynomial Regression&#xff09;2.1 优点2.2 缺点2.3 适用场景2.4 图例说明 3、决策树回归&#xff08;Decision Tree Regression&#…

Linux基础命令(超全面,建议收藏!)

一、Linux的目录结构 /&#xff0c;根目录是最顶级的目录了 Linux只有一个顶级目录&#xff1a;/ 路径描述的层次关系同样使用/来表示 /home/itheima/a.txt&#xff0c;表示根目录下的home文件夹内有itheima文件夹&#xff0c;内有a.txt 二、Linux命令基础格式 无论是什么…

孩子都能学会的FPGA:第十八课——用FPGA实现定点数的除法

&#xff08;原创声明&#xff1a;该文是作者的原创&#xff0c;面向对象是FPGA入门者&#xff0c;后续会有进阶的高级教程。宗旨是让每个想做FPGA的人轻松入门&#xff0c;作者不光让大家知其然&#xff0c;还要让大家知其所以然&#xff01;每个工程作者都搭建了全自动化的仿…

vivado实现分析与收敛技巧6-策略建议

典型时序收敛策略需运行大量实现策略并选取其中最佳的策略以供在实验室内应用。 ML 策略同样可选 &#xff0c; 且只需您运行3 项策略即可达成类似的 QoR 收益。这些策略使用机器学习来检验布线后设计的各项功能特性 &#xff0c; 以便预测相同设计上不同策略的性能。在 repo…

树莓派4b安装ubuntu22和向日葵设置开机启动

树莓派4b安装ubuntu22和向日葵设置开机启动 使用树莓派烧录系统工具烧录ubuntu 在树莓派官网下载官方软件&#xff0c;安装完后运行 在软件上选择 选择ubuntu桌面或者server 根据自己需求选择&#xff0c;这里我选择22.04的系统 烧录好以后进入系统 安装向日葵 下载树莓…

Android实验:启动式service

目录 实验目的实验内容实验要求项目结构代码实现结果展示 实验目的 充分理解Service的作用&#xff0c;与Activity之间的区别&#xff0c;掌握Service的生命周期以及对应函数&#xff0c;了解Service的主线程性质&#xff1b;掌握主线程的界面刷新的设计原则&#xff0c;掌握启…

如何在WordPress中批量替换图片路径?

很多站长在使用WordPress博客或者搬家时&#xff0c;需要把WordPress文章中的图片路径进行替换来解决图片不显示的问题。总结一下WordPress图片路径批量替换的过程&#xff0c;方便有此类需求的站长们学习。 什么情况下批量替换图片路径 1、更换了网站域名 有许多网站建设初期…

一文了解工业互联网是什么,和传统互联网的区别有哪些

几个问题 工业互联网和传统互联网有什么区别 1 业务方面&#xff0c;传统的互联网企业更多是toC的业务&#xff0c;直接面对的是一个个的个体&#xff0c;而工业互联网离消费者更远一点&#xff0c;往往是toB或者toG的&#xff1b; 个人认为这也是最根本的区别&#xff0c;由…

什么是Daily Scrum?

Daily Scrum&#xff08;每日站会&#xff09;&#xff0c;Scrum Master要确保这个会在每天都会开。这个会的目的就是检查正在做的东西和方式是否有利于完成Sprint目的&#xff0c;并及时做出必要的调整。 每日站会一般只开15分钟&#xff0c;为了让事情更简单些&#xff0c;这…