文件夹中每个prefab,单独打包成一个assetbundle,使用于模型,单个UI面板
文件夹内每个文件夹打包成一个assetbundle,适用于图集
所有AB分发器配置数据在Editor/AssetBundle/Database/AssetPackage中,该目录下存在目录的一个映射结构,其中的每个序列化文件对应一个AB分发器
在打包前执行 make tag,通过读上面对应配置,自动设置ab标签与名字
public AssetBundleChecker(AssetBundleCheckerConfig config)
{
this.config = config;
assetsPath = AssetBundleUtility.PackagePathToAssetsPath(config.PackagePath);
importer = AssetBundleImporter.GetAtPath(assetsPath);
}
public void CheckAssetBundleName()
{
if (!importer.IsValid)
{
return;
}
var checkerFilters = config.CheckerFilters;
if (checkerFilters == null || checkerFilters.Count == 0)
{
importer.assetBundleName = assetsPath;
string[] bufName = importer.assetBundleName.Split('.');
MenuAssetBundle.m_abNameStr.AppendFormat("public const string {0} = \"{1}\";", bufName[0], bufName[0]);
MenuAssetBundle.m_abNameStr.AppendLine();
}
采用增量打包方式,只会打包改动的资源 BuildPipeline.BuildAssetBundles(info.outputDirectory, info.options, info.buildTarget); 调用该函数,unity会自动根据资源的标签进行打包,而且是增量打包,
打包完毕把md5信息写入
FileStream fs = new FileStream(newFilePath, FileMode.CreateNew);
StreamWriter sw = new StreamWriter(fs);
for (int i = 0; i < files.Count; i++)
{
string file = files[i];
//if (file.Contains("StreamingAssets")) continue;
string ext = Path.GetExtension(file);
if (file.EndsWith(".meta") || file.Contains(".DS_Store")) continue;
string md5 = NTG.Util.md5file(file);
string value = file.Replace(m_OutputPath + "/", string.Empty);
FileInfo fileInfo = new FileInfo(file);
int size = (int)(fileInfo.Length / 1024) + 1;
//if (value != "StreamingAssets" && value != "StreamingAssets.manifest")
sw.WriteLine(value + "|" + md5 + "|" + size);
}
sw.Close(); fs.Close();
方便查看一个ab包内具体包含哪些
黄色的是代表被多个ab包包含的资源
if (SimulateAssetBundleInEditor)
{
string[] assetPaths = AssetDatabase.GetAssetPathsFromAssetBundleAndAssetName(assetBundleName, assetName);
if (assetPaths.Length == 0)
{
Debug.LogError("There is no asset with name \"" + assetName + "\" in " + assetBundleName);
return null;
}
// @TODO: Now we only get the main object from the first asset. Should consider type also.
UnityEngine.Object target = AssetDatabase.LoadMainAssetAtPath(assetPaths[0]);
operation = new AssetBundleLoadAssetOperationSimulation (target);
}
static public AssetBundleLoadAssetOperation LoadAssetAsync (string assetBundleName, string assetName, System.Type type,string path = "")
{
Log(LogType.Info, "Loading " + assetName + " from " + assetBundleName + " bundle");
AssetBundleLoadAssetOperation operation = null;
{
assetBundleName = RemapVariantName (assetBundleName);
LoadAssetBundle (assetBundleName,false,path);
operation = new AssetBundleLoadAssetOperationFull (assetBundleName, assetName, type);
m_InProgressOperations.Add (operation);
}
return operation;
}
加载依赖项:
public abstract class AssetBundleLoadOperation : IEnumerator
{
public object Current
{
get
{
return null;
}
}
public bool MoveNext()
{
return !IsDone();
}
public void Reset()
{
}
abstract public bool Update ();
abstract public bool IsDone ();
}
string[] dependencies = m_AssetBundleManifest.GetAllDependencies(assetBundleName);
if (dependencies.Length == 0)
return;
for (int i=0;i<dependencies.Length;i++)
dependencies[i] = RemapVariantName (dependencies[i]);
// Record and load all dependencies.
m_Dependencies.Add(assetBundleName, dependencies);
for (int i=0;i<dependencies.Length;i++)
LoadAssetBundleInternal(dependencies[i], false,path);
static private AssetBundle LoadAssetBundleSync(string abname, string abPath = "")
{
AssetBundle bundle = null;
if (!m_LoadedAssetBundles.ContainsKey(abname))
{
//byte[] stream = null;
string uri;
if (abPath != "")
{
uri = abPath + "/" + abname;
}
else
{
uri = AppConst.AbDataPath + "/" + abname;
}
//Debug.Log("Loading AssetBundle: " + uri);
if (!File.Exists(uri))
{
Debug.LogError(String.Format("AssetBundle {0} Not Found", uri));
return null;
}
//stream = File.ReadAllBytes(uri);
bundle = AssetBundle.LoadFromFile(uri);
//stream = null;
LoadedAssetBundle loBundle = new LoadedAssetBundle(bundle);
m_LoadedAssetBundles.Add(abname, loBundle);
if (m_Dependencies != null && m_Dependencies.ContainsKey(abname))
{
for (int i = 0; i < m_Dependencies[abname].Length; i++)
{
LoadAssetBundleSync(m_Dependencies[abname][i]);
}
}
}
else
{
LoadedAssetBundle loBundle = null;
m_LoadedAssetBundles.TryGetValue(abname, out loBundle);
bundle = loBundle.m_AssetBundle;
}
return bundle;
}
LoadFromMemroy即使在PC平台也不如LoadFromFile接口,经测试,PC上LoadFromMemroy接口内存的占用大概会高1/5左右,加载时间比LoadFromFile接口慢1/5左右,而且如loy_liu所说的,LoadFromMemroy接口需要先读取byte[]数组,会导致mono内存的分配,而LoadFromFile不会。 在android平台上,内存的对比将会非常夸张,我这边测试的数据是翻了接近3倍。 所以千万别用LoadFromMemroy接口,LoadFromStream接口没有去测试它的性能和内存,据说和LoadFromFile差不多。