首页 > 解决方案 > Unity3D 更改未显示在构建中

问题描述

我目前正在 Unity 3D 中开发一个基本的 2D Android 问答游戏。问题是某些更改没有传递到构建,即使它们是可见的并且在编辑器中工作。我在 Windows 10(x64) 上使用 Unity 2019.4.1f1(64bit)。到目前为止我已经尝试过:

我在每次测试之间重新启动了 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");
    }
}

播放器.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 后,在StreamingAssets文件夹中查找我的 JSON 文件时,我得到了DirectoryNotFoundException ,所以我相信问题行在这里:

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 中的文件的进一步指导?

标签: unity3d

解决方案


最后,这是一个令人沮丧的简单解决方案,在检查了设备的 logcat 并看到 curl 错误之后,这向我指出了原因是UnityWebRequest的目的是查询 streamingAssetsPath,我不再使用它所以我只是必须删除对UnityWebRequest的引用并返回使用File.ReadAllTextvoila读取数据,就像它开始工作一样。

public int LoadLastLevel()
{         
    string filePath = Application.persistentDataPath + "/playerdata.json";
    string jsonString;

    jsonString = File.ReadAllText(filePath);

    JSONObject playerJson = (JSONObject)JSON.Parse(jsonString);

    lastCompletedLevel = playerJson["player"]["lastCompletedLevel"];

    Debug.Log("Player name is " + playerName + " and the last completed level is " + lastCompletedLevel);
    Debug.Log("The filePath to PlayerData.JSON is " + filePath);

    return lastCompletedLevel;
}

希望这可以帮助其他面临类似问题的人。


推荐阅读