【问题标题】:Unity Streaming Assets iOS not workingUnity Streaming Assets iOS 不工作
【发布时间】:2020-10-21 15:05:16
【问题描述】:

我在 Unity 中制作了一个应用程序,该应用程序已在 Google Play 商店上架一年多。今天我想在 Apple App Market 上部署它,但翻译在那里不起作用。

我使用以下代码加载我的应用翻译

public bool LoadLocalizedText(SystemLanguage language)
{
    localizedText = new Dictionary<string, string>();
    string filePath = Path.Combine(Application.streamingAssetsPath, "localizedText_" + language + ".json");

    WWW reader = new WWW(filePath);
    if (reader.text == null || reader.text == "") return false;
    while (!reader.isDone) { }
    string dataAsJson;
    dataAsJson = reader.text;
    LocalizationData loadedData = JsonUtility.FromJson<LocalizationData>(dataAsJson);



     for (int i = 0; i < loadedData.items.Length; i++)
     {
         localizedText.Add(loadedData.items[i].key, loadedData.items[i].value);
     }


    Debug.Log("Data loaded, dictionary contains: " + localizedText.Count + " entries");
    if (localizedText.Count == 0) return false;
    else
    {
        isReady = true;
        return true;
    }
}

但不知何故,所有文本字段都显示“未找到本地化文本”,因为它找不到我的资产...这可能是什么?

这是因为 StreamingAssets 文件夹未复制到 xCode 吗? 是因为iOS上的位置不同吗? 还有什么?

这是我的文件夹结构

【问题讨论】:

  • 这适用于 Android 吗?你能显示你把 json 文件放在哪里的屏幕截图吗?
  • @Programmer 是的,它确实适用于 Android。我现在已经在文件夹结构中包含了一个屏幕截图。 StreamingAssets 里面是 json 文件

标签: c# unity3d


【解决方案1】:

WWWUnityWebRequest API 用于读取 Android 上 StreamingAssets 上的文件。对于 iOS,应使用 System.IO 命名空间中的任何 API,例如 System.IO.File.ReadAllText

类似这样的:

IEnumerator ReadFromStreamingAssets()
{
    string filePath = System.IO.Path.Combine(Application.streamingAssetsPath, "MyFile");
    string result = "";
    if (filePath.Contains("://"))
    {
        UnityEngine.Networking.UnityWebRequest www = UnityEngine.Networking.UnityWebRequest.Get(filePath);
        yield return www.SendWebRequest();
        result = www.downloadHandler.text;
    }
    else
        result = System.IO.File.ReadAllText(filePath);
}

此外,WWW API 可用于协程函数,以便您可以等待或放弃它,直到下载完成。您的 while (!reader.isDone) { } 可以冻结 Unity。那应该是while (!reader.isDone) yield return null;,它会等待每一帧直到下载完成。 LoadLocalizedText 函数也必须是协程函数,因此返回类型应该是 IEnumerator 而不是 bool。要使其也返回bool,请使用Action&lt;bool&gt; 作为参数。

解决这两个问题后,新代码应如下所示:

public IEnumerator LoadLocalizedText(SystemLanguage language, Action<bool> success)
{
    localizedText = new Dictionary<string, string>();
    string filePath = Path.Combine(Application.streamingAssetsPath, "localizedText_" + language + ".json");

    string dataAsJson;

    //Android
    if (filePath.Contains("://"))
    {

        WWW reader = new WWW(filePath);

        //Wait(Non blocking until download is done)
        while (!reader.isDone)
        {
            yield return null;
        }

        if (reader.text == null || reader.text == "")
        {
            success(false);

            //Just like return false
            yield break;
        }

        dataAsJson = reader.text;
    }

    //iOS
    else
    {
        dataAsJson = System.IO.File.ReadAllText(filePath);
    }


    LocalizationData loadedData = JsonUtility.FromJson<LocalizationData>(dataAsJson);



    for (int i = 0; i < loadedData.items.Length; i++)
    {
        localizedText.Add(loadedData.items[i].key, loadedData.items[i].value);
    }


    Debug.Log("Data loaded, dictionary contains: " + localizedText.Count + " entries");
    if (localizedText.Count == 0)
        success(false);
    else
    {
        isReady = true;
        success(true);
    }
}

并像这样使用:

StartCoroutine(LoadLocalizedText(languageInstance, (status) =>
{
    if (status)
    {
        //Success
    }
}));

【讨论】:

  • 谢谢!一定会试一试,如果有帮助,请告诉您。我还将 if 条件更改为 #if UNITY_ANDROID,而不是自己检测它在哪个平台上运行。但是,我必须说该文件没有被下载,而是包含在二进制文件中,所以如果没有 yield return null,我真的看不出我的 while 条件有问题
  • 您不必添加UNITY_ANDROID 或专门检查Android。我已经用if (filePath.Contains("://")) 处理了这个问题。在我的答案中尝试新的 LoadLocalizedText 函数,如果它有效。直接复制就好了。至于yield return null,不管是下载还是加载都无所谓。你应该总是产生非常WWW 操作。同样,这是为了确保代码不会冻结 Unity。
  • 我的意思是用 Visual Studio 检查替换 if(filePath.Contains(...)。我收到错误消息,指出并非所有代码路径都返回值
  • “我的意思是用 Visual Studio 检查替换 if(filePath.Contains(...)。” 就像我上面说的,你 不要 必须这样做。我的代码中的if (filePath.Contains("://")) 会这样做。这是因为Android流资产路径中有“://”,但对于其他平台没有。至于你的错误,那是因为你错过了yield return null。你需要它。也许你没有看到我的代码,刷新这篇文章以查看我的代码中的编辑。如果你直接将它复制到你的 IDE,我的答案中的最后一个代码将起作用。Don '不要修改它。 像 lit 一样复制它。
  • 我刚刚注意到我用来创建此答案的代码中的另一个错误。在下载完成之前,您正在检查if (reader.text == null || reader.text == "")。那是不对的。这应该在下载完成后完成。我再次更新了LoadLocalizedText 函数。直接复制就好了。一旦你得到它的工作,你改变它到任何你想要的。
【解决方案2】:

JsonUtility 与 iOS 有问题,所以它不起作用 如果您在本地使用 File.OpenRead(path) 在 iOS 中进行测试 filePath = Application.streamingAssetsPath

StreamReader streamReader = new StreamReader(File.OpenRead(string.Format("{0}/{1}.txt", filePath, fileName)));

如果你想在 iOS 中写入文件,streamingAssets 只读使用这个路径 -> Application.persistentDataPath

【讨论】:

    【解决方案3】:

    实际上问题在于 Application.streamingAssetsPath 对于 iOS 设备并不完全正确。您还需要手动将 "file://" 添加到路径中。请注意,它应该在 Path.Combine() 方法之外完成,因为由于某种原因,Combine() 方法会剥离它 =) 我浪费了几个小时试图了解出了什么问题,我希望我的帖子能节省一些人的时间。正确的做法是:filePath = "file://" System.IO.Path.Combine(Application.streamingAssetsPath, "MyFile"); 其余代码相同(这是真的也适用于 AssetBundle)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-24
      • 1970-01-01
      • 2022-01-13
      • 1970-01-01
      • 2016-10-14
      • 1970-01-01
      相关资源
      最近更新 更多