如何在元任务中访问应用程序数据文件?

问题描述 投票:0回答:1

我正在使用 Unity 制作游戏,在游戏中我正在解析 MIDI 文件并使用数据创建关卡。我的问题是它同时适用于 Unity 和 Windows 构建。然而,当我为任务构建时,它不起作用。

构建 Meta Quest 时路径是否有所不同?还是权限问题?

我访问它的方式是将所有 MIDI 文件放入“StreamingAssets”文件夹中,并尝试从那里访问它们。我的逻辑是读取 MIDI 文件的标题,将它们添加到游戏内的菜单中,当玩家按下其中一个时,它会读取它,并在按下播放时为它们创建关卡。

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
using UnityEngine.Android;  // For permission handling on Android
using UnityEngine.Networking; // For reading from StreamingAssets on Android

public class MidiFileLoader : MonoBehaviour
{
    public List<string> midiFilePaths = new List<string>(); // Store all MIDI file paths
    public GameObject buttonPrefab; // Assign a UI Button prefab with a Text component
    public Transform buttonContainer; // A parent object in the UI where buttons will be placed

    void Start()
    {
        // Request permission for external storage on Android
        if (Application.platform == RuntimePlatform.Android)
        {
            RequestStoragePermissions();
        }

        StartCoroutine(LoadMidiFiles()); // Use coroutine for loading MIDI files
    }

    // Coroutine to load MIDI files from StreamingAssets
    private IEnumerator LoadMidiFiles()
    {
        string midiFilesFolder = Path.Combine(Application.streamingAssetsPath, "MidiFiles");

        // Load files from "Piano" and "Drums" subfolders
        string pianoFolder = Path.Combine(midiFilesFolder, "Piano");
        string drumsFolder = Path.Combine(midiFilesFolder, "Drums");

        if (!MidiReader.instance.isDrums)
        {
            yield return StartCoroutine(LoadMidiFilesFromFolder(pianoFolder));
        }
        else
        {
            yield return StartCoroutine(LoadMidiFilesFromFolder(drumsFolder));
        }

        PopulateMenu();
    }

    // Coroutine to load MIDI files from a folder
    private IEnumerator LoadMidiFilesFromFolder(string folderPath)
    {
        // On Android, use UnityWebRequest to load files from StreamingAssets
        string url = Path.Combine(Application.streamingAssetsPath, folderPath);

        if (Application.platform == RuntimePlatform.Android)
        {
            UnityWebRequest request = UnityWebRequest.Get(url);
            yield return request.SendWebRequest();

            if (request.result == UnityWebRequest.Result.Success)
            {
                string[] filePaths = request.downloadHandler.text.Split('\n'); // Parse file paths
                foreach (string path in filePaths)
                {
                    if (path.EndsWith(".mid"))
                    {
                        midiFilePaths.Add(path);
                    }
                }
            }
            else
            {
                Debug.LogError("Failed to load files from: " + url);
            }
        }
        else
        {
            // For platforms other than Android, use standard file system access
            if (Directory.Exists(folderPath))
            {
                string[] files = Directory.GetFiles(folderPath, "*.mid");
                midiFilePaths.AddRange(files);
            }
        }
    }

    // This method will populate the menu with the MIDI file paths
    void PopulateMenu()
    {
        for (int i = 0; i < midiFilePaths.Count; i++)
        {
            string path = midiFilePaths[i];

            // Instantiate the button inside the buttonContainer
            GameObject newButton = Instantiate(buttonPrefab, buttonContainer);

            // Set the button text to the MIDI file name
            newButton.GetComponentInChildren<TMP_Text>().text = Path.GetFileNameWithoutExtension(path);

            // Add a listener to the button to load the selected file when clicked
            Button buttonComponent = newButton.GetComponent<Button>();
            buttonComponent.onClick.AddListener(() => 
            {
                Debug.Log("Button clicked for: " + path);
                MidiReader.instance.StartReading(path);
            });
        }
    }

    // Request external storage permissions on Android
    private void RequestStoragePermissions()
    {
        if (!Permission.HasUserAuthorizedPermission(Permission.ExternalStorageRead))
        {
            Permission.RequestUserPermission(Permission.ExternalStorageRead);
        }

        // Optional: Check for write permission if needed
        if (!Permission.HasUserAuthorizedPermission(Permission.ExternalStorageWrite))
        {
            Permission.RequestUserPermission(Permission.ExternalStorageWrite);
        }
    }
}
c# unity-game-engine virtual-reality oculusquest
1个回答
0
投票

您附加

Application.streamingAssetsPath
两次!

  • 一旦进入

    LoadMidiFiles

      string midiFilesFolder = Path.Combine(Application.streamingAssetsPath, "MidiFiles");
    
      // Load files from "Piano" and "Drums" subfolders
      string pianoFolder = Path.Combine(midiFilesFolder, "Piano");
      string drumsFolder = Path.Combine(midiFilesFolder, "Drums");
    
  • 然后出于某种原因再次在

    LoadMidiFilesFromFolder

     string url = Path.Combine(Application.streamingAssetsPath, folderPath);
    

此时的

folderPath
已经假装了
Application.streamingAssetsPath
,所以你可以使用它并完全摆脱
url

© www.soinside.com 2019 - 2024. All rights reserved.