DeserializeABManifestWindow.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. using XGame.Editor.Asset;
  2. using XGame.Framework.Asset;
  3. using XGame.Framework.Asset.Addressable;
  4. using XGame.Framework.Asset.Addressable.Data;
  5. using System.Reflection;
  6. using UnityEditor;
  7. using UnityEngine;
  8. using XGame.Framework.Json;
  9. namespace XGame.Editor.Build.AssetBundles
  10. {
  11. internal class DeserializeABManifestWindow : EditorWindow
  12. {
  13. internal static void CreateWindow()
  14. {
  15. var window = EditorWindow.GetWindow<DeserializeABManifestWindow>(true, "DeserializeABManifest");
  16. window.Show();
  17. }
  18. private string _manifestName;
  19. private string _manifestFilePath;
  20. private string _outpuPath;
  21. private string _tempPath;
  22. private bool _isToJson;
  23. private void OnEnable()
  24. {
  25. _manifestName = $"{Define.MANIFEST_BUNDLE_NAME}.{Define.BUNDLE_VARIANT}";
  26. _manifestFilePath = $"{PathDefine.AssetBundleOutputPath}/{_manifestName}";
  27. _outpuPath = PathDefine.DefaultOutputPath;
  28. _tempPath = "Assets/TempManifest";
  29. _isToJson = true;
  30. }
  31. private void OnDisable()
  32. {
  33. }
  34. private void OnGUI()
  35. {
  36. _isToJson = EditorGUILayout.Toggle("导出为Json格式", _isToJson);
  37. EditorGUILayout.LabelField($"Manifest文件路径: {_manifestFilePath}");
  38. if (GUILayout.Button("选择Manifest"))
  39. {
  40. SelectManifestFile();
  41. }
  42. EditorGUILayout.LabelField($"导出路径: {_outpuPath}");
  43. if (GUILayout.Button("选择导出目录"))
  44. {
  45. SelectOutputPath();
  46. }
  47. if (GUILayout.Button("开始反序列化"))
  48. {
  49. Deserialize();
  50. }
  51. }
  52. private void SelectManifestFile()
  53. {
  54. var filePath = EditorUtility.OpenFilePanel($"选择Menifest文件,文件名:{_manifestName}", _manifestFilePath, Define.BUNDLE_VARIANT);
  55. if (!string.IsNullOrEmpty(filePath) && filePath.EndsWith(_manifestName))
  56. {
  57. _manifestFilePath = filePath;
  58. }
  59. }
  60. private void SelectOutputPath()
  61. {
  62. var output = EditorUtility.OpenFolderPanel("选择导出文件夹", _outpuPath, "manifest");
  63. if (!string.IsNullOrEmpty(output))
  64. {
  65. _outpuPath = output;
  66. }
  67. }
  68. private void Deserialize()
  69. {
  70. var bundle = AssetBundle.LoadFromFile(_manifestFilePath, 0, Define.MANIFEST_BUNDLE_OFFSET);
  71. if (bundle == null)
  72. {
  73. //先按加密读取,读不到再使用无加密方式读取
  74. bundle = AssetBundle.LoadFromFile(_manifestFilePath);
  75. }
  76. if (bundle == null)
  77. {
  78. BuildLog.Error($"读取Assetbundle失败,请确认bundle是否正确。ManifestPath:{_manifestFilePath}");
  79. }
  80. else
  81. {
  82. if (!System.IO.Directory.Exists(_tempPath))
  83. {
  84. System.IO.Directory.CreateDirectory(_tempPath);
  85. }
  86. CreateAsset<AssetBundleInfosSo, AssetBundleInfo>(bundle, Define.ASSET_BUNDLE_MANIFEST, "bundleInfos");
  87. CreateAsset<SceneInfosSo, SceneAssetInfo>(bundle, Define.SCENE_BUNDLE_MANIFEST, "sceneInfos");
  88. CreateAsset<AssetReferenceInfosSo, AssetReferenceInfo>(bundle, Define.ASSET_REFERENCE_MANIFEST, "references");
  89. CreateAsset<AddressableInfosSo, AssetInfo>(bundle, Define.BUILTIN_ASSET_MANIFEST, "assetInfos");
  90. CreateAsset<AddressableInfosSo, AssetInfo>(bundle, Define.PRODUCT_ASSET_MANIFEST, "assetInfos");
  91. bundle.Unload(true);
  92. Resources.UnloadUnusedAssets();
  93. UnityEditor.FileUtil.DeleteFileOrDirectory(_tempPath);
  94. AssetDatabase.Refresh();
  95. BuildLog.Log("Manifest反序列化结束. ");
  96. }
  97. }
  98. private void CreateAsset<TManifest, TfileType>(AssetBundle bundle, string assetName, string fieldName) where TManifest : ScriptableObject
  99. {
  100. var manifest = bundle.LoadAsset<TManifest>(assetName);
  101. if (manifest == null)
  102. {
  103. BuildLog.Log($"没有该类型文件. Type:{typeof(TManifest)} Name:{assetName}");
  104. return;
  105. }
  106. var fieldInfo = manifest.GetType().GetField(fieldName, BindingFlags.Public | BindingFlags.Instance);
  107. var fieldValue = fieldInfo.GetValue(manifest);
  108. var instance = ScriptableObject.CreateInstance<TManifest>();
  109. fieldInfo.SetValue(instance, fieldValue);
  110. var outputFile = $"{_outpuPath}/{assetName}.asset";
  111. if (System.IO.File.Exists(outputFile))
  112. {
  113. UnityEditor.FileUtil.DeleteFileOrDirectory(outputFile);
  114. }
  115. if (_isToJson)
  116. {
  117. var json = XJson.ToJson(instance);
  118. System.IO.File.WriteAllText(outputFile, json);
  119. }
  120. else
  121. {
  122. var _tempFile = $"{_tempPath}/{assetName}.asset";
  123. AssetDatabase.CreateAsset(instance, _tempFile);
  124. UnityEditor.FileUtil.MoveFileOrDirectory(_tempFile, $"{_outpuPath}/{assetName}.asset");
  125. }
  126. }
  127. }
  128. }