访问Android上的Unity StreamingAssets

时间:2016-02-23 15:52:11

标签: android unity3d directory assets unity5

我编写了一些代码来获取StreamingAssets中文件夹内的所有文件夹,然后获取该文件夹中的所有文件。 它在Windows上运行良好,但我无法在Android上运行。

以下是代码:

foreach (string s in Directory.GetDirectories(model.path + "/Levels")) {
        GameObject el = (GameObject)Instantiate(listButton, Vector3.zero, Quaternion.identity);
        el.transform.SetParent(grid1.transform);
        string[] words = s.Split('/');
        #if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
                            words = s.Split('\\');
        #endif
        el.GetComponentInChildren<Text>().text = words[words.Length - 1];
        el.GetComponent<Button>().onClick.AddListener(() => {
            MapSizeButtonClick(Int32.Parse(el.GetComponentInChildren<Text>().text));
        });
    }

由于&#39; \&#39;我必须为Windows添加#if UNITY_STANDALONE_WIN。

然后对于该文件夹中的文件,我写了这个:

foreach (string s in Directory.GetFiles(model.path + "/Levels/" + model.mapSize + "/" + model.colorNumber)) {
        string[] words = s.Split('/');
        #if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
                    words = s.Split('\\');
        #endif
        words = words[words.Length - 1].Split('.');
        if (words[1] == "json") {
            GameObject el = (GameObject)Instantiate(listButton, Vector3.zero, Quaternion.identity);
            el.transform.SetParent(grid3.transform);
            el.GetComponentInChildren<Text>().text = words[0];
            el.GetComponent<Button>().onClick.AddListener(() => {
                levelButtonClick(Int32.Parse(el.GetComponentInChildren<Text>().text));
            });
        }
    }

我使用UnityEngine.UI.Directory,但我读到它无法在Android上使用,我必须使用WWW。像这样:

string xmlSetUpPath = "jar:file://" + Application.dataPath + "!/assets/xml/xmlSetUp.xml";

        WWW book1WWW = new WWW(book1Path);
        yield return book1WWW;
        if(!File.Exists(Application.persistentDataPath + "/xml/book1.xml"))
        {
            File.WriteAllBytes(Application.persistentDataPath + "/xml/book1.xml", book1WWW.bytes); 
        }

但是我找不到像Directory.getFiles()或Directory.getFolder()那样的东西。所以我想我可以使用WWW来检查文件是否存在(因为文件名是1.json,2.json,3.json)并迭代直到文件不存在。

但我还需要检查脚本的第一部分是否存在文件夹,我无法找到如何检查WWW是否存在文件夹。 (我的文件夹名称也是1,2,3,4 ......)

那么如何检查WWW中是否存在文件夹?

或者我还能做什么?

更新:

我更新了代码,现在看起来像这样:

for (int i = 0; i < 100; i++) {
        if (Directory.Exists(Path.Combine(model.path, "Levels/" + i.ToString()))){
            GameObject el = (GameObject)Instantiate(listButton, Vector3.zero, Quaternion.identity);
            el.transform.SetParent(grid1.transform);
            el.GetComponentInChildren<Text>().text = i.ToString();
            el.GetComponent<Button>().onClick.AddListener(() => {
                MapSizeButtonClick(Int32.Parse(el.GetComponentInChildren<Text>().text));
            });
        }
    }

我使用path.combine()并检查0到100之间的每个文件夹。它适用于Windows但它仍然无法在Android中运行。

路径设置如下:

#if UNITY_IPHONE
        path = Application.dataPath + "/Raw";
    #endif

    #if UNITY_ANDROID
        path = "jar:file://" + Application.dataPath + "!/assets";
    #endif

    #if UNITY_STANDALONE || UNITY_EDITOR
        path = Application.dataPath + "/StreamingAssets";
    #endif

问题更新

我创建了一个生成文件路径的脚本。路径始终相同:&#34; FolderNumerotedFromYToX / FolderNumerotedFromYToX / FileNumerotedFrom1ToX.json&#34;。这一代有效,但写给JSON并不是。它输出&#34; {}&#34;。

        // Generate level list
    List<KeyValuePair<int, List<KeyValuePair<int, List<int>>>>> l;
    l = new List<KeyValuePair<int, List<KeyValuePair<int, List<int>>>>>();
    for (int i = 1; i < 100; i++) {
        if (Directory.Exists(Path.Combine(Path.Combine(Application.dataPath, "StreamingAssets"), "Levels/" + i.ToString()))) {
            l.Add(new KeyValuePair<int, List<KeyValuePair<int, List<int>>>>(i, new List<KeyValuePair<int, List<int>>>()));
            for (int j = 1; j < 100; j++) {
                if (Directory.Exists(Path.Combine(Path.Combine(Application.dataPath, "StreamingAssets"), "Levels/" + i + "/" + j))) {
                    l[l.Count - 1].Value.Add(new KeyValuePair<int, List<int>>(j, new List<int>()));
                    int k = 1;
                    while (true) {
                        if (File.Exists(Path.Combine(Path.Combine(Application.dataPath, "StreamingAssets"), "Levels/" + i + "/" + j + "/" + k + ".json"))) {
                            l[l.Count - 1].Value[l[l.Count - 1].Value.Count - 1].Value.Add(k);
                        }
                        else
                            break;
                        k++;
                    }
                }
            }
        }
    }
    string ljson = JsonUtility.ToJson(l);
    var lsr = File.CreateText("Assets/StreamingAssets/levels.json");
    lsr.WriteLine(ljson);
    lsr.Close();

您能帮我找到将其存储到文件中的方法吗?

2 个答案:

答案 0 :(得分:6)

听起来可能很难,但您必须使用WWW课程从Android上的StreamingAssets访问您的文件。

您必须保留文件名列表才能访问它们,因为似乎无法使用File.ExistsDirectory.GetFiles之类的内容。

示例:

WWW www = new WWW(source);
yield return www;

if (string.IsNullOrEmpty(www.error))
{
    // make sure the destination directory exists
    File.WriteAllBytes(destination, www.bytes); 
}
else
{
    // error handling
}

您的源文件(基本)路径应如下所示: jar:file://" + Application.dataPath + "!/assets/

来自文档:

  

请注意,在Android上,文件包含在压缩的.jar中   file(基本上与标准zip压缩格式相同)   文件)。这意味着如果你不使用Unity的WWW类   检索文件然后您将需要使用其他软件来查看   在.jar归档文件中并获取文件。

来源:http://docs.unity3d.com/Manual/StreamingAssets.html

答案 1 :(得分:1)

为了解决这个问题,我创建了预编译脚本,它将在编译之前运行;此脚本将在稍后的文本文件

中列出您要访问的文件的名称
 #if UNITY_EDITOR
 using UnityEditor.Build;
 using UnityEditor;
 using System.IO;

 public class BM_AndroidBuildPrepartion : IPreprocessBuild
 {
     public int callbackOrder { get { return 0; } }
     public void OnPreprocessBuild(BuildTarget target, string path)
     {
         // Do the preprocessing here
         string[] fileEntries = Directory.GetFiles("Assets/Resources/Prefabs/alphabet", "*.prefab");
         System.IO.Directory.CreateDirectory("Assets/StreamingAssets/");
         using (StreamWriter sw = new StreamWriter("Assets/StreamingAssets/alphabet.txt", false))
         {

         foreach (string filename in fileEntries) {
                 sw.WriteLine(Path.GetFileNameWithoutExtension(filename));
         }

         }
     }
 }
 #endif

然后我读了文本文件,你可以用同样的方式访问文件,但你必须把它们放在你的项目中的Assets / StreamingAssets /

#if UNITY_ANDROID
        string  path = "jar:file://" + Application.dataPath + "!/assets/alphabet.txt";
          WWW wwwfile = new WWW(path);
          while (!wwwfile.isDone) { }
          var filepath = string.Format("{0}/{1}", Application.persistentDataPath, "alphabet.t");
          File.WriteAllBytes(filepath, wwwfile.bytes);

          StreamReader wr = new StreamReader(filepath);
              string line;
              while ((line = wr.ReadLine()) != null)
              {
              //your code
              }
   #endif