Unity3D Android:如何在构建后从文件夹动态(从文件)加载图像和声音?

时间:2018-01-30 13:13:57

标签: c# android unity3d dynamic build

编辑: 因为它被标记为Using Resources Folder in Unity的副本 我需要说它是不同的。因为我知道如何使用资源文件夹,如果你已经阅读了整篇文章,你会看到我已经在使用它,就像在帖子中说的那样。我'如果我没有事先实例化所有图像,因为.apk文件之后不允许我访问该文件夹,因此在构建完成时会遇到麻烦。所以,请再次阅读,不要将其标记为副本,特别是当问题被标注为已经在标题中的另一个问题时...谢谢!

原件:

我是Stack Overflow的新手,所以我希望,我能为您提供所需的所有信息。

我在Unity3D中开发了一款严肃游戏,我需要实例化各种数量的预制拼片,并在场景发生变化时动态更改它的精灵和声音。我会在代码之后解释更多。

这里的代码在编辑器中完美运行:

using UnityEngine;
using UnityEngine.SceneManagement;

#if UNITY_EDITOR
using UnityEditor;
#endif

using System;
using System.IO;

public class SourceManager : MonoBehaviour
{
private string path;
private string filePath;

private string wrongSoundDir;
private string rightSoundDir;

private string letter;
private string levelsFile = "LevelsToLoad.csv";
private string[] listOfCounterletters;
private string[] wordsOne;
private string[] wordsTwo;
private string letterOne;
private string letterTwo;
private string text;
private string text2;

private void Awake()
{
    Debug.Log("SourceManager active.");

    path = GetPath();
    if (SceneManager.GetActiveScene().buildIndex != 0)
    {
        filePath = GetFilePath(path);
        GetLettersFromFile(out letterOne, out letterTwo);
        letter = letterOne;
        if (SceneManager.GetActiveScene().name == "Words" || SceneManager.GetActiveScene().name == "Container")
        {
            GetWordsFromFile(letter, out wordsOne);
            GetWordsFromFile(letterTwo, out wordsTwo);
        }
        SetRightWrongSounds();
    }
}

private string GetPath()
{
    // Returns the path of the active scene
    Debug.Log("Getting path...");
    return SceneManager.GetActiveScene().path.Remove(SceneManager.GetActiveScene().path.LastIndexOf('/') + 1);
}

private string GetFilePath(string path)
{
    // Returns the filepath of the active scene (removes "Assets/Resources/" part)
    Debug.Log("Getting filePath...");
    return path.Replace("Assets/Resources/", "");
}


public void SetRightWrongSounds()
{
    // sets right and wrong sounds
    wrongSoundDir = "mainMusic/general/wrong";
    rightSoundDir = "mainMusic/general/right";
}

private void GetLettersFromFile(out string posL, out string negL)
{
    if (path != null)
    {
        text = File.ReadAllText(path + "letters.txt");
        listOfCounterletters = text.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
        posL = listOfCounterletters[0];
        negL = listOfCounterletters[1];
    }
    else
    {
        Debug.LogError("Path not set (yet). Cannot set pos and neg letters.");
        posL = null;
        negL = null;
    }
}

private void GetWordsFromFile(string letter, out string[] words)
{
    if (letter != null)
    {
        text = File.ReadAllText(path + letter + ".csv");
        words = text.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
    }
    else
    {
        Debug.LogError("Letter not set (yet). Cannot set words list.");
        words = null;
    }
}

public void ChangeToScene(int number)
{
    if (number < SceneManager.sceneCountInBuildSettings)
    {
        if (SceneManager.GetActiveScene() != SceneManager.GetSceneByBuildIndex(number))
            SceneManager.LoadScene(number);
        else
            Debug.LogError("Scene already active.");
    }
    else
    {
        Debug.LogError("Scenenumber is not within the Build Settings.");
    }
}

public string GetLetterOne() { return letterOne; }
public string GetLetterTwo() { return letterTwo; }
public string[] GetWordsOne() { return wordsOne; }
public string[] GetWordsTwo() { return wordsTwo; }
public string GetDirectory() { return path; }
public string GetFileDirectory() { return filePath; }

public string GetWrongSoundDir() { return wrongSoundDir; }
public string GetRightSoundDir() { return rightSoundDir; }
}

所以在Unity编辑器中我只是通过获取路径来实现它,我的场景所在的位置(我需要它像这样而不是在一个单独的场景文件夹中,因为我需要几个具有相同名称但不同的场景内容和整个场景必须由不知道如何使用统一的人编辑,所以我希望他们只需复制粘贴文件夹并替换内容,这样他们就不必乱七八糟与代码甚至开放统一)。

之后我使用函数GetLettersFromFile来获取几个字母(这将在整个时间内更改,这就是为什么我需要它是动态的。)

然后我有许多不同名字的场景,以及名称为&#34; Words&#34;或&#34;容器&#34;我在它们所在的文件夹中有两个.csv文件,其中包含所有需要实例化的精灵/声音(同名)的名称。

E.g。我可以插入100个图像和100个声音,但只能在此列表(csv)中写入10个,因此只需要将其中的10个实例化为预制图块。

这里是我用来反映磁贴的代码示例:

files_dir = sourceManager.GetComponent<SourceManager>().GetFileDirectory();

GameObject[] InitTiles(string myletter, string[] text)
{
    GameObject[] newObj = new GameObject[text.Length - 1];
    for (int i = 0; i < text.Length - 1; i++)
    {
        Debug.Log(files_dir + text[i]);
        zVal = -20.0f + ((i + 2) / 20);
        clone = (GameObject)Instantiate(tile, new Vector3(UnityEngine.Random.Range(-180, 180), UnityEngine.Random.Range(-50, 50), zVal), Quaternion.identity);
        clone.gameObject.GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>(files_dir + text[i]);
        clone.gameObject.GetComponent<AudioSource>().clip = Resources.Load<AudioClip>(files_dir + text[i]);
        clone.gameObject.GetComponent<Dragable>().dragable = true;
        clone.gameObject.GetComponent<Dragable>().letter = myletter;
        newObj[i] = clone;
    }
    return newObj;
}

正如你所看到的,我希望它们可以拖动,如果我开始拖动它们,它们将播放它们曾经发出的声音。

总而言之:

  • 我读了一个csv文件并将内容保存为字符串[]
  • 我浏览字符串[]并实例化一个tile-prefab并将其精灵设置为文件夹中的图像,例如名字&#34; mother.png&#34;并将其音频切换到名为&#34; mother.wav&#34;
  • 的剪辑

现在我需要为Android做同样的事情,但我无法弄清楚如何。我读了几百万个帖子,尝试了www和流式搜索,但它没有用,所以我想也许我做错了,我想问你们男孩和女孩们的帮助。 我不想发布错误的代码,因为这一切都让人感到困惑。

我希望你有足够的信息。如果有些事情尚不清楚,请随时询问。

非常感谢!

最佳, 尼娜

对一个示例级别的所有图像的位置进行Screeshot: location of sprites/sounds for the level words_easy_MN

all files within the mentioned directory

Example how it should look like later on Android

参见示例:中间有两个图块。在读取来自letters.txt和M.csv的内容之后,算法将右侧图块的声音设置为&#34; M&#34;和左边的一个&#34; blume&#34; (列表中的一个例子)。正确的图块也可以获得&#34; blume&#34; (=一朵花)。

我已经拥有该文件夹中的所有内容。我需要磁贴从列表中自动实例化。

1 个答案:

答案 0 :(得分:0)

您需要重新编写代码。几乎所有人。不幸的是,我不能在这个答案中为你做那个,但会解释什么是错的,以及如何解决它们。

Resources文件夹很特殊,无法使用File.XXX函数访问。 Resources.Load函数是专门用于此的API。 这是从Resources文件夹中读取的唯一方法。

如屏幕截图所示,您要阅读的文件来自"Resources/levels/words_diff_MN/"文件夹文件夹。

假设您要从路径中的"Resources/levels/words_diff_MN/"路径删除“资源”中加载“letters.txt”文件。同时删除文件扩展名。读取的最终路径是levels/words_diff_MN/letters"

Resources.LoadTextAsset用于加载文本文件:

"Resources/levels/words_diff_MN/"路径加载“letters.txt”文件:

TextAsset txtAsset = (TextAsset)Resources.Load("levels/words_diff_MN/letters")", typeof(TextAsset));
string textFile = txtAsset.text;

加载 M.mp3 / ogg 声音文件:

AudioClip audio = Resources.Load("levels/words_diff_MN/M", typeof(AudioClip)) as AudioClip;

加载 blume 图像文件:

Sprite sprite = Resources.Load("levels/words_diff_MN/blume", typeof(Sprite)) as Sprite;

如果将blume图像标记为多精灵,则将其加载为数组:

Sprite[] sprite = Resources.LoadAll<Sprite>("levels/words_diff_MN/blume") as Sprite[];

您可以找到其他文件类型here的完整示例列表。