1.【Unity开源项目精选】AssetStudio:提取Unity游戏的资源
2.Unity - Addressables项目总结(一):基础工作流
3.十一重新起步
4.如何防止unity3d代码被反编译?
5.游戏开发工具箱(4) 游戏框架秘籍——使用Game Framework进行资源更新(中一)
【Unity开源项目精选】AssetStudio:提取Unity游戏的资源
大智,你的技术探路者,带您探索Unity开源项目之AssetStudio,一个用于挖掘、提取及导出Unity游戏资源的利器。
AssetStudio,ntddk.h 源码源码地址:github.com/Perfare/Asse...
这个工具专为Unity游戏开发者设计,帮助您轻松获取游戏资源。无论您是寻求灵感,还是希望深入研究游戏内部结构,AssetStudio都是理想选择。
使用AssetStudio,您能够探索、提取和导出asset和assetbundle,解锁Unity游戏资源的秘密。这个开源项目为开发者提供了便利,让您能够快速、高效地进行资源管理。
我是大智,技术探路者,下期再见。别忘了点赞、收藏,与更多开发者共享这份宝贵资源。
Unity - Addressables项目总结(一):基础工作流
近期未更新,现已投入新项目,初期采用Addressables进行资源管理。需对资源从打包、发布、运行时进行完善,期间遇到不少问题,也有不少难以理解的使用方式,现记录如下。
一、综述 & Start
1.1 综述
Unity默认的资源打包发布方式是AssetBundle,Addressables在AssetBundle基础上,处理了资源在项目整个流程中的管理。具体涉及资源打包、源码+定制rom加载与卸载以及热更。传统的AssetBundle对于资源管理来说相对繁琐,主要体现在以下几个方面:
对于成熟的项目,通常已有一套完善的工具链,可能对于部分打包步骤不太直观方便,但整体流程较为完善,一般也不用考虑Addressables。如果是在项目前期,Addressables可能是一个不错的工具,其功能特性如下:
1.2 Start
(1)安装
(2)拉取Package到本地
在Package Manager中拉取的内容是无法修改的,若需要修改源码,则需要将Cache文件夹中的缓存放到Package(包括依赖package)
(3)标记资源:将资源或文件夹放入对应Group即可
(4)配置Profile
只需要配置远端路径(Http服务可使用Addressables自带的Host Services,但建议使用HFS方便测试)
(5)发布资源
Addressbales提供了两种资源发布模式:全量发布;增量发布
(6)选择Play Mode & Start
fastest模式通过AssetDatabase加载资源,Editor下不需要发布资源。Existing Build会真实得加载AB包,Editor下需要打包资源。
二、Settings
2.1 AssetGroup
Addressbales以GUI的方式较为便捷得对资源进行分组打包管理。默认每个分组的资源文件存在于AddressableAssetsData/AssetGroups目录下,分组可以使用相同策略对资源批量管理。
选中Group可以看到其属性面板。Build & Load Paths定义Group的打包与加载路径,该路径可在Profile中修改。包体分为本地包与远程包。
Group提供三种压缩方式:无压缩、LZ4、LZMA。LZ4包体大小中等,解压较快,可以只解压部分资源;LZMA包体较小,但解压资源较慢,只能将资源全部解压。通常选择LZ4。
这三个选项表示打包时,是否将资源的Address、GUID、Label写入包体中。全网通+源码对于有分包更新需求的情况下,建议都勾选上。
Internal Asset Naming Mode:如何为内部asset命名
Asset Load Mode、Asset Provider、Asset Bundle Provider通常不用修改,这三个选项用于控制asset的加载方式、AB包的获取方式。如果存在自定义的处理方式,可自行选择。
2.2 AddressableAssetSettings
Profile定义了各种路径参数,切换不同的路径以灵活映射到的路径。(修改路径后需要重新Build资源后才能生效,因为locator的下载路径是在Build时序列化到本地的。体验上不太舒服~~)
Addressables提供了三种Editor下资源加载方式:Use the Asset database(Asset database加载)、Simulate groups(模拟Group处理)、Use existing build(加载实际包体资源)
三、打包处理
3.1 打全量包
处理步骤如下: (1)根据需求配置Group的构建路径(Remote\Local) (2)根据远端路径(CDN\HFS)修改Profile,选择需要的Profile (3)修改资源版本号(如果只是本地测试不需要,但若是正式发布需要修改,避免影响老版本) (4)点击New Build/Default Build Script进行资源打包 Profile定义Build和Load路径,若需要从多个项目加载资源的情况(比如美术、Scene单独分离出工程进行制作),可以定义不同的Profile以满足需求。对于大部分工程来说,通常不需要修改local资源相管路径,这些工程会构建到相同的目录中。 注意:路径字符(以及自动生成的子目录)长度限制在个character,否则会构建失败 默认的local build路径:Library\com.unity.addressables\aa\平台\系统 默认的local load路径:Editor模式与构建路径相同;实机运行时被解析为StreamingAssets目录 Build输出文件:
注意:使用默认的local路径,在构建应用时,Addressbales会将打包资源拷贝到StreamingAssets目录,在应用构建结束后再将资源移除。如果使用自定义的local路径,需要自己处理这一过程。 默认的Remote Build路径:ServerData\平台 默认的Remote Load路径:为实际的下载url,必须要启用相管服务(CDN\HFS)后自行定义。 构建的文件:
3.2 打增量包
全量包会重新构建所有资源,当我们只需要对一部分资源修改时,源码授权方式这会产生很多不必要的工作。Addressbales提供了根据资源更新记录进行增量式更新
需要注意的是,能够进行增量式更新的前提是存在addressables_content_state.bin文件,并且不能修改资源版本号。此文件记录了资源的状态数据。当我们构建全量包时,会在“Assets\AddressableAssetsData\平台”创建该文件,一定不要手动修改此文件。只有相同版本号的catalog才会检测差异,从而更新。
四、运行时的资源
4.1 资源加载
Addressables提供了通过address、label、AssetReference以及IResourceLocation进行资源加载。在执行异步操作时,会执行以下流程:
若加载失败,相关信息会存储在AsyncOperationHandle.OperationException。默认情况下,加载失败不会抛出异常,如果需要可以为ResourceManager.ExceptionHandler设置回调。此外还可以通过设置抛出异常。
4.2 资源卸载
通过 Addressables.Release可以卸载资源、实例、handle。释放handle可以减少资源的引用计数,并且handle会失效。如果不需要使用回调结果,某些API接口提供了自动的handle回收参数,例如 UnloadSceneAsync。 即便handle回调失败了,仍然需要对其进行释放。通常情况下,Addressables会自动释放Operation失败期间的资源,但手动释放handle仍然是有必要的。 Addressables.LoadAssetsAsync是无法取消的,但如果在操作完成之前释放对应的handle,会减少对handle引用,gcode+源码在资源加载完成后会自动释放。
十一重新起步
哈,没想到吧,本专栏还有再次更新的一天。
其实是看到这个之后,决定把热更新也整合进去。既然要整合热更新,那现在的框架不得不重新写一次,因为代码最终要编译成Dll的。
这次重写的话,我做出了如下选择:
脚本语言:xLua
Unity版本:Unity .3.5 (VS)
文件夹设置:游戏工程的建立
没啥好说的,中规中矩建一个3D工程。随意新建一个脚本,用VS打开,在“解决方案管理器”视图找到Unity相关的引用,其属性为:
把路径里用到的东西打包复制到Dll工程的3rd目录下,供Dll工程引用。然后再找到pdb2mdb.exe和mono.exe:
如果电脑里有多个Unity版本,则可能会有多个该程序,选择对应版本的即可,等下要用的是路径,pdb2mdb.exe是DLL的调试符号转换器,不生成mdb就没法调试DLL中的代码。
类库工程建立
依旧是中规中矩创建一个类库的工程。先添加刚才准备好的Unity相关程序集引用,然后打开项目属性,设置生成后事件:
此处就使用了mono和pdb2mdb的路径,生成之后复制到游戏工程中。这里随便写了一个测试类,在游戏工程中可见,Dll中已经有这个类了。
打上断点,挂上调试。然后运行游戏工程,好的,成功断住:
接入xLua
将Plugin放进游戏工程中,将Src下的源码分别放进Editor目录和DLL工程中,测试一下:
没毛病,成功启动Lua虚拟机。接下来就是要配置xLua,选择一些可能要在Lua端使用的C#内容,按照xLua文档所示,直接整个静态类静态List,把要用的东西码入。
这里我根据个人的判断添加了如下内容:
然后调整一下配置生成器的路径:
然后执行一下生成命令,更新Dll工程,然后编译一下。是时候测试了。
也确实打印出来了“hello”字样。
API定义生成
写这种脚本语言,没有个编辑和调试插件其实是挺蛋疼的。这里推荐luaide,直接在vscode插件里找就可以,收费也比较便宜。
不过暂时还没有用它的打算,而是先接入它的api定义生成,这样编写Lua的时候可以相对直观的看到C#中一些api和数据的写法。
放进工程目录之后,修改导出路径,然后注释掉LuaIdeApi.cs里的菜单标签和自动生成;在xlua的生成函数末尾添加LuaIdeApi的生成即可。
这样,每次生成xlua内容的时候就会自动把api定义也更新,可以说是非常完美。
VS Code准备
用VS Code打开了Lua文件夹之后,会发现Unity生成的.meta文件也被计入了其中,因此我们要设定过滤,保证VS Code开发环境的清爽:
另外我比较习惯折叠代码,这点VSCode的Lua样式还没有,手动打开配置一下:
加载Lua
在编辑器下的开发应当越快越好,越高效越好,所以加载的时候,就有必要设计一种编辑器下的加载模式,跟使用AssetBundle或者其他自定义数据存储形式的生产环境不同,该模式应当做到修改Prefab\Lua等资产之后,无需打包即可立刻启动。
因为是为了测试xLua的加载,所以一切从简:
其中LoadContext是一个发起加载的上下文,该结构我暂时还没想好填充什么,不过也无关紧要,对于现在的测试来说,只要保证LoadLua方法可用就行。
这里使用System.IO.File而不是用AssetDatabase的原因是,“*.lua”在Unity中会被认为是DefaultAsset,无法被当做TextAsset处理。
在测试用的MonoBehavior类中用require('Game/Game'),打印成功。
Lua的class实现
才疏学浅,自己写的果然又长又臭,这里使用了quick-cocos2d-x的实现,但是因为我并没用到什么native C++的东西,所以大笔一挥,只保留了基本的Lua Object的内容:
好,我们来稍加测试一下:
表格的使用
将Excel表格生成成如下形式,代码可参照之前的内容:
使用一个_Data.lua来封装所有对数据表的查询操作:
测试,然后通过:
如何防止unity3d代码被反编译?
防止Unity3D代码被反编译是手游安全中常见的破解风险。Unity的破解风险主要体现在Unity mono脚本解密、Unity il2cpp脚本解析、Assetbundle资源篡改三项。mono脚本文件的二进制形式及源码转换图示,展示了如何对mono脚本进行解密。Il2cpp脚本解析则需要使用Il2CppDumper工具,解析后能获得类名、函数名以及对应偏移信息。尽管iOS中还无法解析为源码,但Android的有效脚本加密对于防止破解尤为重要。Assetbundle资源篡改,如修改材质属性,可实现透视效果,同时还有资源被竞品**、分析的风险。存档数据被修改也是安全问题,如果数据不进行服务端校验或为单机游戏,游戏属性修改风险巨大。保护Unity安全时,自研保护系统面临高成本、兼容性问题、对抗破解的持续升级和第三方服务兼容性挑战。网易云易盾提供了Unity mono DLL脚本加密、IL2CPP加密、Assetbundle加密等解决方案,通过修改或HOOK mono_image_open_from_data_with_name函数,实现对CSharp DLL脚本的加密,以防止其被解密。Unity mono DLL脚本加密经历了从直接文件加密到抹掉PE头、再到方法级加密的三代技术演进。IL2CPP加密则需结合global-metadata.dat文件内的符号信息进行解析,通过SO加壳保护libil2cpp.so来实现。Assetbundle加密后,Unity Studio无法解析资源。网易易盾保护方案特点包括纯Native保护、对引擎SO做加壳、兼容性和稳定性高、性能影响小,支持多平台加固。在选择保护方案时,应考虑DEX加壳的兼容性和安全性问题,而网易易盾提供的纯Native保护方案为手游提供了一种更加安全和兼容性强的解决方案。
游戏开发工具箱(4) 游戏框架秘籍——使用Game Framework进行资源更新(中一)
在上文中,我们概述了游戏框架的基础和启动流程,接下来,我们将深入探讨E大开源的Unity通用游戏框架——Game Framework,它在资源管理和更新方面展现出高效性。框架结构与职责
Game Framework由两大部分构成:独立于Unity的纯C# Game Framework模块,以及封装Unity特性的Unity GameFramework模块。这种模块化设计确保了跨引擎的可复用性,只需替换Unity部分即可迁移至其他平台。 尽管更新频率不高,但Game Framework的设计具有通用性,确保在Unity更新大改动时,框架结构依然稳定,避免频繁添加新模块。 框架的核心职责在于提供底层模块,如流程管理、消息传递、文件管理与资源管理,而非游戏业务逻辑,如动态资源下载和更新,留给开发者更大的扩展空间。功能扩展与示例项目
Game Framework的接口设计便于开发者对其进行修改和扩展,尽管表格和本地化支持可能有待提升,但灵活性极高。官方示例项目Star Force在GitHub上供下载,它是Unity GameFramework的子模块,也可独立下载并集成到Unity .3.f1的工程中。资源管理与更新流程
Unity引擎通过封装,简化了游戏开发过程,提升效率。首先,将Unity GameFramework文件复制到项目文件夹,然后以管理员权限运行HFS Http文件服务器,配置BuildInfo.txt以指向资源服务器地址。 在资源打包阶段,AssetBundle会自动复制到StreamingAssets文件夹。Resource Editor工具提供直观操作,修改资源后记得保存。通过Resource Builder设置导出目录、压缩方式和版本信息,点击Build进行资源包生成。 资源包结构包括Package单机模式和Updatable可更新模式,我们选择Package模式打包,然后通过Build Settings调整分辨率,选择Windows平台打包游戏。运行新版本验证资源更新流程,包括本地资源服务器的配置和资源版本管理。资源更新关键步骤
打开导出资源目录,注意其文件结构,包含 BuildReport、Full、Package、Packed 和 Working 文件夹。
在BuildInfo.txt中配置资源服务器版本信息,客户端与服务器版本对比,下载必要资源。
整合资源包,完成后进入游戏,检查资源版本一致性。
资源更新成功后,飞机贴图变更,体验游戏资源动态更新的便利性。
困惑解答
对于GameFrameworkVersion.dat,它是资源版本的“数据库”,包含压缩和未压缩版本信息。GameFrameworkList.dat则记录游戏中已下载的资源,单机模式下不需要,但在更新模式下用于记录资源下载状态。 资源包整合是通过Game Framework的VFS实现的,减少了文件数量,优化性能。在ResourceCollection.xml中添加FileSystem属性配置资源包在虚拟文件系统中的结构。深入学习与源代码探索
通过官方示例深入了解资源更新流程,无需深入代码。未来文章将逐步深入到Game Framework源代码层面,搭建游戏框架。请关注,我们下期将继续解析Game Framework的实现细节。