动态配置图片

思考并回答以下问题:

  • 如果使用本地的图片,看看需要做哪些改变呢?

图片和文字说明是可以动态替换的。使用配置文件和读取文件的知识,串起来就可以搞定这个问题了。

基本思路是这样的:

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

创建场景

1、3D Object->Quad创建一面墙,然后调整物体的Scale。
2、由于主要是展示图片和文字,在这里就用3D UI进行搭建,这里面有几点需要注意。

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

创建完成大致的结构如下

配置图片和说明

配置的json文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[
{
"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。

ConfigManager

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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导入到工程中。

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

针对每个图片物体的脚本

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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文件即可,不需要重新发布。

0%