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

Nin4ikP

编辑:由于它被标记为在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 Editor中,我只是通过获取场景所在的路径来做到这一点(我需要像这样,而不是在单独的场景文件夹中,因为我需要几个名称相同但内容不同的场景,并且整个场景必须由不知道如何使用统一性的人员进行编辑,因此我希望他们仅复制粘贴文件夹并替换内容,这样他们就不必弄乱代码甚至不必统一性)。

之后,我使用功能GetLettersFromFile来获取几个字母(将在整个过程中更改它,这就是为什么我需要它是动态的)。

然后,我有许多名称不同的场景,在那些名称为“ Words”或“ Container”的场景中,我在文件夹中有两个.csv文件,它们都带有精灵/声音的所有名称(同名) ,需要实例化。

例如,我可以插入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文件,并将内容另存为字符串[]
  • 我遍历string []并实例化tile-prefab,并将其精灵设置为名称为“ mother.png”的文件夹中的图像,并将其音频片段设置为名称为“ mother.wav”的剪辑

现在我需要为Android做同样的事情,但是我不知道怎么做。我读了大概一百万篇的文章,并尝试了www和streamingassests,但是它没有用,所以我认为也许我做错了,所以我想问问男女。我不想发布错误的代码,因为这一切都变得令人困惑。

希望您有足够的信息。如果尚不清楚,请随时问。

非常感谢你!

最好,妮娜

一个示例级别的所有图像的位置的快照:words_easy_MN级别的精灵/声音的位置

提及目录中的所有文件

示例稍后在Android上的外观

参见示例:中间有两个瓷砖。在从letters.txt和M.csv中读取内容之后,该算法将右图块的声音设置为“ M”,将左图块的声音设置为“ blume”(列表中的一个示例)。右边的图块还会获取“暗影”(=一朵花)的图像。

我已经有了文件夹中的所有内容。我需要图块以从列表中自动实例化。

程序员

您需要重新编写代码。几乎所有人。不幸的是,在这个答案中,我无法为您做到这一点,但会解释出什么问题以及如何解决。

Resources文件夹是特殊的,无法使用File.XXX功能进行访问Resources.Load函数是专用于此的特殊API。这是从“资源”文件夹读取的唯一方法。

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

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

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

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

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;

要加载虚拟图像文件:

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

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

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

您可以在此处找到其他文件类型的示例的完整列表

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章