我正在使用 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);
}
}
}
您附加
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
。