之前已经有几篇文章写打包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_ANDROIDpublic 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_IOSpublic 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 toolsstatic 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_ANDROIDprivate static string strLocalFileName = "Android_LocalFilesInfo.asset";
#elif UNITY_IOSprivate static string strLocalFileName = "Ios_LocalFilesInfo.asset";
#endifprivate 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_IPHONEif (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_ANDROIDif (fun(t.width) && fun(t.height)){if (importer.DoesSourceTextureHaveAlpha()){//importer.alphaIsTransparency = true;TextureFormat = TextureImporterFormat.ETC2_RGBA8;}elseTextureFormat = TextureImporterFormat.ETC_RGB4;}else {if (importer.DoesSourceTextureHaveAlpha()){//importer.alphaIsTransparency = true;TextureFormat = TextureImporterFormat.RGBA16;}elseTextureFormat = TextureImporterFormat.RGB16;Debug.LogWarning("Texture " + t.name + " 尺寸不为2的幂次方,无法使用ETC压缩,当前使用 " + TextureFormat.ToString());}
#elseTextureFormat = TextureImporterFormat.RGBA32;
#endifreturn 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);}
}

转载于:https://blog.51cto.com/13638120/2084946

【小松教你手游开发】【unity系统模块开发】Unity5.5.2UI打包AssetBundle相关推荐

  1. mtk 帧同步_【小松教你手游开发】【面试必读(编程基础)】网络游戏同步方式(帧同步和状态同步)...

    在做网络游戏的时候首先要做的是选择一种同步方式来使用,网上的文章都是说帧同步与状态同步的选择,但是又经常讲的模糊不清,我大概整理了一下,并且有一种我们现在项目用的网络同步方式 状态同步 状态同步就有好 ...

  2. 【小松教你手游开发】【unity实用技能】InvalidOperationException: ou

    InvalidOperationException: out of sync 在unity开发中出现这个bug. 在网上查了下是在迭代器中直接修改引起的.c#是不允许你在迭代器中直接修改. 改了一下确 ...

  3. 【小松教你手游开发】【unity实用技能】网游同步技术

    http://www.skywind.me/blog/archives/1343 转自http://www.skywind.me/blog/archives/1343 实时动作游戏在近年来得到迅猛的发 ...

  4. 【小松教你手游开发】【unity实用技能】unity游戏移植到WindowsPhone8平台上的一些...

    最近在移植u3d的游戏到WindowsPhone8上,WindowsPhone有多蛋疼就不说,移植的过程中还各种问题,稍稍总结一下 1.WindowsPhone账号在电脑上注册不要在手机上.手机上我就 ...

  5. 【小松教你手游开发】【unity实用技能】计算目标物体是否在自己的扇形视野范围...

    在做游戏开发中经常会需要到计算扇形的视野或者是受击范围的时候. 其实这个分为两部分, 第一部分是在扇形距离范围内(也就是不考虑角度,其实是圆形范围内) 第二部分是扇形角度范围内 第一部分很简单,Vec ...

  6. 【小松教你手游开发】【unity实用技能】给每个GameObject的打开关闭加上一个渐变...

    在游戏开发中,经常会因为直接将GameObject,setActive的方式打开关闭,这种方式效果太过生硬而给它加上一个Tween 可能是AlphaTween或者ScaleTween. 再加上一个Pl ...

  7. 【小松教你手游开发】【unity实用技能】u3d 层次问题总结

    首先的首先,NGUI区分前后层次关系是用Depth值.已经跟z轴值无关 首先因为我自己用的是NGUI,所以我的u3d层次问题也就是NGUI的层次问题 先确定UI渲染顺序,Camera>UIPan ...

  8. 【小松教你手游开发】【unity实用技能】Unity图片变灰的方式

    http://www.tuicool.com/articles/Vruuqme NGUI中的Button几乎是最常用到的控件之一,并且可以组合各种组件(比如UIButtonColor,UIButton ...

  9. 【小松教你手游开发】【系统模块开发】图文混排 (在label中插入表情)

    本身ngui是自带图文混排的,这个可以在ngui的Example里找到.但是为什么不能用网上已经说得很清楚,比如雨松momo的http://www.xuanyusong.com/archives/29 ...

最新文章

  1. 【说人话】真正意义上讲清楚了如何用$emit()在Vue.js的自定义组件中实现v-model=“”双向绑定
  2. 寒假训练,2.25,J-Palindrome Names (回文
  3. 国内外ip地址黑名单查询
  4. 精选30张炫酷的动态交互式图表,Pandas一键生成,通俗易懂
  5. 管理表空间和数据文件——维护表空间——设置默认表空间和删除表空间和删除数据文件盒临时文件...
  6. 树的度,结点,叶子结点,二叉树
  7. 直面Java第45期
  8. UVA 10405-Longest Common Subsequence
  9. TCP的定时器系列 — 超时重传定时器(有图有代码有真相!!!)
  10. python0b1011_1011 A+B 和 C (15分)Python参考答案
  11. 【网络安全工程师面试合集】—常见端口扫描技术
  12. 用C#代码实现求两条线段的交点并判断各种情况
  13. 华三交换机如何进入配置_华三交换机配置方法及操作案例
  14. 【汇正财经】企业资本的具体形式
  15. 卸载chrome浏览器_如何在Chrome,Firefox和其他浏览器中卸载扩展程序
  16. Jmeter常用断言之响应断言详解
  17. 26.SSR解决了什么问题?有做过SSR吗?你是怎么做的?
  18. 【实用小工具】开发一个网页版LED点阵绘图模拟器
  19. 一些常用的python绘图包
  20. 合泰HT32F52342/HT32F52352芯片Pack下载和工程例程下载

热门文章

  1. MemoryMonitor内存监视器
  2. java 实现自旋锁_java自旋锁的代码实现
  3. vlan跨交换机 udp广播_划分VLAN和接二级路由都能阻止广播风暴?两者有什么区别?...
  4. 窗体 局部变量转换为全局_从嵌入式编程中感悟「栈」为何方神圣?
  5. 小米6指主板图示_小米MIX2手机不开机,修过没修好,通病问题教你一坨锡就能搞定...
  6. 中南大学计算机在线考试答案,中南大学计算机考试复习题
  7. git idea 本地历史版本回滚_如何为IDEA项目创建GitHub存储库和本地Git存储库
  8. html怎样同框架页面内跳转,使用iframe框架时,实现子页面内跳转到整个页面,而不是在子页面内跳转...
  9. vc mysql封装类_Oracle OCI API封装类VC数据库源码下载-华软网
  10. app显示服务器借口错误,hbuider 运行 uni-app 电脑端安卓模拟器接口请求错误