YooAsset学习笔记3:编辑器

前言 上一篇文章简述了YooAsset资源管理框架运行时的框架的使用,接下来通过代码分析其内部原理。 概览 YooAsset框架的编辑器部分包含了四个部分。 收集:通过过滤规则,资源包名,定位地址,划分打包资源。 构建:根据收集到的资源,同时收集其依赖资源,打包成Bundle包。 Reporter:打包后的资源报告。 Debugger:运行时的资源加载情况。 收集 收集器主要通过过滤规则,资源包名,定位地址来划分资源,具体的用法在使用文档有详细介绍,本系列的第一篇也有介绍。 构建 资源构建也是和运行时的设计相似,按步骤构建,流程如下图所示。 构建管线分为内置管线,可编程管线,原生管线,内置管线和可编程管线的构建步骤基本一致,调用的API有不同。原生管线就是直接复制文件,不构建Bundle。 总结 编辑器的框架就是如此,先收集再按步骤构建,再配套Reporter和Debugger进行排查分析。 本系列教程到此结束,感谢阅读。 参考 https://github.com/tuyoogame/YooAsset

2024-6-29 · Dand

YooAsset学习笔记2:运行时

前言 上一篇文章简述了YooAsset资源管理框架的使用,接下来通过代码分析其内部原理。 整体框架 YooAsset框架主要分为运行时和编辑器部分,运行时实现了资源包加载,Bunlde加载,缓存,下载,从上到下的结构。编辑器部分实现了资源收集,资源构建。这篇文章主要分析运行时的机制,结构如下。 加载流程 运行时加载流程主要如下,加载开始以后,每一层的模块基本都是轮询实现。 简单的例子就是调用加载,从上到下,上层等待下层完成自己的步骤,如果完成,再轮询到下个阶段。 每一层根据加载模式和资源类型的不同派生到不同的对象负责轮询,下面的示例是远程加载AssetBundle的示意流程。 根据运行模式初始化包 外部调用加载 调用默认包的加载 Provider轮询,等待Bundle加载完成,再从Bundle中加载具体资源 Loader轮询,等待Bundle加载完成 Downloader轮询,等待下载完成 Requeseter轮询,等待请求完成 资源包(ResourcePackage) 资源包是一个比较上层的概念,在游戏初始化时要初始化包和其加载模式。具体的加载模式可以参照上一篇文章。 定义加载模式 维护版本 维护资源清单 资源管理器(ResourceManager) 资源管理器负责加载具体的资源,根据不同的加载模式和资源类型分成不同的Provider和Loader,并返回对应的Handle。 Provider功能:从加载好的Bundle中加载具体的资源 Loader功能:加载Bundle。 下载系统(DownloadSystem) 下载系统由上层的Loader持有,加载Bundle时,如果还没下载,调用下载系统进行下载。 下载器根据不同的加载模式和资源类型区分,分类普通文件和Web文件,区别在于Web文件不进行缓存。 下载功能由Requester承担,分为普通请求和断点续传。 缓存系统(CacheSystem) 缓存系统是在加载资源时,下载过就不需要再次下载了,直接在本地沙盒目录中读取。 缓存系统由下载系统调用,当下载完成以后,保存本地文件,并记录到缓存系统。 如果已有文件,则进行校验再进行记录。 另一个调用是在资源包初始化后,把已经下载的文件验证一遍,记录到缓存系统中。 后记 运行的框架就是如此,虽然功能很多,但结构清晰,使用了分层处理的思想。 下一篇将介绍编辑器的逻辑,敬请期待。 参考 https://github.com/tuyoogame/YooAsset

2024-6-14 · Dand

UI特效插件-UIParticle

前言 在UI上显示特效是一直是一个比较棘手的问题,一开始的方案是调整UI特效的渲染顺序,设置其sortingLayer和sortingOrder+offset,在每个单独的UI以后渲染。 这种方法能满足大部分的需求,但也有缺点。 如果需要在特效上再盖一层UI的话,由于特效并不属于Canvas的一部分,所以修改Hierarchy并不能改变其渲染顺序,特效会在渲染完Canvas的UI元素以后再进行渲染,所以需要把这个UI的层级通过添加Canvas继续往上抬。 再者无法被RectMask2D和Mask裁剪,除非改造Shader,并手动传入裁剪区域。 最好的方法就是让特效像UI一样,直接按Hierarchy 顺序渲染,并支持遮罩,就是这文章的主角UIParticle。 原理 This package utilizes the new APIsMeshBake/MashTrailBake(introduced with Unity 2018.2) to render particles through CanvasRenderer. You can render, mask, and sort your ParticleSystems for UI without the necessity of an additional Camera, RenderTexture, or Canvas. 这是项目首页的原理,具体就是通过一个API让例子特效通过CanvasRender进行渲染,这样就和普通的UI没什么不同了。 使用 按官方的教程,直接引入包,添加组件到特效上,直接拖到UI中即可。 改造已有shader以支持遮罩 项目推荐我们使用UIShader,如UIDefault或者UIAdditive。 Mask通过模板测试实现遮罩,RectMask2D通过传入裁剪区域实现。 所以自定义的Shader只需要参考上面的UIShader使其拥有遮罩特效即可,注意RenderQueue设置为Transparent,下面贴一下关键Shader代码。 Shader "Your/Custom/Shader" { Properties { // ... // #### required for Mask #### _StencilComp ("Stencil Comparison", Float) = 8 _Stencil ("Stencil ID", Float) = 0 _StencilOp ("Stencil Operation", Float) = 0 _StencilWriteMask ("Stencil Write Mask", Float) = 255 _StencilReadMask ("Stencil Read Mask", Float) = 255 _ColorMask ("Color Mask", Float) = 15 [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 } SubShader { Tags { // ... } // #### required for Mask #### Stencil { Ref [_Stencil] Comp [_StencilComp] Pass [_StencilOp] ReadMask [_StencilReadMask] WriteMask [_StencilWriteMask] } ColorMask [_ColorMask] // ... Pass { // ... // #### required for RectMask2D #### #include "UnityUI.cginc" #pragma multi_compile __ UNITY_UI_CLIP_RECT float4 _ClipRect; // #### required for Mask #### #pragma multi_compile __ UNITY_UI_ALPHACLIP struct appdata_t { // ... }; struct v2f { // ... // #### required for RectMask2D #### float4 worldPosition : TEXCOORD1; }; v2f vert(appdata_t v) { v2f OUT; // ... // #### required for RectMask2D #### OUT.worldPosition = v.vertex; return OUT; } fixed4 frag(v2f IN) : SV_Target { // ... // #### required for RectMask2D #### #ifdef UNITY_UI_CLIP_RECT color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect); #endif // #### required for Mask #### #ifdef UNITY_UI_ALPHACLIP clip (color.a - 0.001); #endif return color; } ENDCG } } } 总结 至此已经可以像UI一样使用UI特效了,具体的性能分析,参考一下首页。 ...

2024-6-6 · Dand

使用状态机初始化游戏

前言 最近在写游戏demo的时候,在写初始化流程的时候遇到一些问题,一开始通过回调函数来控制初始化流程,并不直观,也不好分离逻辑。进入游戏以后首先是准备好必要的资源,通过YooAssets进行加载,加载完成以后再进行游戏系统的初始化。一开始是在资源加载接口加了回调,加载完以后再进行游戏初始化,但不够优雅,如果需要更多的流程控制会写得比较乱。 最后用状态机实现游戏初始化的流程,首先就是要写一个有限状态机了,参考了一下开源的项目,这里总结一下。 状态机 管理状态:启动,状态转换,管理状态的生命周期 数据处理能力:增删查数据,状态中可以使用这些全局数据 状态 状态定义具体的逻辑,有OnInit,OnEnter,OnUpdate,OnLeave,OnDestroy生命周期。状态内调用状态机进行状态的切换。 UML类图 参考 GitHub - EllanJiang/GameFramework: This is literally a game framework, based on Unity game engine. It encapsulates commonly used game modules during development, and, to a large degree, standardises the process, enhances the development speed and ensures the product quality. UniFramework/UniFramework at main · gmhevinci/UniFramework

2024-6-2 · Dand

YooAsset学习笔记1:接入流程

2024-5-21 · Dand