【发布时间】:2020-06-30 12:45:58
【问题描述】:
我目前正在使用 Unity 3D 开发一个基本的 2D Android 问答游戏。问题是某些更改没有传递到构建中,即使它们在编辑器中可见并且正在工作。我在 Windows 10(x64) 上使用 Unity 2019.4.1f1(64bit)。到目前为止我尝试过的:
- 关闭 Unity 并停止后台服务,删除之前的构建实例,重新启动 Unity 并重新构建;
- 已删除 Library 文件夹并重试构建;
- 在我正在测试应用的手机上,我已恢复出厂设置并重新安装了应用。
我在每次测试之间重新启动了 Windows 10 笔记本电脑。
关于为什么没有使用最新脚本创建构建的任何其他建议?
编辑
我已经找到了问题的根源。原因似乎是我的关卡选择场景。我正在使用 json 文件来保存玩家数据,包括:
- 玩家姓名;
- 最后完成的关卡(用于激活/停用关卡按钮;
- 水平分数;
- 以布尔值表示的关卡完成状态。
我在名为 Player.cs(LoadLastLevel) 的脚本中使用了一个单独的函数来获取最后完成的关卡编号。从 json 中提取数据是使用 SimpleJSON 实现的,这里是受影响的两个区域的代码:
LevelSelectController.cs
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using SimpleJSON;
public class LevelSelectController : MonoBehaviour
{
static public int currentLevel;
public Font kb_Font;
public List<Button> buttonsList = new List<Button>();
public int lastCompletedLevel;
public Player player;
// Start is called before the first frame update
void Start()
{
int l = player.LoadLastLevel();
for (int i = 0; i < buttonsList.Count; i++)
{
int levelNum = i;
buttonsList[i].onClick.AddListener(() => {currentLevel = levelNum;});
buttonsList[i].GetComponentInChildren<Text>().fontSize = 48;
buttonsList[i].GetComponentInChildren<Text>().font = kb_Font;
buttonsList[i].GetComponent<Image>().color = Color.grey;
if (i > l)
{
buttonsList[i].interactable = false;
}
}
}
public void StartLevel()
{
SceneManager.LoadScene ("Game");
}
public void ReturnToMenu()
{
SceneManager.LoadScene ("MenuScreen");
}
}
Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using SimpleJSON;
using System.IO;
public class Player : MonoBehaviour
{
public string playerName;
public int lastCompletedLevel;
public int Load()
{
string filePath = Application.dataPath + "/StreamingAssets/data.json";
string jsonString = File.ReadAllText(filePath);
JSONObject playerJson = (JSONObject)JSON.Parse(jsonString);
playerName = playerJson["player"]["playerName"];
lastCompletedLevel = playerJson["player"]["lastCompletedLevel"];
return lastCompletedLevel;
}
public int LoadLastLevel()
{
string filePath = Application.dataPath + "/StreamingAssets/data.json";
string jsonString = File.ReadAllText(filePath);
JSONObject playerJson = (JSONObject)JSON.Parse(jsonString);
lastCompletedLevel = playerJson["player"]["lastCompletedLevel"];
return lastCompletedLevel;
}
public void SavePlayerData(int completedLevel, int levelScore)
{
string filePath = Application.dataPath + "/StreamingAssets/data.json";
string jsonString = File.ReadAllText(filePath);
JSONObject playerJson = (JSONObject)JSON.Parse(jsonString);
playerJson["player"]["lastCompletedLevel"] = completedLevel;
playerJson["player"]["levels"][completedLevel][2] = levelScore;
playerJson["player"]["levels"][completedLevel][1] = true;
string myJsonString = (playerJson.ToString());
File.WriteAllText(filePath, myJsonString);
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
我在 LevelSelectController.cs 脚本中手动设置了“l”的值,它起作用了。然后,我在 Player.cs 中手动设置了“l”的值,以排除脚本的 JSON 部分的问题,但它失败了。所以我认为根本原因是构建没有引入 Player.cs 脚本,因此在 LevelSelectController.cs 脚本中对 player.LoadLastLevel() 的调用失败。
我怀疑问题在于我如何调用 player.LoadLastLevel(),我应该调用脚本附加到的 GameObject 吗?
编辑两个
我认为我有问题的原因,在应用程序运行时使用 adb 检查设备上的 logcat 后,我在 中查找我的 JSON 文件时收到 DirectoryNotFoundException >StreamingAssets 文件夹,所以我相信问题行在这里:
string filePath = Application.dataPath + "/StreamingAssets/data.json";
任何关于如何解决的想法都会受到欢迎?
编辑三个
我通过设置这个问题的答案来跳过枪。虽然下面提供的代码愉快地从 data.json 读取,但它不会写入:
public int LoadLastLevel()
{
string filePath = Path.Combine(Application.streamingAssetsPath, "data.json");
string jsonString;
if (Application.platform == RuntimePlatform.Android)
{
UnityWebRequest www = UnityWebRequest.Get(filePath);
www.SendWebRequest();
while (!www.isDone) ;
jsonString = www.downloadHandler.text;
}
else
{
jsonString = File.ReadAllText(filePath);
}
JSONObject playerJson = (JSONObject)JSON.Parse(jsonString);
lastCompletedLevel = playerJson["player"]["lastCompletedLevel"];
return lastCompletedLevel;
}
我已经能够在persistentDataPath 中创建一个*.json 文件,而不是使用相同的代码并将filePath 的目标更改为persistentDataPath。问题是我无法随后读取或编辑该文件。读取返回 null。
让我走到这一步要归功于 Triple_Why 在 Unity 论坛上对消息的回应
https://forum.unity.com/threads/cant-use-json-file-from-streamingassets-on-android-and-ios.472164/
欢迎提供有关如何在 Android 上读取/写入persistentDataPath 中的文件的任何进一步指导?
【问题讨论】:
-
尝试进行本地 Windows 构建以确保您的更改在其中可见。如果是,这不是 Unity 的错,请确保您在设备上安装了正确的 apk。另外,尝试将 apk 构建到一个新的、易于查找的位置并通过 adb 手动安装。
-
您确定该版本实际上是一个新版本吗?你能检查一下构建文件的修改日期吗?
-
我已经尝试了本地 Windows 构建并且它有效。绝对是正确的 APK,因为我更改了版本号以进行验证。启动 Linux 设备后,将尝试第二个建议。由于所述原因,我确信 APK 构建文件是新的。一旦我测试了建议,就会反馈。
-
已经成功创建了一个新的apk并通过在c:\temp中创建它验证它是新的,通过ADB安装它,安装它没有错误,但内容仍然过期?
标签: unity3d