在安卓下无法获取StreamingAssets目录下所有目录和文件名,所以需要提前将文件名整理成一个文件filelist.txt。
一、方法一使用批处理生成filelist.txt
1.用批处理命令将StreamingAssets下所有文件名输出到filelist.txt中
chcp 65001是使用UTF-8编码,否则中文是乱码。
@echo off
chcp 65001
dir /b /s /a-d > filelist.txt
2.将filelist.txt中绝对路径转换成相对路径
打开filelist.txt,去掉StreamingAssets
3.确何filelist.txt为UTF-8
二、方法二使用C#控制台程序自动生成filelist.txt
建立C#控制台工程,生成FileListConsole.exe。以下代码仅供参考,请根据实际情况修改。
class Program
{
static void Main(string[] args)
{
string rootPath = AppDomain.CurrentDomain.BaseDirectory;
//排除文件夹
List<string> excludeDirs = new List<string>();
excludeDirs.Add("StandaloneWindows");
List<string> dirs = Directory.GetDirectories(rootPath).ToList();
for (int i = 0; i < excludeDirs.Count(); i++)
{
dirs.RemoveAll(item => item.Contains(excludeDirs[i]));
}
List<string> files = new List<string>();
//根目录
List<string> rootFiles = GetFiles(rootPath, SearchOption.TopDirectoryOnly);
for (int i = 0; i < rootFiles.Count(); i++)
{
if(rootFiles[i].Contains("Config.ini") || rootFiles[i].Contains("LOGO.png"))
files.Add(rootFiles[i]);
}
//子目录
for (int i = 0; i < dirs.Count(); i++)
{
string childPath = Path.Combine(rootPath, dirs[i]);
List<string> childFiles = GetFiles(childPath, SearchOption.AllDirectories);
files.AddRange(childFiles);
}
string filePath = Path.Combine(rootPath, "filelist.txt");
using (StreamWriter writer = new StreamWriter(filePath, false))
{
for (int i = 0; i < files.Count(); i++)
{
string file = files[i].Substring(rootPath.Length);
writer.WriteLine(file);
}
}
Console.WriteLine(filePath);
}
static List<string> GetFiles(string path, SearchOption option)
{
List<string> files = new List<string>();
//根目录
files.AddRange(Directory.GetFiles(path,"*.*", option));
files.RemoveAll(item => item.EndsWith(".meta"));
return files;
}
}
在Unity中Assets\Editor文件夹下新建BuildProcessor.cs
using UnityEngine;
using System.Diagnostics;
using System.IO;
using UnityEditor.Build;
using UnityEditor;
public class BuildProcessor : IPreprocessBuild
{
int IOrderedCallback.callbackOrder{ get { return 0; } }
void IPreprocessBuild.OnPreprocessBuild(BuildTarget target, string path)
{
string fileListExe = Application.streamingAssetsPath+ "/FileListConsole.exe";
// 调用控制台程序的路径和参数
ProcessStartInfo startInfo = new ProcessStartInfo(fileListExe)
{
Arguments = Application.streamingAssetsPath,
CreateNoWindow = true, // 不显示窗口
UseShellExecute = false, // 不使用shell启动进程
RedirectStandardOutput = true, // 合并输出和错误流,便于读取
RedirectStandardError = true // 重定向错误输出流
};
using (Process process = Process.Start(startInfo))
{
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd(); // 读取输出结果(如果有)
UnityEngine.Debug.Log(result); // 在Unity控制台中打印输出结果
}
process.WaitForExit(); // 等待进程结束
}
}
}
这样在Build发布apk包时,自动执行 FileListConsole.exe,生成filelist.txt。不再需要手动处理。
扫描二维码关注公众号,回复:
17563043 查看本文章

三、针对Android平台打包AssetBundle
AssetBundle资源需要针对Android单独打包,与Windows的不通用。
打包完将资源复制到StreamingAssets下
ROBOCOPY Android ..\Assets\StreamingAssets\Android /E
四、复制StreamingAssets目录下所有文件到PersistentData
void Start () {
CopySteamingAssetsFileToPersistentDataPath();
}
void CopySteamingAssetsFileToPersistentDataPath()
{
string listFile = Path.Combine(Application.streamingAssetsPath, "filelist.txt");
WWW reader = new WWW(listFile);
while (!reader.isDone) { }
string textString = reader.text;
Debug.Log(textString.Length);
List<string> striparr = textString.Split(new string[] { "\r\n" }, StringSplitOptions.None).ToList();
List<string> lines = striparr.Where(s => !string.IsNullOrEmpty(s)).ToList();
for (int i = 0; i < lines.Count; i++)
{
string srcfile = Path.Combine(Application.streamingAssetsPath, lines[i]);
WWW reader1 = new WWW(srcfile);
while (!reader1.isDone) { }
string dstFile = Path.Combine(Application.persistentDataPath, lines[i]);
//安卓的路径只能是/,反斜杠\无效
dstFile = dstFile.Replace('\\','/');
string dir = Path.GetDirectoryName(dstFile);
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
Debug.Log(dstFile);
}
File.WriteAllBytes(dstFile, reader1.bytes);
}
}
五、加载AssetBundle
//存放AssetBundle的根目录名字
private static string rootFolder = "Android";
//本地资源路径
public string AbPath
{ get
{
string path =
#if UNITY_ANDROID && !UNITY_EDITOR
Application.persistentDataPath + "/";
#else
Application.streamingAssetsPath + "/";
#endif
return string.Format("{0}{1}/", path, rootFolder);
}
}
AssetBundle assetBundle = AssetBundle.LoadFromFile(string.Format("{0}{1}", AbPath, rootFolder));
......