【专栏精选】实战:动态配置图片

本文节选自洪流学堂公众号技术专栏《大话Unity2019》,未经允许不可转载。

洪流学堂公众号回复专栏,查看更多专栏文章。

洪流学堂,让你快人几步。你好,我是郑洪智。

小新:“大智,最近我在做一个虚拟展厅的demo,你说我怎么最大程度提高这个程度的扩展性呢?最好图片和文字说明是可以动态替换的。”
大智:“这个问题用我们这两周学的配置文件和读取文件的知识,串起来就可以搞定这个问题了!”
小新:“那你可以不可以给我提示一下?”
大智:“没问题,基本思路是这样的:”

  • 使用json配置图片的路径和文字说明
  • 动态获取外部的图片,这样图片可以在外面替换,不用重新发布程序

实战:动态配置图片

小新:“好,我大概有思路了,我先试试。”

创建场景

1、先创建一个虚拟展厅的场景,我这里偷懒就使用一个3D Object > Quad创建了一面墙,然后调整物体的Scale。
2、由于主要是展示图片和文字,在这里就用3D UI进行搭建,这里面有几点需要注意。

  • 注意图片选择Raw Image组件。RawImage可以直接显示Texture类型的贴图,而不用转换为Sprite。
  • Canvas设置为World Space,然后设置位置和Scale,符合三维场景中墙壁的尺寸。
  • 这里我将Text作为了图片的子物体(如果你的层级结构不同,下面获取图片对应的代码需要做相应的修改)

创建完成大致的结构如下

配置图片和说明

配置的json文件如下:

[
    {
        "Id": 1,
        "Url": "http://www.zyzw.com/sjmhxs/sjmhxst/sjmhxst003.jpg",
        "Name": "蒙娜丽莎"
    },
    {
        "Id": 2,
        "Url": "http://www.zyzw.com/sjmhxs/sjmhxst/sjmhxst003.jpg",
        "Name": "蒙娜丽莎"
    },
    {
        "Id": 3,
        "Url": "http://www.zyzw.com/sjmhxs/sjmhxst/sjmhxst003.jpg",
        "Name": "蒙娜丽莎"
     }
]

一定要注意保存的文件不要有BOM头。

这里面你会注意到我加了一个Id,这个Id是用来和场景中的物体进行对应,便于修改与调试。否则我们就只能通过数组的索引来访问,很不方便。

不知道你还记不记得,Unity自带的JsonUtility无法解析最外层是数组的JSON字符串,如果你像我上面那样写,需要导入LitJson。

扫描二维码关注公众号,回复: 8864554 查看本文章

ConfigManager

由于我们很多对象中都需要获取这个配置信息,所以我们通过一个通用的管理类来获取配置的数据。

using System;
using System.Collections;
using System.IO;
using System.Linq;
using LitJson;
using UnityEngine;
using UnityEngine.Networking;

// 图片信息
public class PicData
{
    public int Id;
    public string Url;
    public string Name;
}

public class ConfigManager : MonoBehaviour
{
    // 设置为静态,方便在其他地方访问
    public static PicData[] Data;

    IEnumerator Start()
    {
        var uri = new Uri(Path.Combine(Application.streamingAssetsPath, "data.json"));
        var request = UnityWebRequest.Get(uri);
        yield return request.SendWebRequest();

        if (request.isHttpError || request.isNetworkError)
            Debug.Log(request.error);
        else
            ParseJsonStr(request.downloadHandler.text);
    }

    // 解析获取到的JSON字符串
    private void ParseJsonStr(string json)
    {
        Data = JsonMapper.ToObject<PicData[]>(json);
        Debug.Log(Data.Length);
    }

    // 使用Linq获取第一个符合Id的数据
    public static PicData GetData(int id)
    {
        return Data.First(t => t.Id == id);
    }
}

记得把LitJson导入到工程中,如果忘了回去看看195节哦。

创建一个Manager空物体,将这个脚本挂到Manager空物体上。

针对每个图片物体的脚本

下面的代码用于从配置类中获取信息,然后去下载对应的图片。

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

public class Picture : MonoBehaviour
{
    public int Id;

    IEnumerator Start()
    {
        // 防止配置文件还没读取完毕
        while (ConfigManager.Data == null) yield return null;

        var data = ConfigManager.GetData(Id);

        // 如果Id有误,没有对应的数据则退出此协程
        if (data == null) yield break;

        var uri = new Uri(data.Url);

        // 使用UnityWebRequestTexture类来获取图片
        var request = UnityWebRequestTexture.GetTexture(uri);
        yield return request.SendWebRequest();

        if (request.isHttpError || request.isNetworkError)
            Debug.Log(request.error);
        else
            GetComponent<RawImage>().texture = DownloadHandlerTexture.GetContent(request);

        GetComponentInChildren<Text>().text = data.Name;
    }
}

将这个脚本挂在Pic1、Pic2、Pic3物体上并设置相应的Id即可。

总结

最后的结果如下:

如果你想改变墙上的图片和内容,即使发布出来以后,也只需要修改json文件即可,不需要重新发布。

今日思考题

大智:“如果使用本地的图片,看看需要做哪些改变呢?”
小新:“好嘞!”
大智:“收获别忘了分享出来!也别忘了分享给你学Unity的朋友,也许能够帮到他。”

推荐阅读

洪流学堂公众号回复专栏,查看更多专栏文章。

《大话Unity2019》,大智带小新学Unity2019的有趣经历,让你学Unity更简单。

https://edu.hongliu.cc

发布了138 篇原创文章 · 获赞 72 · 访问量 29万+

猜你喜欢

转载自blog.csdn.net/zhenghongzhi6/article/details/92586341