工程的入口CS
默认为false,也就是当程序在后台时暂停。
软件层面是关不掉硬件VSync的,所以软件层面都是通过生命周期函数,每帧判断一下时间,然后决定是否等待。一般游戏都会限制到30FPS,否则虽然帧率高了,但是由于计算量负荷太大,发热就快了。目前,基本操作都是将QualitySettings.vSyncCount设为0,然后通过Application.targetFrameRate来控制游戏FPS,详见在Unity中实现准确的帧率(Patrick:其实在这里我心里有个疑问,硬件层是可以通过双缓冲或者三缓冲来实现,不知道这里的设置是否会影响这个选择,目前我的测试感觉两者好像没关系。但是Unity3d 用户文档圣典1.0中表达的意思,感觉两者有一定关系。)
使得游戏运行的过程中不自动锁屏。相应的,一定要做好处理,用户一段时间不操作,降低屏幕暗度,降低游戏帧率和画质等。以防手机过热。
获取手机的设备信息,并根据此进行分级。典型的就是上述这个接口,如果手机支持HSR,那么绘制顺序可以根据状态切换来处理,否则,就要按照不透明从前到后的渲染顺序,以防过度的OverDraw。
Cinemachine也是个大模块,先跳过吧。
游戏可以选择使用NGUI、UGUI、Faiygui。但是Unity原生支持UGUI,其他的都需要初始化一些东西。所以一般游戏刚打开时候的Loading图都会使用UGUI,对应的Loading图的资源也会直接放到Resources文件夹中,跟着包走(而非AB)。里面包含登录等一些游戏逻辑。
如果屏幕宽高比大于1.28,小于1.45,则认为它是pad,然后背景图片需要使用高一点的图片。
比如:渠道信息、App版本号、资源版本号、App下载路径、资源下载路径、App下载的方式、资源下载的方式、库下载的方式、debug/release、登录所需资源的版本、登录所需资源下载的方式等
调试日志特别影响性能,所以release一定要关闭。看性能也要用release看。print其实是对Debug.Log的封装,详见print和log的区别
真机默认使用AB模式,安装包中的AB资源会被放到StreamingAssetsPath路径下(原始AssetBundle存放路径),使用热更新下载(API UnityWebRequest)下来的AB资源会被放到persistentDataPath路径下(补丁AssetBundle存放路径,优先从这个路径加载资源)
从disk中,通过路径从文件同步加载一个AB。支持压缩格式的bundle,比如lzma压缩格式,数据会被自动解压缩到内存中,chunk压缩格式或者未压缩的数据可以直接从disk中被读取。与AssetBundle.LoadFromFileAsync唯一的区别就是同步的,AB被加载后才会返回。
创建LuaState和LuaLooper。
显示游戏初始界面
获取当前设备的联网模式,但是不能通过该接口判断是否联网,因为可能只是连了一个热点。非手持设备始终返回NetworkReachability.ReachableViaLocalAreaNetwork
实例化Timer类,设置间隔时间为1000毫秒;
到达时间的时候执行倒计时事件timeout;
设置是执行一次(false)还是一直执行(true);
需要调用 timer.Start()或者timer.Enabled = true来启动它, timer.Start()的内部原理还是设置timer.Enabled = true;
调用 timer.Stop()或者timer.Enabled = false来停止引发Elapsed事件, timer.Stop()的内部原理还是设置timer.Enabled = false,最重要的是timer.Enabled = false后会取消线程池中当前等待队列中剩余任务的执行。
在Timer时间内下载完资源后,就开始加载AB了
从MainScript中触发了两个大的模块,Lua和AB,先看AB
这里涉及到AssetsManager、AssetsInfoManagerr、AssetsInfoInit和ResourceRequest四个大类,主要就是根据版本号,对AB进行下载。
另外,就是这里会下载shader相关的ab,然后根据需要进行warmup,以及下载SRP对应的ab,然后根据条件设置给GraphicsSettings.renderPipelineAsset。并在Camera上挂载PostProcessLayerEA组件和EA_GameMainRendererSetup组件。
下载lua和lua_bin这两个ab,然后通过LuaManager.Instance.CreateLuaState确保LuaState和LuaLooper创建好了,然后通过LuaManager.Instance.StartMain,开始从Lua的入口文件Game.lua,对应的OnInitOK这个入口函数开始执行。
嗯,作为lua小白,先去读了文档Lua 教程,然后再看代码
首先,luajit分为jit模式和interpreter模式。我们的建议是,继续使用luajit,但是对于一般的团队而言,使用interpreter模式。详情参考文章用好lua+unity,让性能飞起来——luajit集成篇/平台相关篇。我们的项目使用的是interpreter模式。所以,在Game.Lua中,先将luajit关闭了。
然后,借用LuaLoop的机制,将函数PreUpdate加入event.lua中的update中,将函数OnUpdate加入event.lua中的update中。
原创技术文章,撰写不易,转载请注明出处:电子设备中的画家|王烁 于 2020 年 4 月 17 日发表,原文链接(http://geekfaner.com/unity/blog18_UnitySourceCode.html)