- 最后登录
- 2019-12-25
- 注册时间
- 2012-8-24
- 阅读权限
- 90
- 积分
- 71088
- 纳金币
- 52336
- 精华
- 343
|
先简单说一下项目经历 文笔有限别见笑
项目一开始使用的是Unity4.6.1这个版本在进行开发,由于要在ios平台发布一个版本,公司准备购买unity llisences 当时决定买unity5的lisences。所以决定吧项目升级到Unity5版本,在升级的过程中遇到了各种的坑,各种问题网上基本找不大解决方案。最后只有自己一个个的填坑。最后终于可以发表版本了;但是当时的场景是没有进行资源分离打包的;
由于我们的项目使用了一个叫T4M 的插件 该插件不兼容Unity5 最后google各种外国网站 发现这个T4M插件好像停止对unity5的支持了。最后卡在这里了。
经过开会讨论最后决定吧项目还原到Unity4.6.1这个版本进行开发。折腾呀 说多了都是泪。。。。
最后发现Unity5里面确实优化了很多东西 渲染这块和烘焙这块 还有shader 最让人高兴的就是AssetBundle打包方式给集成到编辑器里面了;回到Unity4版本过后 自己就一直想模仿Unity5的
打包方式。最后终于实现了。
Unity4.6里面每个资源都有个Labels属性 这个我就当成了Unity5里面的inpector里面的assetbundle来使用了
如果想把两个资源打包一起就可以给他相同的labels
比如一个player 的prefab 依赖于材质A 材质A使用了shader
prefab的label设置为 player/player01
材质和贴图设置为相同的labels playermat
最后shader设置labels 为 custom/diffuseshader
打包就OK啦
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Collections.Generic;
using System.Text;
using System.IO;
public class AssetBundlesTest {
[MenuItem("Editor/AssetBundle/Export")]
static void Export(){
Object[] objs = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
foreach(Object obj in objs){
DependLink link = SelectDependencies(obj);
ExportByDependLink(link);
}
Debug.Log("Export Completed!");
AssetDatabase.Refresh();
}
[MenuItem("Editor/AssetBundle/CleanLabel")]
static void CleanLabel(){
Object[] objs = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
foreach (Object obj in objs){
AssetDatabase.ClearLabels(obj);
}
AssetDatabase.Refresh();
}
/*
*导出资源
*/
static void ExportByDependLink(DependLink link){
Export(link);
}
/*
*导出资源选项
*/
static BuildAssetBundleOptions vars = BuildAssetBundleOptions.CompleteAssets | BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.DeterministicAssetBundle;
/*
*递归导出
*/
static void Export(DependLink link){
BuildPipeline.PushAssetDependencies();
List<Object> objs = new List<Object>();
foreach(string asset in link.assets){
objs.Add(AssetDatabase.LoadAssetAtPath(asset,typeof(Object)));
}
// 如果没有目录就先创建
string path = Application.streamingAssetsPath +"/" + link.label + ".assetbundle";
int idx = path.LastIndexOf("/");
string filepath = path.Substring(0, idx);
if (!Directory.Exists(filepath)){
Directory.CreateDirectory(filepath);
}
BuildPipeline.BuildAssetBundle(null, objs.ToArray(), path, vars);
if(link.berefs != null && link.berefs.Count > 0){
foreach(DependLink dlink in link.berefs){
Export(dlink);
}
}
BuildPipeline.PopAssetDependencies();
}
/*
*查找资源
*/
static DependLink SelectDependencies(Object assetObject){
string[] labels = AssetDatabase.GetLabels(assetObject);
if (labels.Length == 0){// 没有标签不打包
return null;
}
// 最顶层
string rootlabel = labels[0].ToLower();
Dictionary<string, List<string>> labelDicts = new Dictionary<string, List<string>>();
AddAssetByLabel(rootlabel, AssetDatabase.GetAssetPath(assetObject), labelDicts);
// 依赖标签分类
string[] dependencies = AssetDatabase.GetDependencies(new string[] { AssetDatabase.GetAssetPath(assetObject)});// 找出依赖关系
if (dependencies.Length != 1){
foreach(string assetpath in dependencies){
Object asset = AssetDatabase.LoadAssetAtPath(assetpath, typeof(Object));
if (asset != assetObject){
string[] dlabels = AssetDatabase.GetLabels(asset);
if (dlabels.Length != 0){
AddAssetByLabel(dlabels[0].ToLower(), assetpath, labelDicts);
}else{
AddAssetByLabel(rootlabel, assetpath, labelDicts);
}
}
}
}
//Print(labelDicts);
// 确定依赖关系
Dictionary<string, List<string>> relationships = new Dictionary<string, List<string>>();
List<string> list;
Object temp;
string[] templabels;
string templab;
foreach (string label in labelDicts.Keys){
list = labelDicts[label];
foreach(string asset in list){
string[] deps = AssetDatabase.GetDependencies(new string[] {asset});
if (deps.Length > 1){// 有依赖
foreach(string dep in deps){
if (!dep.Equals(asset)){// 排除自己
temp = AssetDatabase.LoadAssetAtPath(dep,typeof(Object));
templabels = AssetDatabase.GetLabels(temp);
templab = templabels[0].ToLower();
if (!templab.Equals(label)){// 不能自己依赖自己
AddAssetByLabel(label, templab, relationships);
}
}
}
}
}
}
Print(relationships);
// Test
/*relationships.Clear();
AddAssetByLabel("A", "B", relationships);
AddAssetByLabel("A", "C", relationships);
AddAssetByLabel("A", "D", relationships);
AddAssetByLabel("B", "C", relationships);
AddAssetByLabel("C", "D", relationships);*/
// 过滤重复关系
List<string> repeates = new List<string>();
foreach (string label in relationships.Keys){
List<string> deps = relationships[label];
foreach(string dept2 in deps){
bool b = IsRepeated(dept2,relationships,deps);
Debug.Log("dept2:"+dept2+","+b);
if(b){
repeates.Add(dept2);
}
}
if (repeates.Count > 0){
foreach(string del in repeates){
deps.Remove(del);
}
repeates.Clear();
}
}
Print(relationships);
// Link
List<string> refs;
Dictionary<string, DependLink> berefsDict = new Dictionary<string, DependLink>();
List<DependLink> links;
DependLink dependLink;
List<string> assets;
foreach (string label in labelDicts.Keys){// fill
assets = labelDicts[label];
AddLink(label, assets.ToArray(), null, berefsDict);
}
foreach (string label in labelDicts.Keys){// fill
refs = FindBeRef(label, relationships);
if(refs.Count > 0){// 资源被引用过
dependLink = berefsDict[label];
links = new List<DependLink>();
foreach(string beref in refs){
links.Add(berefsDict[beref]);
}
dependLink.berefs = links;
}
}
// Find
DependLink headLink = FindNoneDepend(labelDicts, relationships, berefsDict);
return headLink;
}
static void AddLink(string label, string[] assets, List<DependLink> refs, Dictionary<string, DependLink> berefsDict){
DependLink dependLink;
berefsDict.TryGetValue(label, out dependLink);
if (dependLink == null){
dependLink = new DependLink(label, assets, refs);
berefsDict.Add(label, dependLink);
}
}
/*
*添加资源
*/
static void AddAssetByLabel(string label, string asset, Dictionary<string, List<string>> labelDicts){
List<string> list = null;
labelDicts.TryGetValue(label, out list);
if (list == null){
list = new List<string>();
labelDicts.Add(label, list);
}
if (!list.Contains(asset)){
list.Add(asset);
}
}
/*
*打印
*/
static void Print(Dictionary<string, List<string>> labelDicts){
foreach(string key in labelDicts.Keys){
Debug.Log("Label:"+key);
List<string> list = labelDicts[key];
foreach(string asset in list){
Debug.Log(asset);
}
}
}
/*
*查找被引用关系
*/
static List<string> FindBeRef(string label,Dictionary<string, List<string>> relationships){
List<string> refs = new List<string>();
List<string> temp;
foreach (string key in relationships.Keys){
temp = relationships[key];
if(temp.Contains(label)){
refs.Add(key);
}
}
return refs;
}
/*
*查找头
*/
static DependLink FindNoneDepend(Dictionary<string, List<string>> labelDicts, Dictionary<string, List<string>> relationships, Dictionary<string, DependLink> berefsDict){
DependLink dependLink = null;
foreach (string key in labelDicts.Keys){
if (!relationships.ContainsKey(key)){
dependLink = berefsDict[key];
}
}
return dependLink;
}
static bool IsRepeated(string label, Dictionary<string, List<string>> relationships, List<string> list){
foreach (string lb in list){
List<string> tempList = null;
relationships.TryGetValue(lb, out tempList);
if (tempList != null){
if (tempList.Contains(label)){
return true;
}else{
bool b = IsRepeated(label, relationships,tempList);
if(b){
return true;
}
}
}
}
return false;
}
}
数据结构类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
/*
*依赖关系链表
*/
class DependLink
{
public List<DependLink> berefs;
public string label;// 标签
public string[] assets;// 当前资源
public string mainAsset;// 只有一个资源情况
public DependLink(string label, string[] assets, List<DependLink> berefs){
this.label = label;
this.assets = assets;
this.berefs = berefs;
}
}
|
|