UnityAsetBundle开发模式管理
来源:互联网 发布:搞笑照片软件 编辑:程序博客网 时间:2024/06/10 03:39
公司终于使用AssetBundle来开发游戏了。虽然AssetBunle对项目的资源更新方面起到了很大的便利。但是在开发过程中却多有不变。主要体现在一下几个方面。
1:资源加载过程,直接使用资源,本地bundle资源,网上bundle资源这三种模式切换很麻烦。
2:加载具体资源,需要传入相应的资源字符串,字符拼写容易出错。
针对以上两种问题,我想出以下的解决方案。
1:无论是,本地资源,本地bundle资源,网上bundle资源,都使用同一套接口来调用。模式之间的切换,通过预先指定就行了。
2:加载本地资源时,资源并没有在resource下,因此主要用于编辑器模式,所以通过配置相关的路径信息来加载资源,我获取了所有的bundle资源的路径,并以json表来保存。
3:针对设置的bundle,相应的bundle资源,通过生成相应的枚举,和类变量,通过引用。就可以避免字符串之间的传入错误。
下面是相关的代码,可以参考:
1:配置bundle资源的路径信息
2:生成所有bundle资源的枚举
3:以bundle名+“_”+”prefab”为类名,生成类名,资源名用字段保存,用const来修饰
[MenuItem("LazerSelect/Bundle/Config")] private static void BundlePathConfig() { //准备一个代码编译器单元 CodeCompileUnit unit = new CodeCompileUnit(); //准备必要的命名空间(这个是指要生成的类的空间) CodeNamespace sampleNamespace = new CodeNamespace(); CodeTypeDeclaration bundleEnum = new CodeTypeDeclaration("EBundleName"); bundleEnum.IsEnum = true; bundleEnum.TypeAttributes = TypeAttributes.Public; sampleNamespace.Types.Add(bundleEnum); unit.Namespaces.Add(sampleNamespace); CodeMemberField field; CodeTypeDeclaration bundleClass; int bundleIndex = 0; Dictionary<string, PrefabPath> prefabDict = new Dictionary<string, PrefabPath>(); string[] assetBundleNames = AssetDatabase.GetAllAssetBundleNames(); Dictionary<ObjPoolItem, string> pool_item_bundle_dict = new Dictionary<ObjPoolItem, string>(); foreach (string bundleName in assetBundleNames) { Debug.Log("bundle name:" + bundleName); field = new CodeMemberField(typeof(System.Enum), bundleName); field.InitExpression = new CodePrimitiveExpression(bundleIndex); bundleEnum.Members.Add(field); ++bundleIndex; bundleClass = new CodeTypeDeclaration(string.Format("{0}_Prefab", bundleName)); bundleClass.IsClass = true; bundleClass.TypeAttributes = TypeAttributes.Public; sampleNamespace.Types.Add(bundleClass); PrefabPath prefabPathInfo = new PrefabPath(); prefabPathInfo.PrefabPathDict = new Dictionary<string, string>(); string[] prefabPaths = AssetDatabase.GetAssetPathsFromAssetBundle(bundleName); foreach (string prefabPath in prefabPaths) { if (prefabPath.Contains(".mat")) { continue;} if (Helper.IsChinaString(prefabPath)){continue;} if (prefabPath.Contains(".prefab")) { ObjPoolItem poolItem = (UnityEditor.AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject).GetComponent<ObjPoolItem>(); if (poolItem) { pool_item_bundle_dict[poolItem] = bundleName; } } string[] splitStrings = prefabPath.Split('/', '.'); string prefabName = splitStrings[splitStrings.Length - 2]; Debug.Log("prefabPath:" + prefabPath + " prefabname:" + prefabName); int prefabIndex; if (int.TryParse(prefabName, out prefabIndex)) { continue; } if (prefabName.Contains("-")) { continue; } if (!prefabPathInfo.PrefabPathDict.ContainsKey(prefabName)) { field = new CodeMemberField(typeof(String), prefabName); field.Attributes = MemberAttributes.Public | MemberAttributes.Const; field.InitExpression = new CodePrimitiveExpression(prefabName); bundleClass.Members.Add(field); prefabPathInfo.PrefabPathDict[prefabName] = prefabPath; } else { if (prefabPath.Contains(".prefab"))//优先保存预设 { prefabPathInfo.PrefabPathDict[prefabName] = prefabPath; } } } prefabDict[bundleName] = prefabPathInfo; } string json = JsonConvert.SerializeObject(prefabDict, Newtonsoft.Json.Formatting.Indented);//JsonMapper.ToJson(prefabDict); Debug.Log(json); byte[] bytes = System.Text.UTF8Encoding.UTF8.GetBytes(json); File.WriteAllBytes(Application.dataPath + "/" + "Project_Fish/BundleBuilder/BundleConfigJson/BundleConfig.json", bytes); string outputFile = Application.dataPath + "/" + "Project_Fish/BundleBuilder/BundleConfigJson/BundleConfig.cs";// "Customer.cs"; CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp"); CodeGeneratorOptions options = new CodeGeneratorOptions(); options.BracingStyle = "C"; options.BlankLinesBetweenMembers = false; using (System.IO.StreamWriter sw = new System.IO.StreamWriter(outputFile)) { provider.GenerateCodeFromCompileUnit(unit, sw, options); } AssetDatabase.Refresh(); foreach (KeyValuePair<ObjPoolItem, string> key_value in pool_item_bundle_dict) { Debug.Log(key_value.Value); //标记预设为修改状态 这步很重要,不执行这步操作。关闭Unity后。预设并不会保存。 EditorUtility.SetDirty(key_value.Key.gameObject); //key_value.Key.Bundle = key_value.Value;// (EBundleName)Enum.Parse(typeof(EBundleName), key_value.Value); key_value.Key.BundleName = (EBundleName)Enum.Parse(typeof(EBundleName), key_value.Value); } AssetDatabase.Refresh(); AssetDatabase.SaveAssets(); pool_item_bundle_dict = null; GC.Collect(); }
1:此文件,是三种资源加载的通用接口
2:如果是编辑器模式,先加载本地资源路径信息json表(上面代码生成的)
3:如果是本地bundle模式,需要生成相关的bundle,保存在streamassets文件夹localbundle下
4:如果是服务器bundle模式,保证在调用相关的接口调用之前,将下载的bundle保存在字典即可。
public class BundleResourceManager :CommonSingleton<BundleResourceManager>{ //bundle 字典 public Dictionary<string, AssetBundle> AssetBundlePool = new Dictionary<string, AssetBundle>(); //资源字典 public Dictionary<string, PrefabPath> ResourceDict; public override void Initialize() { if(AppConst.BundleType == EBundleType.NoBundle) {#if UNITY_EDITOR ResourceDict = JsonMapper.ToObject<Dictionary<string,PrefabPath>>((UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/Project_Fish/BundleBuilder/BundleConfigJson/BundleConfig.json", typeof(TextAsset)) as TextAsset).text); //SDebug.Log(ResourceDict.Count);#endif } else if(AppConst.BundleType == EBundleType.LocalBundle) { GetBundle(EBundleName.fishuiatlas);// typeof(EBundleName),"fishuiatlas")); GetBundle(EBundleName.fishingameuiatlas);// (EBundleName)Enum.Parse(typeof(EBundleName), "fishingameuiatlas")); GetBundle(EBundleName.common); //(EBundleName)Enum.Parse(typeof(EBundleName), "common")); } } public T CreateObj<T>(EBundleName bundleName,string prefabName) where T :Object { SDebug.Log("need create bundle:"+bundleName+" prefab name:"+prefabName); if(prefabName.Contains("."))//去除后缀 { prefabName = prefabName.Split('.')[0]; } return CreateObj(bundleName, prefabName,typeof(T)) as T; } public Object CreateObj(EBundleName bundleName, string prefabName) { return CreateObj(bundleName, prefabName, typeof(GameObject)); } //实例化预设 public UnityEngine.Object CreateObj(EBundleName bundleName, string prefabName,Type type) { SDebug.Log("need create bundle:" + bundleName + " prefab name:" + prefabName); if (AppConst.BundleType == EBundleType.NoBundle) { string prefabPath = ResourceDict[bundleName.ToString()].PrefabPathDict[prefabName]; SDebug.Log("path:" + prefabPath);#if UNITY_EDITOR return UnityEditor.AssetDatabase.LoadAssetAtPath(prefabPath, type);#endif return null; } else if (AppConst.BundleType == EBundleType.LocalBundle) { AssetBundle assetBundle; if (AssetBundlePool.TryGetValue(bundleName.ToString(), out assetBundle)) { return assetBundle.LoadAsset(prefabName); } assetBundle = GetBundle(bundleName); if (assetBundle != null) { return assetBundle.LoadAsset(prefabName); } Debug.LogError("the prefab name:" + prefabName + " is not exist!"); return null; } else { AssetBundle assetBundle; if (AssetBundlePool.TryGetValue(bundleName.ToString(), out assetBundle)) { return assetBundle.LoadAsset(prefabName); } Debug.LogError("the prefab name:" + prefabName + " is not exist!"); return null; } } public void SetBundle(string bundleName,AssetBundle bundle) { AssetBundlePool[bundleName] = bundle; } public AssetBundle GetBundle(EBundleName bundleName) { AssetBundle result; if(AssetBundlePool.TryGetValue(bundleName.ToString(),out result)) { return result; } if(AppConst.BundleType == EBundleType.LocalBundle) { result = AssetBundle.LoadFromFile(string.Format("{0}/{1}", Util.LocalBundlePath, bundleName)); SetBundle(bundleName.ToString(), result); return result; } Debug.LogError(string.Format("the bundle name :{0} is not exist!", bundleName)); return null; }}
阅读全文
0 0
- UnityAsetBundle开发模式管理
- 产品开发模式管理网站开发
- 产品开发模式管理网站开发
- 产品开发模式管理网站开发
- 产品开发模式管理网站开发
- 软件开发项目管理的模式概述
- 超市管理系统,mvc开发模式
- SVN 版本管理:两种开发模式
- SVN 版本管理:两种开发模式
- 软件开发项目管理的模式概述
- 论React后台管理系统开发模式
- 手机软件开发管理过程中,如何采用敏捷开发模式
- 手机软件开发管理过程中,如何采用敏捷开发模式
- 主流新产品开发模式介绍:集成产品开发管理
- IOS开发笔记27-应用管理之MVC模式
- 开发管理
- 开发管理
- 开发管理
- 数据统计类中求平均值的方法
- 浅谈汇编,认识汇编(三)
- react项目实战(权限模块开发一) 配置路由
- bio aio nio
- php imap读取邮件功能
- UnityAsetBundle开发模式管理
- Android7.0 使用FileProvider 共享文件
- java基础之一 类型、算术运算和控制语句
- 不需要用vuex,只需要用到axios一样可以实现登录拦截,想后台请求数据
- jQuery选择器
- 异议申请流程
- Windows服务器上完成Let’s Encrypt免费SSL证书的自动化更新部署(apache)
- CString转成char*
- 如何使用命令在navicat中创建数据库及表