制作一个承载想法的东西(十二)—— 图片加载、HTTP封装

  • A+
所属分类:Unity3d 原创文章

在资源加载中,说了加载场景和Prefab,并不完全,还有材质、图集、贴图、远程加载东西等等。后面用到了再做补充。其实加载的流程都是一样的,这里补充一下图集和远程图片加载,完善一下UIImage组件。

 

一、图集的打包

这里需要定制一个规则,编写扩展工具,进行图集的打包。这里的规则是搜索打包目录下的所有名字叫做Atlas的文件夹,然后将这些目录及其子目录分别打成一个图集。将Atlas下的目录也打成一个图集的理由是防止这个模块下的图集太大,可以分开成多个图集。可以根据项目的需要设置打包图集的相应参数,可以做检测图集大小的工具做约束和警报等。

 

二、加载图集和精灵

为了减少lua和c#之间的交互,可以在lua侧缓存加载过的图集和精灵,在有缓存的情况下可以直接在lua侧返回结果。同时为了控制内存的使用,需要做一个缓存大小的控制,如果加载的资源全部都缓存,在有些图片资源非常丰富的时候就会造成内存占用越来越大。有一个LRUCaches算法就可以很好的处理这一个情况,给定一个最大的缓存大小,再不够的时候会吧最近最少用到的资源缓存替换掉。

SetCheckCanPopCallback设置是否可以清理缓存,SetPopCallback设置要删除的需要处理的回调

 

图集和单个的Sprite的加载和卸载方式有所不同,所以这里要创建两个缓存池,一个管理图集和通过图集加载的Sprite,一个管理单个Sprite。可以看到通过SetCheckCanPopCallback设置是否可以清楚缓存的条件是引用计数为0的时候,对于使用图集加载的Sprite在卸载的时候直接销毁就行了。在上面说了图集打包识别的是Atlas目录,所以在加载的时候通过__GetSpriteInfo分析路径是通过图集加载还是单个的Sprite加载,并且可以分析出哪个图集的address和子Sprite的名字。

 

三、Http封装

封装Http是为了更好的调用,对http的get、put、post、加载文件的方法和请求头及参数的传递进行封装成一些方便调用的方法。在加载远程图片的时候,对于不是重新加载的图片会优先在本地查找缓存,新的远程图片加载会缓存到黑匣子目录中,在lua层进行管理。

 

其中的HttpOperationData是提供给lua层做异步处理用的,完成后可以通过它获取到相应需要加载的资源。

 

Lua侧对C#提供的接口进行调度。

 

 

四、远程图片的加载

和图集和Sprite的加载类似,我们也使用缓存来优化加载速度和lua与c#的交互。同时在加载完成后管理保存到本地中,加快下次加载的速度和流量的时候。同时,有了保存到本地的这个机制后,就需要提供一个重新网络加载的机制,因为有可能的是这个本地图片已经过时了,那么就需要重新到网络上下载。那么缓存就不能用原来的缓存了,但是这个又不能卸载,因为有可能有些地方已经用了旧的了。可以考虑在重新加载完成后发送一个事件,接收到事件的为使用旧资源的Image,然后更新为最新的,这样的引用计数就对了,然后旧资源也可以安全卸载了。考虑到大有可能的是使用旧资源的Image是不在激活状态的,所以,我这里在Reload的时候,做了一个资源缓存的栈,保存多个资源,保留原来的引用计数,获取的时候永远返回最新哪个资源。当引用计数为0的时候,就把栈中的资源全部卸载,这样就安全了。

远程下载的资源为Texture2D的格式,在需要使用Sprite的格式时候,需要通过Texture2D来创建一个Sprite。所以这里也是保存两个缓存池,Sprite的引用计数影响Texture2D。

 

五、UIImage组件加载图片和远程图片

需要注意的是加载都是异步的,在设置的时候需要考虑连续设置的问题,例如第一个设置后异步加载比第二次加载慢,那么显示的就不是你最新加载的了。还需要考虑加载远程图片和加载本地图集之间的切换情况和连续设置的情况,要留好状态来表示。不需要用到的资源要通过管理器去释放保持引用计数的正确性。

 

通过Texture2D创建Sprite:

 

 

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: