【发布时间】:2019-07-11 07:37:26
【问题描述】:
我正在构建的 Unity 项目面向 iOS、Android 和 Windows X64。
问题
在我的一个场景中,我使用 JSON 文件在运行时动态加载位于 Resources 文件夹中的一些精灵。我目前遇到的问题是:当我在 Unity 编辑器中运行游戏时,它的行为符合预期(精灵被动态加载并显示在场景中)。但是当我在三个平台中的任何一个(在真实硬件上)运行它时,精灵不会加载/显示在场景中。但静态精灵已加载。
设置
场景是一种关卡选择屏幕。对于每个级别,都会显示一个精灵。显示的精灵和精灵数量基于场景开始时读取的 JSON 文件。这是一个截图,让您有更好的印象:
在其中一个游戏对象的 Startcallback 中,我运行代码来读取 JSON 数据:
var sceneSelectionInfoList = JsonHelper.GetSceneSelectionInfoForLanguage(GameLanguage.German);
目前为止的 JSONHelper 类(使用 JSON.NET 处理来自 Asset Store 的 Unity 资源):
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public static class JsonHelper
{
private const string SceneDataIndexFilename = "Assets/Resources/SceneData/SceneDataIndex.json";
// Start is called before the first frame update
public static List<SceneSelectionInfo> GetSceneSelectionInfoForLanguage(GameLanguage language)
{
var sceneSelectionInfoList = new List<SceneSelectionInfo>();
// Open scene selection index
var sceneDataIndexEntries = GetSceneDataIndexEntries(SceneDataIndexFilename);
foreach (var sceneDataIndexEntry in sceneDataIndexEntries)
{
Logger.LogInfo(sceneDataIndexEntry.Filename);
using (var streamReader = new StreamReader(sceneDataIndexEntry.Filename))
{
var jsonData = streamReader.ReadToEnd();
var jObject = JObject.Parse(jsonData);
var id = jObject.SelectToken("id").ToString();
var basePath = jObject.SelectToken("basePath").ToString();
var sceneSelectionImage = basePath + jObject.SelectToken("dragAndDrop.sceneSelectionImage");
string title = null;
switch (language)
{
case GameLanguage.English:
title = jObject.SelectToken("titleEN").ToString();
break;
case GameLanguage.French:
title = jObject.SelectToken("titleFR").ToString();
break;
case GameLanguage.SwissGerman:
title = jObject.SelectToken("titleSG").ToString();
break;
case GameLanguage.Spanish:
title = jObject.SelectToken("titleES").ToString();
break;
case GameLanguage.German:
title = jObject.SelectToken("titleDE").ToString();
break;
case GameLanguage.Italian:
title = jObject.SelectToken("titleIT").ToString();
break;
}
var sceneSelectionInfo = new SceneSelectionInfo();
sceneSelectionInfo.SceneId = id;
sceneSelectionInfo.SceneSelectionImage = sceneSelectionImage;
sceneSelectionInfo.Title = title;
sceneSelectionInfoList.Add(sceneSelectionInfo);
}
}
return sceneSelectionInfoList;
}
private static List<SceneDataIndexEntry> GetSceneDataIndexEntries(string sceneDataIndexFilename)
{
using (var reader = new StreamReader(sceneDataIndexFilename))
{
var jsonData = reader.ReadToEnd();
Logger.LogInfo(jsonData);
return JsonConvert.DeserializeObject<List<SceneDataIndexEntry>>(jsonData);
}
}
}
仅出于完整性考虑:SceneSelectionInfo 类只是一个数据容器 (DTO),其中包含一些要传递的值:
public class SceneSelectionInfo
{
public string SceneId;
public string SceneSelectionImage;
public string Title;
}
这里是 JSON 文件和 sprite 的路径,相对于 Unity 项目文件夹:
精灵路径:Assets/Resources/SceneData/AfternoonAtTheBeach/DragAndDrop/SceneSelection.png
JSON 文件路径:Assets/Resources/SceneData/AfternoonAtTheBeach/SceneData.json
这是从 JSON 文件中截取的片段(basePath 和 sceneSelectionImage 一起构建了要加载的精灵的路径):
{
"id": "AfternoonAtTheBeach",
"basePath": "SceneData/AfternoonAtTheBeach/",
"titleEN": "Afternoon at the beach",
"titleFR": "Après-midi sur la plage",
"titleSG": "Namitag am Strand",
"titleES": "Tarde en la playa",
"titleDE": "Nachmittag am Strand",
"titleIT": "Pomeriggio in spiaggia",
"dragAndDrop": {
"sceneSelectionImage": "DragAndDrop/SceneSelection",
"levels": [
{
"backgroundImage": "DragAndDrop/Graphics/Level1/Background",
"items": [
{
"image": "DragAndDrop/Graphics/Level1/Ball",
"dropPosX": -623,
加载精灵的代码(从 JSON 文件读取路径后):
var sprite = Resources.Load<Sprite>(sceneSelectionInfo.SceneSelectionImage);
swiperItem.GetComponent<SpriteRenderer>().sprite = sprite;
到目前为止我检查过的内容
- 我使用相对路径来引用 sprite,从 Assets/Resources 目录开始,没有文件扩展名(参见上面的 sprite 路径示例)。
- 我已在 Unity Cloud Build 中禁用库缓存以避免旧的构建工件出现问题(因此每次构建时,我都会进行正确、干净的构建)
- 我可以在本地构建所有三个平台(Unity 将其报告为“构建成功”)
- 我正在使用 LoadSceneMode.Single(默认)
- 我在本地和 Unity Cloud Build 中使用相同的 Unity 版本:2018.3.0f2
感谢任何提示!
【问题讨论】:
-
这是一个复杂的问题,所以这里有一些你可以更新你的问题的东西:你的 JSON 文件以及你的 sprite 的完整路径是什么(与统一项目相关)?你加载 JSON 的代码是什么样的?在场景转换期间是否有任何复杂的异步操作或协程在运行?任何可能最终处于不良状态的静力学如何?初始化期间场景 A 依赖的任何东西(
Awake()和Start()方法)?您使用的是LoadSceneMode.Single还是LoadSceneMode.Additive?你试过切换到SceneManager.LoadSceneAsync()吗? -
@Foggzie 感谢您的反馈。我在问题中添加了更多细节。我希望这能让它更清楚。关于协程:是的,我有一些(但没有一个是异步运行的)。查看示例代码。
-
您是否认为 / 并不总是路径分隔符,应该是合适的?
-
@BugFinder 嗯,不,我没有。正斜杠是否存在任何已知问题?谢谢。
-
Windows 使用反斜杠 - 您始终可以使用 Path.PathSeparator 选择相关的反斜杠
标签: unity3d