Unity使用AssetImporter整理资源对其进行打包
- AssetImporter概述
- 打包思路
- 具体实现
- 资源配置
- 资源配置的信息
- 调用生成
- 打包
- 打包分类
- 按照单个文件打包
- 按照文件夹打包
- 打包Lua文件(特别的)
- 使用打包方法进行打包
- 打包调用
AssetImporter概述
AssetImporter.GetAtPath获取路径资源
static function GetAtPath (path : string) : AssetImporter
Description描述
Retrieves the asset importer for the asset at path.
通过资源路径 ,导入器重新获取资源。
简单的说,通过指定路径来导入资源。
该方法返回的是AssetImporter对象,我们通常给该对象的assetBundleName赋值为要打包的资源路径名称,这个操作实际上相当于在Unity编辑器Inspector页面中手动添加是一样的。
打包思路
这里我把要打包的所有资源统一放在同一个Res文件夹下面,Res中不同的资源类型,不同的加载时间的资源新建文件夹,按照文件夹分类(如:把通用的资源放在同一个文件夹下,UI统一放入一个文件夹,material建一个文件夹),打包时在打包配置里指定要打包的资源路径,打包类型(这里类型指的是:1.整个文件夹打一个包,2.将文件夹下单个资源都对应一个ab包)
具体实现
资源配置
[System.Serializable]
public class PackageItem
{
public enum PackType {File,DirFiles,Dir}
public PackType type;
public string path;
public string searchPattern = "*.*";
public SearchOption searchOption;
}
效果如下:
资源配置的信息
[System.Serializable]
public class PackageConfig : ScriptableObject {
private static PackageConfig _instance;
public static PackageConfig instance
{
get
{
_instance = AssetDatabase.LoadAssetAtPath<PackageConfig>("Assets/Tools/Editor/PackConf.asset");
if(_instance==null)
{
_instance = ScriptableObject.CreateInstance<PackageConfig>();
AssetDatabase.CreateAsset(_instance, "Assets/Tools/Editor/PackConf.asset");
}
return _instance;
}
}
//版本号
[SerializeField]
private string _version = "1.0";
public static string version { get { return instance._version; } }
//游戏名称
[SerializeField]
private string _appName = "Test";
public static string appName { get { return instance._appName; } }
//游戏发布的目录
[SerializeField]
private string _publishDir = "publish/";
public static string publishDir { get { return instance._publishDir; } }
//游戏web发布目录
[SerializeField]
private string _webPublishUrl = "http://192.168.1.27/publish/";
public static string webPulishUrl { get { return instance._webPublishUrl; } }
// 是否使用jit
[SerializeField]
private bool _luaJit = true;
public bool luaJit { get { return instance._luaJit; } }
// debugBuild
[SerializeField]
private bool _debugBuild = true;
public static bool debugBuild { get { return instance._debugBuild; } }
// 自动开启
[SerializeField]
private bool _autoRunPlayer = false;
public static bool autoRunPlayer { get { return instance._autoRunPlayer; } }
[SerializeField]
private List<PackageItem> _packItems = new List<PackageItem>();
public List<PackageItem> packItems { get { return instance._packItems; } }
public static BuildOptions buildOptions
{
get
{
if(debugBuild)
{
BuildOptions op = BuildOptions.AllowDebugging | BuildOptions.ConnectWithProfiler | BuildOptions.Development;
if(autoRunPlayer)
{
return op | BuildOptions.AutoRunPlayer;
}
return op;
}
else
{
return BuildOptions.None;
}
}
}
}
调用生成
// 各种配置文件
[MenuItem("BuildTool/依赖打包方式/发布设定")]
public static void open()
{
Selection.activeObject = PackageConfig.instance;
}
打包
打包分类
按照单个文件打包
直接指定文件所在路径
//文件打包
public bool PackFile(string res)
{
AssetImporter importer = AssetImporter.GetAtPath(res);
if (importer == null)
{
Debug.LogError("Path not Exist!" + res);
return false;
}
importer.assetBundleName = res + abExtens;
return true;
}
指定资源所在的文件夹路径,查找文件夹下的所有文件,每个文件单独一个AB包
//打包目录中所有资源
public bool PackDirFiles(string res,string pattern,SearchOption searchOption)
{
string[] files = GetDirFiles(res,pattern,searchOption);
if (files.Length == 0) return false;
foreach(var file in files)
{
PackFile(file);
}
return true;
}
按照文件夹打包
//目录打包
public bool PackDir(string res,string pattern,SearchOption searchOption)
{
string[] files = GetDirFiles(res, pattern, searchOption);
if (files.Length == 0) return false;
string fn = res.Trim('/') + abDirExtens;
foreach(var file in files)
{
AssetImporter impoter = AssetImporter.GetAtPath(file);
impoter.assetBundleName = fn;
}
return true;
}
//打包目录中所有资源
public bool PackDirDir(string res,string pattern)
{
string[] Dirs = Directory.GetDirectories(res);
if (Dirs.Length == 0) return false;
foreach(var d in Dirs)
{
PackDir(d.Replace('\\', '/'), pattern, SearchOption.AllDirectories);
}
return true;
}
打包Lua文件(特别的)
如果Lua需要使用Jit进行编译
//编译Lua到固定目录
public void CompileLuaJit(string []src,string[]dst)
{
Debug.Log("Start CompileLuaJit");
#if !UNITY_EDITOR_OSX
string workDir = Application.dataPath + "/../jit/";
Dictionary<BUILDLUATYPE, string> build = new Dictionary<BUILDLUATYPE, string>()
{
{ BUILDLUATYPE.WIN32,Application.dataPath+"/../jit/win/x86/luajit.exe"},
{ BUILDLUATYPE.WIN64,Application.dataPath+"/../jit/win/x64/luajit.exe"},
{ BUILDLUATYPE.GC64,Application.dataPath+"/../jit/win/gc64/luajit.exe"},
};
string exePath = build[buildLuaDict[_target]];
System.Diagnostics.Process[] psList = new System.Diagnostics.Process[src.Length];
#endif
for(int i=0;i<src.Length;i++)
{
string srcLua = Application.dataPath + "/../" + src[i];
string dstLua = Application.dataPath + "/../" + dst[i];
string cmd = " -b " + srcLua + " " + dstLua;
psList[i] = ProcessHelper.StartProcess(exePath,cmd,workDir);
}
#if !UNITY_EDITOR_OSX
foreach(var ps in psList)
{
if(ps!=null&&!ps.HasExited)
{
ps.WaitForExit();
}
}
#endif
}
编译的过程需要使用Process调起进程exe执行编译指令
public class ProcessHelper {
public static Process StartProcess(string command,string parm,string workDir="")
{
return StartProcess(command, parm, workDir, DataReceived, ErrorReceived);
}
public static Process StartProcess(string command, string parm, string workDir, DataReceivedEventHandler dataReceived, DataReceivedEventHandler errorReceive)
{
Process ps = new Process()
{
StartInfo =
{
FileName=command,
Arguments=parm,
CreateNoWindow=true,
UseShellExecute=false,
RedirectStandardOutput=true,
RedirectStandardError=true,
WorkingDirectory=workDir
}
};
ps.OutputDataReceived += DataReceived;
ps.ErrorDataReceived += ErrorReceived;
ps.Start();
ps.BeginOutputReadLine();
ps.BeginErrorReadLine();
return ps;
}
private static void DataReceived(object sender,DataReceivedEventArgs eventArgs)
{
if (null != eventArgs.Data) UnityEngine.Debug.Log(eventArgs.Data);
}
private static void ErrorReceived(object sender,DataReceivedEventArgs eventArgs)
{
if(null !=eventArgs.Data) UnityEngine.Debug.Log(eventArgs.Data);
}
}
打包lua到 "Assets/Res/Lua/"路径下
//打包Lua目录
public bool PackLuaDir(string res,bool useJit=true)
{
string fixLuaDIr = "Assets/Res/Lua/";
AssetDatabase.DeleteAsset(fixLuaDIr);
var files = Directory.GetFiles(res, "*.lua", SearchOption.AllDirectories);
var dests = new string[files.Length];
for(int i=0;i<files.Length;i++)
{
string file = files[i].Replace('\\', '/');
string dst = "Assets/Res/" + file;
string dstName = dst.Substring(0, dst.Length - 3) + "bytes"; //lua后缀改为bytes后缀
string destDir = Path.GetDirectoryName(dstName);
if(!Directory.Exists(destDir))
{
Directory.CreateDirectory(destDir);
}
files[i] = file;
dests[i] = dstName;
}
if(useJit)
{
CompileLuaJit(files,dests);
}
else
{
CompileLua(files,dests);
}
AssetDatabase.Refresh();
PackDir(fixLuaDIr,"*.bytes",SearchOption.AllDirectories);
return true;
}
使用打包方法进行打包
public AssetBundleManifest BuildAllAssetRes()
{
if (!Directory.Exists(_targetDir)) Directory.CreateDirectory(_targetDir);
return BuildPipeline.BuildAssetBundles(_targetDir, BuildAssetBundleOptions.None, _target);
}
打包调用
static void BuildAllResources(BuildTarget buildTarget)
{
Package pack = new Package(buildTarget);
try { Directory.Delete(pack.targetDir, true); } catch(Exception c) { UnityEngine.Debug.LogError(c.Message); }
foreach(var item in PackageConfig.instance.packItems)
{
if(item.type== PackageItem.PackType.File)
{
pack.PackFile(item.path);
}else if(item.type==PackageItem.PackType.DirFiles)
{
pack.PackDirFiles(item.path,item.searchPattern,item.searchOption);
}else if(item.type==PackageItem.PackType.Dir)
{
pack.PackDir(item.path,item.searchPattern,item.searchOption);
}
}
pack.PackLuaDir("lua/", PackageConfig.instance.luaJit);
AssetBundleManifest manifest = pack.BuildAllAssetRes();
}