Unity安卓Android从StreamingAssets加载AssetBundle

在安卓下无法获取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));
......

猜你喜欢

转载自blog.csdn.net/zouxin_88/article/details/146156716
今日推荐