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

13 篇文章 0 订阅

使用场景

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

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

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

工具包内容如下:

使用说明

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

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

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

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

程序原理

主要代码

using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Tar;
using System.IO;

namespace ExtractUnityPackage
{
    internal static class Extractor
    {
        public static void ImportUnityPackage(string packagePath, string destinationFolderPath, bool overwrite)
        {
            var tempFolder = Path.Combine(Path.GetTempPath(), Path.GetFileName(packagePath) + ".unitypackage.extract");

            using (var i = new FileStream(packagePath, FileMode.Open, FileAccess.Read))
            using (var gi = new GZipInputStream(i))
            using (var tar = TarArchive.CreateInputTarArchive(gi))
            {
                tar.ExtractContents(tempFolder);
            }

            foreach (var item in Directory.GetDirectories(tempFolder))
            {
                var pathNameData = File.ReadAllLines(Path.Combine(item, "pathname"));
                var pathname = pathNameData[0];
                
                var path = Path.Combine(destinationFolderPath, pathname);

                var assetPath = Path.Combine(item, "asset");
                if (File.Exists(assetPath))
                {
                    var folder = Path.GetDirectoryName(Path.GetFullPath(path));
                    if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);
                    if (overwrite || !File.Exists(path)) File.Copy(assetPath, path, true);
                }
                else
                {
                    var folder = path;
                    if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);
                }
                var assetMetaPath = Path.Combine(item, "asset.meta");
                var metaPath = path + ".meta";
                if (File.Exists(assetMetaPath))
                {
                    if (overwrite || !File.Exists(metaPath)) File.Copy(assetMetaPath, metaPath, true);
                }
            }

            Directory.Delete(tempFolder, true);
        }
    }
}
using McMaster.Extensions.CommandLineUtils;
using System.ComponentModel.DataAnnotations;

namespace ExtractUnityPackage
{
    [Command(Description = "A global tool for extracting .unitypackage", Name = "dotnet ExtractUnityPackage")]
    public class Program
    {
        [Argument(0, Description = "source .unitypackage path")]
        [Required]
        public string Package { get; }

        [Argument(1, Description = "destination folder path")]
        [Required]
        public string Destination { get; }

        [Option("-o|--overwrite", Description = "overwrites if file exists")]
        public bool Overwrite { get; }

        static void Main(string[] args)
        {
            CommandLineApplication.Execute<Program>(args);
        }

        public void OnExecute()
        {
            Extractor.ImportUnityPackage(Package, Destination, Overwrite);
        }
    }
}

 原理解析

通过上面的主要代码,我们可以看到其实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

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鱼蛋-Felix

如果对你有用,可以请我喝杯可乐

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值