using XGame.Editor.Asset; using XGame.Framework.Asset; using XGame.Framework.Asset.Addressable; using XGame.Framework.Asset.Addressable.Data; using System.Reflection; using UnityEditor; using UnityEngine; using XGame.Framework.Json; namespace XGame.Editor.Build.AssetBundles { internal class DeserializeABManifestWindow : EditorWindow { internal static void CreateWindow() { var window = EditorWindow.GetWindow(true, "DeserializeABManifest"); window.Show(); } private string _manifestName; private string _manifestFilePath; private string _outpuPath; private string _tempPath; private bool _isToJson; private void OnEnable() { _manifestName = $"{Define.MANIFEST_BUNDLE_NAME}.{Define.BUNDLE_VARIANT}"; _manifestFilePath = $"{PathDefine.AssetBundleOutputPath}/{_manifestName}"; _outpuPath = PathDefine.DefaultOutputPath; _tempPath = "Assets/TempManifest"; _isToJson = true; } private void OnDisable() { } private void OnGUI() { _isToJson = EditorGUILayout.Toggle("导出为Json格式", _isToJson); EditorGUILayout.LabelField($"Manifest文件路径: {_manifestFilePath}"); if (GUILayout.Button("选择Manifest")) { SelectManifestFile(); } EditorGUILayout.LabelField($"导出路径: {_outpuPath}"); if (GUILayout.Button("选择导出目录")) { SelectOutputPath(); } if (GUILayout.Button("开始反序列化")) { Deserialize(); } } private void SelectManifestFile() { var filePath = EditorUtility.OpenFilePanel($"选择Menifest文件,文件名:{_manifestName}", _manifestFilePath, Define.BUNDLE_VARIANT); if (!string.IsNullOrEmpty(filePath) && filePath.EndsWith(_manifestName)) { _manifestFilePath = filePath; } } private void SelectOutputPath() { var output = EditorUtility.OpenFolderPanel("选择导出文件夹", _outpuPath, "manifest"); if (!string.IsNullOrEmpty(output)) { _outpuPath = output; } } private void Deserialize() { var bundle = AssetBundle.LoadFromFile(_manifestFilePath, 0, Define.MANIFEST_BUNDLE_OFFSET); if (bundle == null) { //先按加密读取,读不到再使用无加密方式读取 bundle = AssetBundle.LoadFromFile(_manifestFilePath); } if (bundle == null) { BuildLog.Error($"读取Assetbundle失败,请确认bundle是否正确。ManifestPath:{_manifestFilePath}"); } else { if (!System.IO.Directory.Exists(_tempPath)) { System.IO.Directory.CreateDirectory(_tempPath); } CreateAsset(bundle, Define.ASSET_BUNDLE_MANIFEST, "bundleInfos"); CreateAsset(bundle, Define.SCENE_BUNDLE_MANIFEST, "sceneInfos"); CreateAsset(bundle, Define.ASSET_REFERENCE_MANIFEST, "references"); CreateAsset(bundle, Define.BUILTIN_ASSET_MANIFEST, "assetInfos"); CreateAsset(bundle, Define.PRODUCT_ASSET_MANIFEST, "assetInfos"); bundle.Unload(true); Resources.UnloadUnusedAssets(); UnityEditor.FileUtil.DeleteFileOrDirectory(_tempPath); AssetDatabase.Refresh(); BuildLog.Log("Manifest反序列化结束. "); } } private void CreateAsset(AssetBundle bundle, string assetName, string fieldName) where TManifest : ScriptableObject { var manifest = bundle.LoadAsset(assetName); if (manifest == null) { BuildLog.Log($"没有该类型文件. Type:{typeof(TManifest)} Name:{assetName}"); return; } var fieldInfo = manifest.GetType().GetField(fieldName, BindingFlags.Public | BindingFlags.Instance); var fieldValue = fieldInfo.GetValue(manifest); var instance = ScriptableObject.CreateInstance(); fieldInfo.SetValue(instance, fieldValue); var outputFile = $"{_outpuPath}/{assetName}.asset"; if (System.IO.File.Exists(outputFile)) { UnityEditor.FileUtil.DeleteFileOrDirectory(outputFile); } if (_isToJson) { var json = XJson.ToJson(instance); System.IO.File.WriteAllText(outputFile, json); } else { var _tempFile = $"{_tempPath}/{assetName}.asset"; AssetDatabase.CreateAsset(instance, _tempFile); UnityEditor.FileUtil.MoveFileOrDirectory(_tempFile, $"{_outpuPath}/{assetName}.asset"); } } } }