赞
踩
游戏的资源类型大致分为:
根据Addressable系统的特性,我们大致可以将游戏的资源文件分两类:
根据文件夹路径,我们将对资源进行自动标记地址,标签以及分组类型(本地或远程)。
/// <summary> /// 自动创建图集 /// </summary> /// <param name="path">路径</param> /// <param name="dir">文件夹</param> private static void addSpriteAtlas(string path, DirectoryInfo dir) { var dirs = dir.GetDirectories(); if (dirs == null || dirs.Length == 0) { string name = path.Replace(AtlasRoot + "/", string.Empty).Replace("/", "_"); string filePath = SpriteAtlas + "/" + name + ".spriteatlas"; if (File.Exists(filePath)) { int assetIndex = filePath.IndexOf("Assets"); string guidPath = filePath.Remove(0, assetIndex); var guid = AssetDatabase.AssetPathToGUID(guidPath); var group = setting.FindGroup("Local_SpriteAtlas"); var entry = setting.CreateOrMoveEntry(guid, group); var label = name + ".spriteatlas"; if (entry.address != name) { entry.SetAddress(name); addAddressInfo("Local_SpriteAtlas", name); } List<string> oldLabels = new List<string>(); foreach (var item in entry.labels) { if (item != label) oldLabels.Add(item); } for (int i = 0; i < oldLabels.Count; i++) { entry.SetLabel(oldLabels[i], false); setting.RemoveLabel(oldLabels[i]); } if (!setting.GetLabels().Contains("SpriteAtlas")) { setting.AddLabel("SpriteAtlas"); } entry.SetLabel("SpriteAtlas", true); if (!setting.GetLabels().Contains(label)) { setting.AddLabel(label); } entry.SetLabel(label, true); return; } else { SpriteAtlas atlas = new SpriteAtlas(); //设置打包参数 SpriteAtlasPackingSettings packSetting = new SpriteAtlasPackingSettings() { blockOffset = 1, enableRotation = true, enableTightPacking = false, padding = 2, }; atlas.SetPackingSettings(packSetting); //设置打包后Texture图集信息 SpriteAtlasTextureSettings textureSettings = new SpriteAtlasTextureSettings() { readable = false, generateMipMaps = false, sRGB = true, filterMode = FilterMode.Bilinear, }; atlas.SetTextureSettings(textureSettings); //设置平台图集大小压缩等信息 TextureImporterPlatformSettings platformSettings = new TextureImporterPlatformSettings() { maxTextureSize = 4096, format = TextureImporterFormat.Automatic, crunchedCompression = true, textureCompression = TextureImporterCompression.Compressed, compressionQuality = 50, }; atlas.SetPlatformSettings(platformSettings); int index = filePath.IndexOf("Assets"); string atlasPath = filePath.Remove(0, index); AssetDatabase.CreateAsset(atlas, atlasPath); index = path.IndexOf("Assets"); string spritePath = path.Remove(0, index); Object obj = AssetDatabase.LoadAssetAtPath(spritePath, typeof(Object)); atlas.Add(new[] { obj }); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); int assetIndex = filePath.IndexOf("Assets"); string guidPath = filePath.Remove(0, assetIndex); var guid = AssetDatabase.AssetPathToGUID(guidPath); var group = setting.FindGroup("Local_SpriteAtlas"); var entry = setting.CreateOrMoveEntry(guid, group); var label = name + ".spriteatlas"; if (entry.address != name) { entry.SetAddress(name); addAddressInfo("Local_SpriteAtlas", name); } List<string> oldLabels = new List<string>(); foreach (var item in entry.labels) { if (item != label) oldLabels.Add(item); } for (int i = 0; i < oldLabels.Count; i++) { entry.SetLabel(oldLabels[i], false); setting.RemoveLabel(oldLabels[i]); } if (!setting.GetLabels().Contains(label)) { setting.AddLabel(label); } entry.SetLabel(label, true); if (!setting.GetLabels().Contains("SpriteAtlas")) { setting.AddLabel("SpriteAtlas"); } entry.SetLabel("SpriteAtlas", true); AssetDatabase.Refresh(); } } else { if (dirs.Length > 0) { foreach (var info in dirs) { addSpriteAtlas(path + "/" + info.Name, info); } } } }
addressDic.Clear(); /* var groupList = setting.groups; for (int i = 0; i < groupList.Count; i++) { if (!groupList[i].name.Contains("Built In Data") && !groupList[i].name.Contains("Default Local Group")) setting.RemoveGroup(groupList[i]); }*/ ///创建分组 string loaclRoot = Application.dataPath + "/AddressableAssets/Local"; string remotedRoot = Application.dataPath + "/AddressableAssets/Remoted"; DirectoryInfo[] dirs = new DirectoryInfo(loaclRoot).GetDirectories(); foreach (var info in dirs) { string group_name = "Local_" + info.Name; var group = setting.FindGroup(group_name); if (group == null) { group = setting.CreateGroup(group_name, false, false, false, new List<AddressableAssetGroupSchema> { setting.DefaultGroup.Schemas[0], setting.DefaultGroup.Schemas[1] }); } AutoMarkRootAddress("Local", info); if (info.Name != "SpriteAtlas") AutoMark(info.Name); } dirs = new DirectoryInfo(remotedRoot).GetDirectories(); foreach (var info in dirs) { string group_name = "Remoted_" + info.Name; var group = setting.FindGroup(group_name); if (group == null) { group = setting.CreateGroup(group_name, false, false, false, new List<AddressableAssetGroupSchema> { setting.DefaultGroup.Schemas[0], setting.DefaultGroup.Schemas[1] }); } AutoMarkRootAddress("Remoted", info); AutoMark(info.Name, false); } ///自动创建图集 AutoCreateSpriteAtlas(); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); Debug.Log("MarkAsset Successful");
private static void markFiles(string path, string name, DirectoryInfo dir, bool local = true) { var files = dir.GetFiles(); if (files != null && files.Length > 0) { foreach (var file in files) { if (file.Extension != ".meta") { int index = file.Name.IndexOf("."); string address = file.Name.Remove(index, file.Name.Length - index); string group_name = local ? "Local_" + name : "Remoted_" + name; string assetPath = path + "/" + dir.Name + "/" + file.Name; List<string> label = new List<string>(); string[] allDirs; if (local) { allDirs = (path + "/" + dir.Name).Replace("Assets/AddressableAssets/Local/" + name + "/", string.Empty).Split('/'); } else { allDirs = (path + "/" + dir.Name).Replace("Assets/AddressableAssets/Remoted/" + name + "/", string.Empty).Split('/'); } label.Add(name); for (int i = 0; i < allDirs.Length; i++) { label.Add(allDirs[i]); } var guid = AssetDatabase.AssetPathToGUID(assetPath); var group = setting.FindGroup(group_name); if (group != null) { var entry = setting.CreateOrMoveEntry(guid, group); if (entry.address != address) { entry.SetAddress(address); addAddressInfo(group_name, address + file.Extension); List<string> oldLabels = new List<string>(); foreach (var item in entry.labels) { if (!label.Contains(item)) oldLabels.Add(item); } for (int i = 0; i < oldLabels.Count; i++) { entry.SetLabel(oldLabels[i], false); setting.RemoveLabel(oldLabels[i]); } for (int i = 0; i < label.Count; i++) { var _label = label[i]; if (!setting.GetLabels().Contains(_label)) { setting.AddLabel(_label); } entry.SetLabel(_label, true); } } } else { Debug.LogError("分组 = " + group_name + "不存在"); } } } } }
自动化打包需要以下几个步骤:
/// <summary> /// 标记为资源分组 /// 0 小包,所有资源存放资源服务器 /// 1 分包 ,Local资源存本地,Remoted资源存资源服务器 /// 2 整包,所有资源存本地 /// </summary> private void markStatus(int status) { List<AddressableAssetGroup> deleteList = new List<AddressableAssetGroup>(); for (int i = 0; i < setting.groups.Count; i++) { var group = setting.groups[i]; if (group.name != "Default Local Group" && group.name != "Built In Data") { if (group.entries.Count <= 0) { ///删除没有资源的分组 deleteList.Add(group); } else { foreach (var schema in group.Schemas) { if (schema is UnityEditor.AddressableAssets.Settings.GroupSchemas .BundledAssetGroupSchema) { bool bundleCrc = true; string buildPath = AddressableAssetSettings.kLocalBuildPath; string loadPath = AddressableAssetSettings.kLocalLoadPath; if (group.name.Contains("Local_")) { bundleCrc = status == 0; buildPath = status == 0 ? AddressableAssetSettings.kRemoteBuildPath : AddressableAssetSettings.kLocalBuildPath; loadPath = status == 0 ? AddressableAssetSettings.kRemoteLoadPath : AddressableAssetSettings.kLocalLoadPath; } else if (group.name.Contains("Remoted_")) { bundleCrc = !(status == 2); buildPath = status == 2 ? AddressableAssetSettings.kLocalBuildPath : AddressableAssetSettings.kRemoteBuildPath; loadPath = status == 2 ? AddressableAssetSettings.kLocalLoadPath : AddressableAssetSettings.kRemoteLoadPath; } else if (group.name.Contains("UpdateGroup_")) { bundleCrc = true; buildPath = AddressableAssetSettings.kRemoteBuildPath; loadPath = AddressableAssetSettings.kRemoteLoadPath; } var bundledAssetGroupSchema = (schema as UnityEditor.AddressableAssets.Settings.GroupSchemas.BundledAssetGroupSchema); bundledAssetGroupSchema.BuildPath.SetVariableByName(group.Settings, buildPath); bundledAssetGroupSchema.LoadPath.SetVariableByName(group.Settings, loadPath); bundledAssetGroupSchema.UseAssetBundleCrc = bundleCrc; bundledAssetGroupSchema.BundleNaming = UnityEditor.AddressableAssets.Settings.GroupSchemas.BundledAssetGroupSchema.BundleNamingStyle.NoHash; bundledAssetGroupSchema.BundleMode = UnityEditor.AddressableAssets.Settings.GroupSchemas.BundledAssetGroupSchema.BundlePackingMode.PackTogetherByLabel; } else if (schema is UnityEditor.AddressableAssets.Settings.GroupSchemas.ContentUpdateGroupSchema) { var updateGroupSchema = (schema as UnityEditor.AddressableAssets.Settings.GroupSchemas.ContentUpdateGroupSchema); if (group.name.Contains("Local_")) { updateGroupSchema.StaticContent = !(status == 0); } else if (group.name.Contains("Remoted_")) { updateGroupSchema.StaticContent = (status == 2); } else if (group.name.Contains("UpdateGroup_")) { updateGroupSchema.StaticContent = false; } } } } } } for (int i = 0; i < deleteList.Count; i++) { setting.RemoveGroup(deleteList[i]); } }
public enum BuildEnvironment { Local,//内网测试整包 Debug, Beta, Release } private void setActiveProfileId() { var names = setting.profileSettings.GetAllProfileNames(); if (!names.Contains(environment.ToString())) { setting.profileSettings.AddProfile(environment.ToString(), setting.activeProfileId); } var id = setting.profileSettings.GetProfileId(environment.ToString()); if (setting.activeProfileId != id) setting.activeProfileId = id; if (environment == BuildEnvironment.Local) { setting.profileSettings.SetValue(setting.activeProfileId, "RemoteBuildPath", "[UnityEngine.AddressableAssets.Addressables.BuildPath]/[BuildTarget]"); setting.profileSettings.SetValue(setting.activeProfileId, "RemoteLoadPath", "{UnityEngine.AddressableAssets.Addressables.RuntimePath}/[BuildTarget]"); setting.BuildRemoteCatalog = false; } else { setting.BuildRemoteCatalog = true; string[] ver = version.Split('.'); string name = setting.profileSettings.GetProfileName(setting.activeProfileId); string buildPath = "ServerData" + "/[BuildTarget]/" + ver[0] + "." + ver[1] + "/" + name; if (setting.profileSettings.GetValueByName(setting.activeProfileId, "RemoteBuildPath") != buildPath) setting.profileSettings.SetValue(setting.activeProfileId, "RemoteBuildPath", buildPath); string loadPath = url + "/poetry/" + buildPath; if (setting.profileSettings.GetValueByName(setting.activeProfileId, "RemoteLoadPath") != loadPath) setting.profileSettings.SetValue(setting.activeProfileId, "RemoteLoadPath", loadPath); } }
private void buildByStatus(int status, bool buildApp = true) { isBuildSuccess = true; BuildTools.ClearConsole(); Application.logMessageReceived += onLogMessage; if (buildApp) { /* Generator.ClearAll(); Generator.GenAll();*/ } AssetDatabase.Refresh(); setActiveProfileId(); AssetDatabase.Refresh(); markStatus(status); SetMD5Info(); AddressableAssetSettings.BuildPlayerContent();//Addressable打包资源API AssetDatabase.Refresh(); CopyBuildData(); AssetDatabase.Refresh(); SetMD5Info(false); if (buildApp) build(); Application.logMessageReceived -= onLogMessage; if (isBuildSuccess) { string showMessage = string.Empty; if (status == 0) { showMessage = buildApp ? "打包小包成功" : "打包小包资源完成"; } else if (status == 1) { showMessage = buildApp ? "打包分包成功" : "打包分包资源完成"; } else if (status == 2) { showMessage = buildApp ? "打包整包成功" : "打包整包资源完成"; } if (EditorUtility.DisplayDialog(buildApp ? "打包完成" : "打包资源", showMessage, "确定")) { if (buildApp) { EditorUtility.RevealInFinder(BuildTools.OutPath); BuildTools.OutPath = string.Empty; } } } else { if (EditorUtility.DisplayDialog("打包失败", "请检测报错信息", "确定")) { EditorUtility.RevealInFinder(BuildTools.OutPath); BuildTools.OutPath = string.Empty; } } }
详细的源码已上传,直接导入Unity(开发时使用的版是Unity2019.4)可以使用,注意要从PackageManager中下载相应Addressable系统相关组件,并创建好AddressableSetting文件
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。