unity3d开发2d游戏中Assetbundle有啥作用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity3d开发2d游戏中Assetbundle有啥作用相关的知识,希望对你有一定的参考价值。
在unity3d开发2d游戏中,Assetbundle 是Unity Pro提供提供的功能,它可以把多个游戏对象或者资源二进制文件封装到Assetbundle中,提供了封装与解包的方法使用起来很便利。在如下几个方面的作用明显:1.预设
Assetbundle可以将Prefab封装起来,这是多么方便啊! 而且我也强烈建议大家将Prefab封装成Assetbundle,因为Prefab可以将游戏对象身上带的游戏游戏组件、游戏脚本、材质都封装在一起。当从服务器上将Assetbundle下载以后直接Instantiate就可以放入游戏中。
试想一下,如果只能将原始的二进制资源文件放在服务器上下载,当资源文件下载完毕后,需要动态的创建游戏对象、然后动态的将脚本绑定在游戏对象、动态的将贴图赋予游戏对象等等各种动态的操作。。所以强烈建议使用Prefa,不解释!!!!!
另外,我在举个例子,因为模型有可能会带很多动画文件,那么这样一组模型资源就可能是多个FBX 文件 和 若干png贴图文件 材质文件。这时我只需要把原始模型放入Prefab中,它就会包含这个模型的所有组件、甚至包括它的动画资源、贴图。那么如下图所示,Mode就是模型的Prefab文件,那么我仅仅只需要把Mode这个预设打包成Assetbundle即可。 当我在服务器上下载这个Assetbundle并且载入游戏中就可以直接使用了,切换动画、换贴图都可以。。
2.二进制文件
也并不是Assetbundle中全都要用预设,Assetbundle它也可以将二进制文件直接封装在里面,比如图片、声音、文本信息等等。
3.场景文件
在Unity中可以将一个场景保存在Scene中,Scene就会包含这个场景中的所有,那能不能把Scene也封装成Assetbundle中?答案是能,但是它不能在移动平台上用,因为移动平台上是不能更新脚本的,换句话来说就是即使将脚本绑定在Prefab中,然后下载Assetbundle后,所有脚本是不会执行的,后面说另外一种巧妙用法。
4.移动平台
上面MOMO已经将Assetbundle 的使用原理大致介绍了一下 ,我们在谈谈移动平台。脚本不能更新是移动平台下最大的伤,这就意味着开发者无法绕过App store和 google Play这种在线商店升级应用程序。唯一能做到的就是更新资源、举个例子,游戏中在处理版本升级时,一般会有个大版本号和一个小版本号,大版本号就是 2.0、3.0这种 版本需要在AppStore中更新,大版本主要是升级游戏脚本,然后当小版本号,比如2.0.1 或2.0.2这种只是更新游戏中的资源,通过自己游戏的服务器就可以完成,通过Assetbundle在自己服务器上下载,然后适应在游戏中。如果非要更新脚本,或不得不更新脚本那么只能在Appstore或者google Play去更新大版本。
移动平台上不能更新脚本,那么Prefab上绑定的脚本怎么办?在任何平台上都可以把脚本添加到Prefab上,然后打包成Assetbundle,只有移动平台上有点特殊,比如将Test.cs这条脚本绑定在Prefab中,最后程序通过服务器下载这个Assetbundle ,当载入工程中这条脚本是不会被执行的。
但是如果本地工程有Test.cs这条脚本,那么Unity会自动将这条脚本绑定在下载的Prefab中,并且他们执行的非常好。如果本地工程中没有Test.cs这条脚本,那么Prefab上的脚本是永远都不会执行的。有时我们会在脚本中写一些Public的变量,有可能不同的Prefab上绑定的是相同的脚本,只是Inspector 脚本中的public参数不同。别担心这一点Assetbundle 中的Prefab也是没问题,所以说只要大版本中的脚本没问题,在小版本中只更新游戏资源是一点问题都么有的。
5.移动优化
之前我们说过可以将游戏中的某个游戏对象封装成Assetbundle,也可以将游戏中的整个场景也封装成Assetbundle。但是我认为需要巧妙的使用封装场景,因为场景中肯定有很多公用的模型,如果打包场景的话那么内存与size就是 公用模型的size * N个场景,想想其实挺恐怖的。其实我们可以巧妙的使用,首先把场景中公用的部分和私有的部分统统放入Unity, 然后烘培整个场景。 当场景烘培完毕后把公用的模型部分在拿出去,场景只只保留私有的模型。还可以做一个工具将公用模型在场景中的坐标保存在XML中(每个场景文件会对应一个公用模型的XML信息),最后在将公用的模型分别封装在别的Assetbundle中。
服务器上提供每个场景的Assetbundle ,和公用模型的Assetbundle,一般公用模型的Assetbundle可以放在常驻内存中(可能使用频繁、根据项目的不同而定)场景Assetbundle下载完毕后,现载入场景然后在根据场景对应的XML信息将公用模型部分动态的在添加到场景中,这样就完成了一个场景的构建。 参考技术A 打包成Assetbundle的资源,可以输出windows,iphone,Androd等模式。
unity系统模块开发Unity5.5.2UI打包AssetBundle
之前已经有几篇文章写打包AssetBundle,但毕竟没有实际在项目中写过都写的比较浅。刚好最近项目更新Unity5.5.2就顺便由我来更新ui打包流程
这里就把这次的经验写一下
这里还是稍微解释一下打包的基本目的:
打包ui就是把你做的界面打包出来成assetbundle包,讲道理你就把每个界面打成bundle包在游戏中你就可以直接加载来用,但是这样子的话你的每个bundle包就会非常的大,为什么呢,是因为这样子每个界面的bundle包里都包含这个界面用到的字体,贴图atlas,texture,shader还可以有你自己使用的动态组件。
这样子你的同一份资源都复制了很多份出来。
当然不能这样子做
所以我们就需要把这些atlas,font给剥离开来独立打包
不过新的打包方式让我们不用再手动剥离开来这些东西,也就是没有了剥离之后要重新引用的烦恼。
所要做的事就是把需要打包的东西改一改它的AssetBudnle名再一起build就好了
总的来说,就是把一个ui界面的下的atlas,font,texture,component记录下来,
通过修改这个ui.prefab,atlas,font,texture,compoent的预制件的bundle名,最后调一下打包函数就可以了
(有的项目texutre和shader是有自己写的管理类来加载,需要把引用置空的,这时候就需要实例ui.prefab,并把引用赋空,拷贝一份到另外一个文件夹中)
上一篇ui打包文章
http://blog.csdn.net/chrisfxs/article/details/55046339
而这次的流程是
1.清理数据,建立文件夹
2.遍历所有文件夹下的ui界面prefab
3.遍历所有prefab下的compoent(动态组件)
4.找出所有的资源(如atlas,font)用个list记录下来
5.修改这些资源和这个ui.prefab的assetbundle名
6.build
补充一点!
游戏加载assetbundle的时候要先加载atlas,font这些资源,最后加载ui资源
这样才能保证引用没有丢失
下面是代码
//#if UNITY_5_MODE
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using UnityEditor.SceneManagement;
using UnityEngine.SceneManagement;
using System.IO;
public class BuildAssetbundle
{
public static string m_destFileName = "Assetbundle";
#if UNITY_ANDROID
public static string PlatformExtension = ".android";
public static string Extension = ".x.android";
public static BuildTarget Target = BuildTarget.Android;
public static string ASSETBUNDLE_PATH = Application.dataPath + "/../AndroidResources/StreamingAssets";
public static string FULL_ASSETBUNDLE_PATH = ASSETBUNDLE_PATH + "/" + m_destFileName;
#elif UNITY_IOS
public static string PlatformExtension = ".ios";
public static string Extension = ".x.ios";
public static BuildTarget Target = BuildTarget.iOS;
public static string ASSETBUNDLE_PATH = Application.dataPath + "/../IosResources/StreamingAssets";
#endif
#if BUILD_UI
//需要打包的资源
public static List<UIFont> fontList = new List<UIFont>();
public static List<UIAtlas> atlasList = new List<UIAtlas>();
public static List<GameObject> componentList = new List<GameObject>();
public static List<GameObject> panelList = new List<GameObject>();
public static void BuildOnePanel()
{
ClearAllBundleName();
CleanTempData();
GameObject[] selectGameObjects = Selection.gameObjects;
UnityEngine.Object selectFloder = Selection.activeObject;
if (selectGameObjects != null && selectGameObjects.Length != 0)
{
foreach (GameObject selGb in selectGameObjects)
{
string selGbPath = AssetDatabase.GetAssetPath(selGb);
if (selGbPath.StartsWith(BuildUtils.PANEL_ASSET_PATH))
{
if (selGbPath.EndsWith(BuildUtils.PREFAB_SUFFIX))
{
GameObject uiInstance = PrefabUtility.InstantiatePrefab(selGb) as GameObject;
CheckComponent(uiInstance);
FindRefrence(uiInstance.transform);
string prefabPath = BuildUtils.TEMP_PANEL_PREFAB_PATH + "/" + uiInstance.name + BuildUtils.PREFAB_SUFFIX;
PrefabUtility.CreatePrefab(prefabPath, uiInstance);
GameObject prefabAsset = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject;
panelList.Add(prefabAsset);
UnityEngine.Object.DestroyImmediate(uiInstance);
}
else
{
Debug.LogWarning("选择的资源 " + selGb.name + " 不是界面Prefab!");
}
}
else
{
Debug.LogWarning("只能打包放在 " + BuildUtils.PANEL_ASSET_PATH + " 下面的界面Prefab");
}
}
StartBuildGameObjects();
BuildUtils.DeleteFileWithSuffixs(ASSETBUNDLE_PATH, new string[]{".manifest",""}, true, false);
ShowBundleFolder();
EditorUtility.DisplayDialog("提示", "打包完成!", "确定");
}
else
{
Debug.LogWarning("只能对 " + BuildUtils.PANEL_ASSET_PATH + " 下面的UI使用!");
}
}
public static void BuildAllPanel(bool hint)
{
ClearAllBundleName();
if (!hint || EditorUtility.DisplayDialog("提示", "确定打包 " + BuildUtils.PANEL_ASSET_PATH + " 下所有界面?", "确定", "取消"))
{
CleanTempData();
string[] files = Directory.GetFiles(BuildUtils.PANEL_ASSET_PATH);
if (files.Length != 0)
{
foreach (string file in files)
{
if (file.EndsWith(BuildUtils.PREFAB_SUFFIX))
{
GameObject uiInstance = PrefabUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(file)) as GameObject;
string ui_panel_prefab_name = Path.GetFileNameWithoutExtension(file);
CheckComponent(uiInstance);
FindRefrence(uiInstance.transform);
string prefabPath = BuildUtils.TEMP_PANEL_PREFAB_PATH + "/" + uiInstance.name + BuildUtils.PREFAB_SUFFIX;
PrefabUtility.CreatePrefab(prefabPath, uiInstance);
GameObject prefabAsset = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject;
panelList.Add(prefabAsset);
UnityEngine.Object.DestroyImmediate(uiInstance);
}
}
StartBuildGameObjects();
BuildUtils.DeleteFileWithSuffixs(ASSETBUNDLE_PATH, new string[]{".manifest",""}, true, false);
}
if (hint)
{
ShowBundleFolder();
EditorUtility.DisplayDialog("提示", BuildUtils.PANEL_ASSET_PATH + " 下的界面界面全部打包完成!", "确定");
}
}
}
/// <summary>
/// 对每一个要打包的Prefab保存组件信息,找出Atlas、Font等//
/// </summary>
/// <param name="com">COM.</param>
static void FindRefrence(Transform com)
{
PrefabHierarchyInfo info = com.gameObject.AddComponent<PrefabHierarchyInfo>();
info.transforms = com.gameObject.GetComponentsInChildren<Transform>(true);
info.myuianchors = com.gameObject.GetComponentsInChildren<MyUIAnchor>(true);
UILabel[] uilabels = com.gameObject.GetComponentsInChildren<UILabel>(true);
UISprite[] uisprites = com.gameObject.GetComponentsInChildren<UISprite>(true);
UITexture[] uitextures = com.gameObject.GetComponentsInChildren<UITexture>(true);
foreach (UILabel lab in uilabels)
{
UIFont font = lab.bitmapFont;
if (font == null)
{
Debug.LogWarning(com.gameObject.name + " 下出现未使用UIFont或者没有知道字体的UIlabel, " + lab.gameObject.name);
continue;
}
string uifontPath = AssetDatabase.GetAssetPath(font);
if (!uifontPath.StartsWith(BuildUtils.UIFONT_PREFAB_PATH))
Debug.LogWarning("使用了没有放在" + BuildUtils.UIFONT_PREFAB_PATH + " 目录下的UIFont:" + uifontPath);
if (!fontList.Contains(font))
{
fontList.Add(font);
}
lab.text = "";
}
foreach (UISprite sp in uisprites)
{
UIAtlas atlas = sp.atlas;
if (atlas == null)
continue;
string atlasPath = AssetDatabase.GetAssetPath(atlas);
if (!atlasPath.StartsWith(BuildUtils.ATLAS_PREFAB_PATH))
Debug.LogWarning("使用了未放在" + BuildUtils.ATLAS_PREFAB_PATH + "目录下的Atlas:" + atlasPath);
sp.RecordAtlasName = atlas.name;
if (!atlasList.Contains(atlas))
atlasList.Add(atlas);
}
foreach (UITexture t in uitextures)
{
t.mainTexture = null;
t.shader = null;
}
com.parent = null;
}
/// <summary>
/// 对找出的需要打包资源打包//
/// </summary>
private static void StartBuildGameObjects()
{
EditorUtility.UnloadUnusedAssetsImmediate();
AssetbundleCommonFun.SetAssetBundlesName<UIFont>(fontList, Extension, false);
AssetbundleCommonFun.SetAssetBundlesName<UIAtlas>(atlasList, Extension, false);
AssetbundleCommonFun.SetAssetBundlesName<GameObject>(componentList, Extension, false);
AssetbundleCommonFun.SetAssetBundlesName<GameObject>(panelList, Extension, false);
AssetDatabase.Refresh();
BuildAll();
CleanTempData();
ClearAllBundleName();
}
//在一次打包过程中,出现过的Component,检测多个Panel里面的(DynamicComponent)重名//
static List<string> componentNames = new List<string>();
//支持无限深度的Component嵌套
static void CheckComponent(GameObject go)
{
string prefabPath = "";
Dictionary<uint, List<Transform>> allComponent = new Dictionary<uint, List<Transform>>();
FindComponents(go.transform, 0, ref allComponent);
uint[] indexs = new uint[allComponent.Keys.Count];
allComponent.Keys.CopyTo(indexs, 0);
System.Array.Sort(indexs);
for (int i = indexs.Length - 1; i >= 0; i--)
{
foreach (Transform com in allComponent[indexs[i]])
{
FindRefrence(com);
prefabPath = BuildUtils.TEMP_COMPONENT_PREFAB_PATH + "/" + com.name + BuildUtils.PREFAB_SUFFIX;
PrefabUtility.CreatePrefab(prefabPath, com.gameObject);
GameObject prefabAsset = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject;
componentList.Add(prefabAsset);
}
}
for (int i = indexs.Length - 1; i >= 0; i--)
{
foreach (Transform com in allComponent[indexs[i]])
{
UnityEngine.Object.DestroyImmediate(com.gameObject);
}
}
}
/// <summary>
/// 递归寻找动态组件//
/// </summary>
/// <param name="tf">Tf.</param>
/// <param name="index">Index.</param>
/// <param name="dict">Dict.</param>
static void FindComponents(Transform tf, uint index, ref Dictionary<uint, List<Transform>> dict)
{
if (tf.name.Contains("(DynamicComponent)"))
{
foreach (Transform sonTf in tf)
{
if (componentNames.Contains(sonTf.name))
{
UnityEngine.Debug.LogError(tf.name + " 子物体中出现同名的动态组件 " + sonTf.name);
UnityEngine.Object.DestroyImmediate(sonTf);
continue;
}
if (!sonTf.name.Contains("(DynamicComponent)"))
{
componentNames.Add(sonTf.name);
if (!dict.ContainsKey(index))
dict.Add(index, new List<Transform>());
dict[index].Add(sonTf);
if (sonTf.childCount > 0)
FindComponents(sonTf, index + 1, ref dict);
}
else
{
if (sonTf.childCount > 0)
FindComponents(sonTf, index + 1, ref dict);
}
}
}
else {
foreach (Transform sonTf in tf)
{
if (sonTf.childCount > 0)
FindComponents(sonTf, index + 1, ref dict);
}
}
}
static void CleanTempData()
{
fontList.Clear();
atlasList.Clear();
componentList.Clear();
componentNames.Clear();
}
#endif
#region tools
static void BuildAll()
{
EditorUtility.ClearProgressBar();
AssetbundleCommonFun.CreatePath(ASSETBUNDLE_PATH + "/Assetbundle");
BuildPipeline.BuildAssetBundles(ASSETBUNDLE_PATH + "/Assetbundle", BuildAssetBundleOptions.ChunkBasedCompression, Target);
}
//[MenuItem("[AssetBundles]/Build Bundles Independent")]
static void BuildBundlesIndependent()
{
List<Object> list = new List<Object>();
list.AddRange(Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets));
int count = list.Count;
string temp_path;
List<string> pathList = new List<string>();
foreach (Object o in list)
{
if (o == null)
{
continue;
}
AssetbundleCommonFun.ChangeTextureFormat(o);
temp_path = AssetDatabase.GetAssetPath(o);
if (!pathList.Contains(temp_path))
{
pathList.Add(temp_path);
}
}
BuildIndependent(pathList);
}
static void BuildIndependent(List<string> pathList)
{
string OutPutFolder = ASSETBUNDLE_PATH + "/Assetbundle";
AssetbundleCommonFun.CreatePath(OutPutFolder);
AssetBundleBuild temp_build;
List<AssetBundleBuild> abbs = new List<AssetBundleBuild>();
int count = pathList.Count;
int index = 0;
foreach (string item in pathList)
{
if (item == null)
{
index++;
continue;
}
EditorUtility.DisplayProgressBar("Build Bundles Independent", item, (float)index / (float)count);
if (!string.IsNullOrEmpty(item))
{
temp_build = new AssetBundleBuild();
temp_build.assetBundleName = AssetbundleCommonFun.GetBundleName(item, Extension);
temp_build.assetNames = new string[] { item };
abbs.Add(temp_build);
}
index++;
}
BuildPipeline.BuildAssetBundles(OutPutFolder, abbs.ToArray(), BuildAssetBundleOptions.ChunkBasedCompression, Target);
string mainConfigPath = OutPutFolder + "/" + Path.GetFileName(OutPutFolder);
if (File.Exists(mainConfigPath))
{
File.Delete(mainConfigPath);
}
AssetbundleCommonFun.ExportModifyFilesInfo(ASSETBUNDLE_PATH + "/Assetbundle");
EditorUtility.ClearProgressBar();
EditorUtility.DisplayDialog("提示", "操作结束", "OK");
}
//[@MenuItem("[AssetBundles]/Set Name for self")] 此功能不开放
static void SetNameForSelf()
{
List<Object> list = new List<Object>();
list.AddRange(Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets));
int count = list.Count;
int index = 0;
foreach (Object o in list)
{
if (o == null)
{
index++;
continue;
}
string path = AssetDatabase.GetAssetPath(o);
AssetbundleCommonFun.SetBundleName(path, Extension);
index++;
EditorUtility.DisplayProgressBar("Set Assetbundle Name", path, (float)index / (float)count);
}
EditorUtility.ClearProgressBar();
EditorUtility.DisplayDialog("提示", "操作结束", "OK");
}
//[@MenuItem("[AssetBundles]/Set Assetbundle Name")] 此功能不开放
static void SetName()
{
List<Object> list = new List<Object>();
list.AddRange(Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets));
int count = list.Count;
int index = 0;
foreach (Object o in list)
{
if (o == null)
{
index++;
continue;
}
string path = AssetDatabase.GetAssetPath(o);
AssetbundleCommonFun.SetBundleName(path, Extension);
index++;
EditorUtility.DisplayProgressBar("Set Assetbundle Name", path, (float)index / (float)count);
}
EditorUtility.ClearProgressBar();
//EditorUtility.DisplayDialog("提示", "操作结束", "OK");
}
//[@MenuItem("[AssetBundles]/Clear Selected AssetbundleName")]
static void ClearName()
{
List<Object> list = new List<Object>();
list.AddRange(Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets));
int count = list.Count;
int index = 0;
foreach (Object o in list)
{
if (o == null)
{
index++;
continue;
}
string path = AssetDatabase.GetAssetPath(o);
AssetbundleCommonFun.SetBundleName(path, "", true);
//AssetbundleCommonFun.SetDependenciesName(path, "", false, true);
index++;
EditorUtility.DisplayProgressBar("Clear Assetbundle Name", path, (float)index / (float)count);
}
EditorUtility.ClearProgressBar();
//EditorUtility.DisplayDialog("提示", "操作结束", "OK");
}
//[@MenuItem("[AssetBundles]/Clear All AssetbundleNames")]
static void ClearAllBundleName()
{
string[] allBundleNames = AssetDatabase.GetAllAssetBundleNames();
List<string> hasBundleNameAssets = new List<string>();
foreach (string n in allBundleNames)
{
foreach (string p in AssetDatabase.GetAssetPathsFromAssetBundle(n))
{
hasBundleNameAssets.Add(p);
}
}
float idx = 0f;
foreach (string asset in hasBundleNameAssets)
{
AssetbundleCommonFun.SetBundleName(asset, "", true);
EditorUtility.DisplayProgressBar("清除所有Bundle名称", "当前处理文件:" + Path.GetFileName(asset), idx++ / hasBundleNameAssets.Count);
}
EditorUtility.ClearProgressBar();
AssetDatabase.RemoveUnusedAssetBundleNames();
AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
//EditorUtility.DisplayDialog("提示", "操作结束", "OK");
}
/// <summary>
/// 显示Bundle文件夹//
/// </summary>
static void ShowBundleFolder()
{
string path = FULL_ASSETBUNDLE_PATH +"/assets";
path = path.Replace("/", "\\");
Debug.Log(path);
System.Diagnostics.Process.Start("explorer.exe", "/select," + path);
}
#endregion
}
//#endif
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Collections.Generic;
using System.Text;
public class AssetbundleCommonFun
{
#if UNITY_ANDROID
private static string strLocalFileName = "Android_LocalFilesInfo.asset";
#elif UNITY_IOS
private static string strLocalFileName = "Ios_LocalFilesInfo.asset";
#endif
private static List<string> componentList = new List<string>();
static AssetImporter m_importer = null;
public static void ClearAllBundleName()
{
string[] allBundleNames = AssetDatabase.GetAllAssetBundleNames();
List<string> hasBundleNameAssets = new List<string>();
foreach (string n in allBundleNames)
{
foreach (string p in AssetDatabase.GetAssetPathsFromAssetBundle(n))
{
hasBundleNameAssets.Add(p);
}
}
float idx = 0f;
foreach (string asset in hasBundleNameAssets)
{
SetBundleName(asset, "", false);
EditorUtility.DisplayProgressBar("清除所有Bundle名称", "当前处理文件:" + Path.GetFileName(asset), idx++ / hasBundleNameAssets.Count);
}
EditorUtility.ClearProgressBar();
AssetDatabase.RemoveUnusedAssetBundleNames();
AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
}
public static void CreatePath(string path)
{
string NewPath = path.Replace("\\", "/");
string[] strs = NewPath.Split(‘/‘);
string p = "";
for (int i = 0; i < strs.Length; ++i)
{
p += strs[i];
if (i != strs.Length - 1)
{
p += "/";
}
if (!Path.HasExtension(p))
{
if (!Directory.Exists(p))
Directory.CreateDirectory(p);
}
}
}
public static string SetBundleName(string path, string name, bool isForce = false)
{
if (!isForce)
{
if (Directory.Exists(path))
{
return null;
}
}
string dictName = Path.GetDirectoryName(path);
string fileName = Path.GetFileNameWithoutExtension(path);
string extension = Path.GetExtension(path);
dictName = dictName.Replace("UIResources_temp", "UIResources");
if (!isForce)
{
if (extension.Equals(".dll") || extension.Equals(".cs") || extension.Equals(".js") || (name != "" && fileName.Contains("atlas") && !extension.Equals(".prefab")))
{
return null;
}
}
m_importer = AssetImporter.GetAtPath(path);
if (name != "")
{
m_importer.assetBundleName = dictName + "/" + fileName + name;
}
else
{
m_importer.assetBundleName = "";
}
AssetDatabase.Refresh();
return m_importer.assetBundleName;
}
public static string GetBundleName(string path, string name, bool isForce = false)
{
string retBundleName = null;
if (!isForce)
{
if (Directory.Exists(path))
{
return retBundleName;
}
}
string dictName = Path.GetDirectoryName(path);
string fileName = Path.GetFileNameWithoutExtension(path);
string extension = Path.GetExtension(path);
if (!isForce)
{
if (extension.Equals(".dll") || extension.Equals(".cs") || extension.Equals(".js") || (name != "" && fileName.Contains("atlas") && !extension.Equals(".prefab")))
{
return null;
}
}
if (name != "")
{
retBundleName = dictName + "/" + fileName + name;
//Object tex = AssetDatabase.LoadAssetAtPath(path, typeof(Object));
//if (tex is Texture2D)
//{
// SetTexture(tex as Texture2D);
//}
}
Debug.Log("Asset name: " + fileName);
AssetDatabase.Refresh();
return retBundleName;
}
static void FindComponents(Transform tf, uint index, ref Dictionary<uint, List<Transform>> dict)
{
if (tf.name.Contains("(DynamicComponent)"))
{
foreach (Transform sonTf in tf)
{
if (componentList.Contains(sonTf.name))
{
Debug.LogWarning("same name component...");
UnityEngine.Object.DestroyImmediate(sonTf);
continue;
}
if (!sonTf.name.Contains("(DynamicComponent)"))
{
Debug.Log("找到组件" + sonTf.name + "深度" + index);
componentList.Add(sonTf.name);
if (!dict.ContainsKey(index))
dict.Add(index, new List<Transform>());
dict[index].Add(sonTf);
if (sonTf.childCount > 0)
FindComponents(sonTf, index + 1, ref dict);
}
else
{
if (sonTf.childCount > 0)
FindComponents(sonTf, index + 1, ref dict);
}
}
}
else
{
foreach (Transform sonTf in tf)
{
if (sonTf.childCount > 0)
FindComponents(sonTf, index + 1, ref dict);
}
}
}
public static void SetTexture(Texture2D tex)
{
string path = AssetDatabase.GetAssetPath(tex);
TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
if (importer != null)
{
if (!(importer.textureType == TextureImporterType.NormalMap || importer.normalmap))
importer.mipmapEnabled = false;
importer.npotScale = TextureImporterNPOTScale.ToNearest;
importer.textureType = TextureImporterType.Default;
importer.spriteImportMode = SpriteImportMode.None;
importer.isReadable = false;
if (path.Contains("_alpha8"))
{
importer.textureFormat = TextureImporterFormat.Alpha8;
}
else
{
importer.textureFormat = SetTextureFormat(tex, importer);
}
importer.maxTextureSize = 8192;
AssetDatabase.ImportAsset(path);
}
}
static TextureImporterFormat SetTextureFormat(Texture t, TextureImporter importer)
{
TextureImporterFormat TextureFormat;
#if UNITY_IPHONE
if (fun(t.width) && fun(t.height))
{
if (importer.DoesSourceTextureHaveAlpha())
{
TextureFormat = TextureImporterFormat.PVRTC_RGBA4;
}
else
{
TextureFormat = TextureImporterFormat.PVRTC_RGB4;
}
}
else
{
TextureFormat = TextureImporterFormat.ETC2_RGBA8;
}
#elif UNITY_ANDROID
if (fun(t.width) && fun(t.height))
{
if (importer.DoesSourceTextureHaveAlpha())
{
//importer.alphaIsTransparency = true;
TextureFormat = TextureImporterFormat.ETC2_RGBA8;
}
else
TextureFormat = TextureImporterFormat.ETC_RGB4;
}
else {
if (importer.DoesSourceTextureHaveAlpha())
{
//importer.alphaIsTransparency = true;
TextureFormat = TextureImporterFormat.RGBA16;
}
else
TextureFormat = TextureImporterFormat.RGB16;
Debug.LogWarning("Texture " + t.name + " 尺寸不为2的幂次方,无法使用ETC压缩,当前使用 " + TextureFormat.ToString());
}
#else
TextureFormat = TextureImporterFormat.RGBA32;
#endif
return TextureFormat;
}
static bool fun(int v)
{
bool flag = false;
if ((v > 0) && (v & (v - 1)) == 0)
flag = true;
return flag;
}
public static void ExportModifyFilesInfo(string path)
{
string extension = "";
string[] retFils = Directory.GetFiles(path, "*.manifest", SearchOption.AllDirectories);
//LocalFilesInfo filesInfo = ScriptableObject.CreateInstance<LocalFilesInfo>();
foreach (var item in retFils)
{
File.Delete(item);
}
}
private static void FileCopy(string sourceFileName, string destFileName)
{
string dictName = Path.GetDirectoryName(destFileName);
CreatePath(dictName);
File.Copy(sourceFileName, destFileName);
}
private static string GetMD5HashFromFile(string fileName)
{
try
{
FileStream file = new FileStream(fileName, FileMode.Open);
System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(file);
file.Close();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
catch (System.Exception ex)
{
throw new System.Exception("GetMD5HashFromFile() fail, error:" + ex.Message);
}
}
public static void ChangeTextureFormat(Object obj)
{
Object[] dependObjects;
dependObjects = EditorUtility.CollectDependencies(new Object[] { obj });
foreach (Object val in dependObjects)
{
if (val is Texture2D)
{
SetTexture(val as Texture2D);
}
}
AssetDatabase.Refresh();
}
public static void SetAssetBundlesName<T>(List<T> list, string Extension, bool needRefresh) where T : Object
{
for (int i = 0; i < list.Count; i++)
{
SetAssetBundleName(list[i], Extension, needRefresh);
}
}
public static void SetAssetBundleName<T>(T asset, string Extension, bool needRefresh) where T : Object
{
string path = AssetDatabase.GetAssetPath(asset);
SetBundleName(path, Extension, needRefresh);
}
}
以上是关于unity3d开发2d游戏中Assetbundle有啥作用的主要内容,如果未能解决你的问题,请参考以下文章