using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEngine; using XGame.Framework.i18n; namespace XGame.Editor.Build.AssetBundles { public class ABPackerInfoManifestWindow { private ABPackerInfoManifest manifest; private readonly bool isInspector; private GUIContent _shaderContent; private ABPackerReorderableList _abPackerList; private ABPackerReorderableList _abGroupList; public ABPackerInfoManifestWindow(ABPackerInfoManifest manifest, bool isInspector) { this.manifest = manifest; this.isInspector = isInspector; _shaderContent = new GUIContent("是否合并Shader", "将*.shadervariants文件和其所依赖的shader一起打在一个包内"); var apckerToolTip = "打包分类 \r\nTopDirectoryOnly:默认方式,当前目录的资源(不包含子目录)打一个包 \r\nAllDirectories:当前目录及子目录的资源打一个包 \r\nSingleAsset:单个资源打包"; _abPackerList = new ABPackerReorderableList(manifest.PackerInfos, "Assetbundle打包配置", apckerToolTip) { IsFoldout = true }; var groupToolTip = "设置分组的资源,Assetbundle会生成在指定分组文件夹下: StreamAssets/{Platform}/AssetBundles/{GroupName}/ "; _abGroupList = new ABPackerReorderableList(manifest.GroupInfos, "Assetbundle分组配置", groupToolTip) { IsFoldout = true }; } public void OnGUI() { EditorGUILayout.BeginVertical(); manifest.bundleNameMode = (AssetBundleNameMode)EditorGUILayout.EnumPopup("Bundle命名模式", manifest.bundleNameMode); manifest.isMergeShader = EditorGUILayout.Toggle(_shaderContent, manifest.isMergeShader); _abPackerList.OnGUI(); _abGroupList.OnGUI(); DrawButtons(); DrawMsg(); EditorGUILayout.EndVertical(); } private void DrawButtons() { var apply = GUILayout.Button("Apply"); if (apply) { //刷新 OnApplyBtn(); } } private void DrawMsg() { GUILayout.Space(20); EditorGUILayout.HelpBox("友情提示:如有修改请及时上传同步 Manifest 文件,否则后果自负。", MessageType.Warning); //GUI.color = Color.red; //GUILayout.TextArea("友情提示:如有修改请及时上传同步 Manifest 文件,否则后果自负。", GUI.skin.textArea); //GUI.color = Color.white; GUILayout.Space(5); EditorGUI.BeginDisabledGroup(true); EditorGUILayout.ObjectField("Manifest", manifest, typeof(Object), false); EditorGUI.EndDisabledGroup(); } private void OnApplyBtn() { ApplyPackerInfos(); ApplyGroupInfos(); manifest.Save(); Debug.Log("ABPackerInfoManifest apply completed."); } private void ApplyPackerInfos() { var guids = new HashSet(); var packerInfos = new List(); foreach (var item in manifest.PackerInfos) { var guid = item.GUID; if (string.IsNullOrEmpty(guid)) { Debug.LogWarning($"AssetbundlePacker 资源为空. {item}"); } else if (guids.Contains(guid)) { Debug.LogError($"AssetbundlePacker 资源重复. Path: {AssetDatabase.GUIDToAssetPath(guid)}"); } else { guids.Add(guid); packerInfos.Add(item); } } manifest.PackerInfos.Clear(); manifest.PackerInfos.AddRange(packerInfos); } private void ApplyGroupInfos() { var datas = _abGroupList.GetItemDatas(); var guids = new HashSet(); var groupMap = new Dictionary(); foreach (var data in datas) { var groupName = data.groupName.Trim(); if (string.IsNullOrEmpty(groupName) || Asset.FileUtil.HasChinese(groupName)) { Debug.LogError($"AssetbundleGroup 名字为空或者包含中文字符! GroupName:{groupName}"); continue; } if (LanguageUtils.IsLanguage(groupName)) { Debug.LogError($"AssetbundleGroup 名字不能为多语言枚举. GroupName:{groupName}"); continue; } if (groupMap.ContainsKey(groupName)) { Debug.LogError($"AssetbundleGroup 名字重复. GroupName:{groupName}"); continue; } for(var i = data.guidList.Count - 1; i >= 0; i--) { var guid = data.guidList[i]; if (string.IsNullOrEmpty(guid)) { data.guidList.RemoveAt(i); } else if (guids.Contains(guid)) { data.guidList.RemoveAt(i); Debug.LogError($"AssetbundleGroup 资源重复. Path:{AssetDatabase.GUIDToAssetPath(guid)}"); } else { guids.Add(guid); } } if (data.guidList.Count < 1) { Debug.LogError($"AssetbundleGroup 资源列表为空! GroupName:{groupName}"); continue; } data.groupName = groupName; groupMap.Add(groupName, data); } manifest.GroupInfos.Clear(); foreach(var item in groupMap) { manifest.GroupInfos.Add(item.Value); } } public void Close() { (_abPackerList as System.IDisposable)?.Dispose(); _abPackerList = null; (_abGroupList as System.IDisposable)?.Dispose(); _abGroupList = null; manifest = null; } } }