当前位置:   article > 正文

如何不依赖Unity直接解压unitypackage的内容_解包unitypackage

解包unitypackage

使用场景

我们都知道unity的资源导出是导出成.unitypackage文件,如果要里面的内容,得打开Unity,将unitypackage导入进去才能看到里面的内容。

但是很多时候我们下了几十个unitypackage资源包,又不清楚好不好用,而且导入之后编译特别慢,unity又不提供批量解压的功能,所以这时候就想能不能提前解压呢。

当然可以,为此我做了一个工具,可以不需要unity直接将unitypackage解压出来,这里我介绍下他的用法,后续我会把工具包上传上来。

工具包内容如下:

使用说明

这个工具包是用C#写的,我先说下说用方法:

  • 单个解压:适用于只解压一个unitypackage的情况
    1. @echo off
    2. ::设置unitypackage文件路径
    3. set fileName=file.unitypackage
    4. ::设置导出目录
    5. set destPath=file
    6. call dotnet-ExtractUnityPackage.exe %fileName% %destPath%
    7. echo 导出成功!
    8. pause

    运行前先修改下fileName也就是.unitypackage的路径,destPath就是导出目录
    修改完毕双击直接运行即可

  • 批量解压:适用于解压文件夹下包括子目录下的所有unitypackage文件
    将多个unitypackage文件复制到sources目录下,双击批量解压.bat,即可在export里找到解压出来的内容

程序原理

主要代码

  1. using ICSharpCode.SharpZipLib.GZip;
  2. using ICSharpCode.SharpZipLib.Tar;
  3. using System.IO;
  4. namespace ExtractUnityPackage
  5. {
  6. internal static class Extractor
  7. {
  8. public static void ImportUnityPackage(string packagePath, string destinationFolderPath, bool overwrite)
  9. {
  10. var tempFolder = Path.Combine(Path.GetTempPath(), Path.GetFileName(packagePath) + ".unitypackage.extract");
  11. using (var i = new FileStream(packagePath, FileMode.Open, FileAccess.Read))
  12. using (var gi = new GZipInputStream(i))
  13. using (var tar = TarArchive.CreateInputTarArchive(gi))
  14. {
  15. tar.ExtractContents(tempFolder);
  16. }
  17. foreach (var item in Directory.GetDirectories(tempFolder))
  18. {
  19. var pathNameData = File.ReadAllLines(Path.Combine(item, "pathname"));
  20. var pathname = pathNameData[0];
  21. var path = Path.Combine(destinationFolderPath, pathname);
  22. var assetPath = Path.Combine(item, "asset");
  23. if (File.Exists(assetPath))
  24. {
  25. var folder = Path.GetDirectoryName(Path.GetFullPath(path));
  26. if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);
  27. if (overwrite || !File.Exists(path)) File.Copy(assetPath, path, true);
  28. }
  29. else
  30. {
  31. var folder = path;
  32. if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);
  33. }
  34. var assetMetaPath = Path.Combine(item, "asset.meta");
  35. var metaPath = path + ".meta";
  36. if (File.Exists(assetMetaPath))
  37. {
  38. if (overwrite || !File.Exists(metaPath)) File.Copy(assetMetaPath, metaPath, true);
  39. }
  40. }
  41. Directory.Delete(tempFolder, true);
  42. }
  43. }
  44. }
  1. using McMaster.Extensions.CommandLineUtils;
  2. using System.ComponentModel.DataAnnotations;
  3. namespace ExtractUnityPackage
  4. {
  5. [Command(Description = "A global tool for extracting .unitypackage", Name = "dotnet ExtractUnityPackage")]
  6. public class Program
  7. {
  8. [Argument(0, Description = "source .unitypackage path")]
  9. [Required]
  10. public string Package { get; }
  11. [Argument(1, Description = "destination folder path")]
  12. [Required]
  13. public string Destination { get; }
  14. [Option("-o|--overwrite", Description = "overwrites if file exists")]
  15. public bool Overwrite { get; }
  16. static void Main(string[] args)
  17. {
  18. CommandLineApplication.Execute<Program>(args);
  19. }
  20. public void OnExecute()
  21. {
  22. Extractor.ImportUnityPackage(Package, Destination, Overwrite);
  23. }
  24. }
  25. }

 原理解析

通过上面的主要代码,我们可以看到其实unitypackage就是一个简单的压缩包,解压出来的文件如下图所示,像乱码一样,文件也不明文。

随便找个目录看下,找到pathname。

打开pathname会发现这个就是文件的原始路径,以及asset就是文件的原始文件,如图所示就是一个iron.png图,将asset改名为iron.png会发现就可以访问了。

所以总的来说原理就是解析每个目录下的pathname,将asset拷贝到对应目录下,组装成一个解压出来的包内容。

请注意,该工具运行需要电脑安装有.net环境,如果有疑问,请评论或加Q群提问:Unity开发探讨交流 904994482。

工具包资源路径:https://download.csdn.net/download/egostudio/88949421

如果需要免费下载该资源包,请加群获取。

该工具基于GitHub开源dotnet-ExtractUnityPackage进行了修改,解决了里面的一点报错,如果需要源码可以访问这里。GitHub - ufcpp/dotnet-ExtractUnityPackage: A dotnet global tool for extracting .unitypackage

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/1019415
推荐阅读
相关标签
  

闽ICP备14008679号