谈谈AssetStore及其脱离Unity下载方法

AssetStore一直是Unity开发者又爱又恨的东西。首先这个生态绝对是先进的,并且越来越能够吸引高质量的开发者开发或开源他们的插件。它的缺点可能是大陆开发者尤为头疼的。

1、付费,客观的看99%的资源价格都在100刀以内,先不论个人开发者能否完成同样功能的开发,即使可以,也绝对值回工时费了。

2、网络,没有验证过在国外是否都能流畅下载,至少使用电信、网通的“局域网”都十分痛苦。

3、断点续传,AssetStore的资源下载过程中一旦网络异常或关闭Unity,都只能“从0开始”。


我们都知道AssetStore下载到Windows本地的路径是C:\Users\用户名\AppData\Roaming\Unity\Asset Store-5.x\开发者公司名\插件名\xxx.unitypackage。

下载过程中会有如下2个文件生成,在目录下持续F5,TMP文件体积会增长。



而JSON文件由url和key组成。

{"download" : {"url" : "http://d2ujflorbtfzji.cloudfront.net/download/950fd1fa-e786-4587-8180-13f83f057c52", "key" : "b370540fa8321d35e84cedafc7565512b69f06ae73cf07c589db3899a1b0cd4555c11dc3eae8561271d18d9012106263"}}


url很明显可以拷贝到任何下载器中下载,但下载完的文件即使手动添加后缀.unitypackage,也无法导入unity中使用。



后来查阅参考资料,发现可以通过key来解码,代码如下。 

using System;
using System.Reflection;

namespace Babybus.Framework.ExtensionMethods
{
    public static class AccessExtensions
    {
        public static T InvokeConstructor<T>(this Type type, Type[] paramTypes = null, object[] paramValues = null)
        {
            return (T)type.InvokeConstructor(paramTypes, paramValues);
        }

        public static object InvokeConstructor(this Type type, Type[] paramTypes = null, object[] paramValues = null)
        {
            if (paramTypes == null || paramValues == null)
            {
                paramTypes = new Type[] { };
                paramValues = new object[] { };
            }

            var constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, paramTypes, null);

            return constructor.Invoke(paramValues);
        }

        public static T Invoke<T>(this object o, string methodName, params object[] args)
        {
            var value = o.Invoke(methodName, args);
            if (value != null)
            {
                return (T)value;
            }

            return default(T);
        }

        public static T Invoke<T>(this object o, string methodName, Type[] types, params object[] args)
        {
            var value = o.Invoke(methodName, types, args);
            if (value != null)
            {
                return (T)value;
            }

            return default(T);
        }

        public static object Invoke(this object o, string methodName, params object[] args)
        {
            Type[] types = new Type[args.Length];
            for (int i = 0; i < args.Length; i++)
                types[i] = args[i] == null ? null : args[i].GetType();

            return o.Invoke(methodName, types, args);
        }

        public static object Invoke(this object o, string methodName, Type[] types, params object[] args)
        {
            var type = o is Type ? (Type)o : o.GetType();
            var method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, CallingConventions.Any, types, null);
            if (method == null)
                method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

            return method.Invoke(o, args);
        }

        public static T GetFieldValue<T>(this object o, string name)
        {
            var value = o.GetFieldValue(name);
            if (value != null)
            {
                return (T)value;
            }

            return default(T);
        }

        public static object GetFieldValue(this object o, string name)
        {
            var field = o.GetType().GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
            if (field != null)
            {
                return field.GetValue(o);
            }

            return null;
        }

        public static void SetFieldValue(this object o, string name, object value)
        {
            var field = o.GetType().GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
            if (field != null)
            {
                field.SetValue(o, value);
            }
        }

        public static T GetPropertyValue<T>(this object o, string name)
        {
            var value = o.GetPropertyValue(name);
            if (value != null)
            {
                return (T)value;
            }

            return default(T);
        }

        public static object GetPropertyValue(this object o, string name)
        {
            var property = o.GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
            if (property != null)
            {
                return property.GetValue(o, null);
            }

            return null;
        }

        public static void SetPropertyValue(this object o, string name, object value)
        {
            var property = o.GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
            if (property != null)
            {
                property.SetValue(o, value, null);
            }
        }
    }
}

Menu工具

using UnityEditor;
using Babybus.Framework.ExtensionMethods;
using UnityEngine;

class DecryptUtility
{
    [MenuItem("Utility/DecryptFile")]
    static void DecryptFile()
    {
        var inputFile = Application.dataPath + "/950fd1fa-e786-4587-8180-13f83f057c52";
        var key = "b370540fa8321d35e84cedafc7565512b69f06ae73cf07c589db3899a1b0cd4555c11dc3eae8561271d18d9012106263";

        var unityEditor = typeof(Editor).Assembly;

        var assetStoreUtils = unityEditor.GetType("UnityEditor.AssetStoreUtils");

        assetStoreUtils.Invoke("DecryptFile", inputFile, inputFile + ".unitypackage", key);
    }
}



这里注意修改inputFile的路径,需要解码的文件名和key值,我的代码对应路径是项目的project文件夹。点击Menu上新增的Utility→DecryptFile,执行上面的代码。进度条读完,一个同名的unitypackage已经生成在目录下了。


把这个unitypackage文件拷到C:\Users\用户名\AppData\Roaming\Unity\Asset Store-5.x\开发者公司名\插件名\ 

路径下,Unity内打开AssetStore,可以看见即使文件没有重命名,系统已经识别该文件存在。



另外笔者实验将不相关的unitypackage重命名靠过来,或低版本的该插件导进来,系统都能识别,结果分别是导入按钮变灰色,及显示更新。key值或许就控制了这些奥妙。



  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
### 回答1: Unity Asset Store是Unity官方提供的一个资源库,可以在其中下载各种Unity相关的资源,包括模型、贴图、音效、插件等等。使用Unity Asset Store需要以下步骤: 1. 打开Unity编辑器,在菜单栏中选择“Window”->“Asset Store”打开Asset Store窗口。 2. 在Asset Store窗口中可以浏览各种资源,可以按照分类、关键字等进行搜索。 3. 找到需要的资源后,点击“Download”按钮进行下载。如果是免费资源,可以直接下载;如果是付费资源,需要先购买。 4. 下载完成后,可以在Unity编辑器中的“Assets”窗口中找到下载的资源,可以直接拖拽到场景中使用。 需要注意的是,使用Asset Store下载的资源需要遵守相应的使用协议,不得用于商业用途等违反协议的行为。 ### 回答2: Unity Asset Store是Unity游戏引擎的一个商店,在这个商店中,用户可以浏览、购买、下载和使用各种游戏开发资源,比如模型、纹理、材质、脚本等。Unity Asset Store的使用非常简单,下面就来详细讲解一下。 第一步,打开Unity编辑器,在窗口上方点击“Window”,然后选择“Asset Store”菜单。这样就会打开Asset Store的窗口。 第二步,在Asset Store的窗口中,可以浏览不同的资源类别,或者搜索特定的资源。您可以使用标签过滤器和搜索框以更快地找到所需资源。 第三步,找到需要的资源后,点击资源卡片以查看详细信息、演示视频、评分、评论等,并查看资源包含的文件和示例。 第四步,如果您决定购买资源,先登录到Unity账户,选择所需的许可证类型,并点击“Add to Cart”按钮。确认购物车中的内容,并点击“Checkout”按钮。跟随屏幕上的指导,完成付款。 第五步,下载资源包,并导入到您的项目中。可以在“Assets”窗口中查看刚才导入的资源。如果资源包含脚本,则需要将脚本添加到场景对象或项目中。 第六步,使用导入的资源完成您的游戏开发工作,可以在您的项目中查看资源的许可证和使用条款。 总的来说,Unity Asset Store可以帮助游戏开发者更快地创建游戏,节省时间和资源,同时提高游戏的品质和体验。希望以上步骤能帮助您了解如何在Unity Asset Store中使用及购买所需的资源。 ### 回答3: Unity的Asset Store是一种在线资源库,可以让Unity用户获得免费或付费的资源,如3D模型、音效、脚本等,以便在游戏开发中使用。在这里,我将介绍Unity Asset Store的使用方法。 第一步:登录Unity账号 首先,你需要有一个Unity账号,如果没有,可以在Unity的官网上注册。注册后,登录您的Unity账号。 第二步:打开Asset Store 打开Unity编辑器,在编辑器左上角点击Asset Store,即可打开Asset Store。在Installer中可以查看与编辑器安装在一起的内容,而在Assets中可以查看和购买或免费下载特定的资产,如:硬表面模型,粒子系统等。 第三步:浏览和搜索资源 在Asset Store的主页面,你可以浏览热门资源,新资产,功能和编辑器扩展,或在搜索栏中输入关键词来搜索你需要的资源。 第四步:选择并下载资源 当你发现需要的资源后,可以单击资源的缩略图,然后查看更多信息,如相关文件、价格、作者等。如果你想要下载或购买,可以单击对应的按钮。在下载和购买之前,您需要确保资源是与您的Unity版本兼容的。 第五步:使用资源 在下载完成后,资源将自动添加到Unity项目中的Asset文件夹中。您可以创建一个新场景,从新的要素窗格中将其拉出。使用资产,您也可以在视图窗口中拖动资源到场景中,然后使用它们来构建游戏内的元素。 总结: Unity Asset Store是一个强大的工具,可以让Unity用户快速而方便地获取所有类型的资源,以便在他们的游戏中使用。使用Asset Store并不需要太多的技能或知识,只需要登录账户,浏览和搜索资源,选择并下载资源,然后在Unity项目当中使用它们。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值