以下文章转载自图形学大神李总老师的博客.
C#Lite是李总自己做的一个开源项目,旨在解决因u3d在ios平台不能动态更新以及lua脚本在u3d上效率低下的问题.作为4年前就给李总当小弟,被李总狂虐的我一定要帮他做做宣传.有需要的朋友可以去/观看持续更新的帖子.
貌似最近他开始讲些图形学的入门捷径.
有兴趣并且不是小白的同学也可以加群一起讨论(群内大神太多了.我只能躲在角落里默默看他们聊天,深怕他们过来把我打了.):
223823428
首先来赞叹一下中文,何谓为何如何,写完才发现这三个词是如此的有规律。
为何赞叹中文?因为这是一篇针对新手程序员的文字,是一节语文课。
然后来做一下说文解字,也就是
何谓热更新
热更新,每个程序员一听就明白,但是它语出何处,究竟表达了什么含义,到底代表了什么,对技术有什么要求,对经验相对较少的程序员来说可能就有一层神秘面纱了。
热更新,是对hot update 或者 hot fix的翻译,计算机术语,表示在不停机的前提下对系统进行更改。
hot 就是热,机器运行会发烫,hot就是不停机的意思。
热更新,是个很形象的词,机器烫的时候更新,开着更新。
比如Windows 不重启的前提下安装补丁
比如Http服务器在不重启的前提下换掉一个文件
那么对于Unity3D来说,何谓热更新?
额……这个真相实在是不想讲出来,因为很多时候,这个词都用错了。
Unity3D是一个客户端工具,用户是否重启客户端,根本是我们不关心的问题。
很多时候我们用着热更新这个词汇,却不需要真的热更新。
只有少部分游戏,游戏资源在玩的过程中边玩边下,不重启的前提下变更了资源。
我们不需要用户不重启客户端就能实现资源代码的更新,我们需要的是用户重启客户端能实现资源代码的更新。
让我们暂时放过这个我们的需求连词汇都用错了这个基本事实,来总结一下何谓Unity3D热更新
Unity3D热更新就是指:用户重启客户端就能实现客户端资源代码更新的需求或者功能。
为何热更新
热更新,能够缩短用户取得新版客户端的流程,改善用户体验。
没有热更新:
pc用户:
下载客户端->等待下载->安装客户端->等待安装->启动->等待加载->玩
手机用户:
商城下载APP->等待下载->等待安装->启动->等待加载->玩
有了热更新
pc用户:
启动->等待热更新->等待加载->玩
有独立loader的pc用户:
启动loader->等待热更新->启动游戏->等待加载->玩
手机用户:
启动->等待热更新->等待加载->玩
通过对比就可以看出,有没有热更新对于用户体验的影响还是挺大的,主要就是省去用户自行更新客户端的步骤。
为了方便用户、留住用户、进而从留住的用户身上赚到钱,热更新如今已经成为了大部分游戏的标配功能。
如果你的游戏不标配这个功能,那么竞争力就会少一些,无论是主动还是被动,无论是方便用户还是被标配,你都必须面对热更新这个课题,虽然这个词用错了。
如何热更新
热更新是为了让用户获得资源和代码的变更,这里的代码不是指真的代码,用户不要代码,他要的是变化的业务逻辑。实现变更的具体过程是首先查并更新本地资源和业务逻辑,如需下载则下载。然后启动时资源均从本地资源创建,业务逻辑从本地执行。
Unity3D提供了一种机制AssetBundle,可以满足所有资源的比对下载加载,但是assetbundle每平台分别打包对于多平台项目而言比较麻烦,是一个明显的短板,而且assetbundle不能脱离unityeditor产生,也是一个麻烦,项目大了话,多人合作,把所有资源都放入assetbundle明显降低效率。
对于代码,Unity3D是不提供变更机制的。但是Unity3D执行核心是Mono,也就是dotnet,dotnet有一种符号反射机制,可以直接加载一个dll,然后反射出其中的类型进行操作。符号和反射的主要问题是有些平台不能使用,比如ios wp8。另外dotnet有一种emit机制,可以运行时调用编译器对代码进行编译,他的问题也是平台不支持。
以上两点是Unity3D免费赠送给你的帮助
如果不能满足你的需求,你就需要自己搞定三个模块:
资源下载模块
当assetbundle不能满足需要时,我们需要自己建立检查更新需要则下载的机制,也就是资源下载模块。
这个资源下载模块应该有一个版本生成工具,我们将一组文件生成一个一个版本待下载。
有一个Unity3D用的下载模块,下载模块会首先检查服务器上的版本信息,和本地信息做比对,需要的文件则下载。
资源加载模块
然后需要建立自己的从下载保存在本地的文件中加载出资源的机制,也就是资源加载模块。
资源加载模块负责从下载的文件中加载出资源。
如果你希望游戏带有一份初始资源文件,这里有两种思路
一种是资源加载模块直接提供从包内文件和下载文件两种加载路径
一种是游戏第一次启动时,将包内文件全部copy到下载文件
脚本模块
当符号反射不能满足需求时,业务逻辑更新就只有套用脚本语言这一条路,也就是脚本模块。
虽然dotnet世界里有很多脚本可以用 ironRuby ironPython,可是在unity这个特定环境下全部不可用。
你可以使用的一个选择是lua,这个由魔兽世界采用作为界面脚本,从而红遍整个游戏行业,十年经久不衰的脚本。
unity有了很多lua的绑定库,也有了unilua这样的pure c#移植实现。
你还有一个选择是C#Light/Evil,他是C#语法的,pure c#实现的一门新生脚本语言,就是为了Unity3D逻辑热更新而生。
由于深刻的认识到自己是个思维跳跃的人,深入浅出是个我还要努力很久的目标,为了让大家不至于在我乱七八糟的文字中迷失,特整理目录一份
无分类
《Unity3D热更新全书-何谓热更新,为何热更新,如何热更新》
这一篇是写给对热更新完全没概念的人
下载系列预告:《将下载加载脚本统一到一起的例子》
时间不定
《Unity3D热更新全书-下载 唯一的一篇》介绍我们的基本下载加载模块
加载系列
《Unity3d热更新全书-加载(一)从AssetBundle说起》
这一篇是探讨使用AssetBundle来做资源更新的问题,希望能让更多人理解AssetBundle是有害的
《Unity3d热更新全书-加载(二)如何在不用AssetBundle的前提下动态加载预设》
这里给出既然AssetBundle是有害的,在某些情况下,我们不使用他的替代方案。比如NGUI界面,就很适合这种方案。
脚本系列
《Unity3D热更新全书-脚本(一) 初识脚本》
这是一篇给我们所说的脚本定性的文字,因为脚本实在是一个太多含义的字,先统一一下再开篇
《Unity3D热更新全书-脚本(二) 两级分化》
这一篇尝试寻找一个变量来量化解读解释脚本和程序之间的关系
《Unity3D热更新全书-脚本(三) C#LightEvil语法与调试》
这是实际介绍C#LightEvil的语法不支持部分,和如何调试C#LightEvil的策略
《Unity3D热更新全书-脚本(四) 用C#LightEvil搭建实际开发使用的脚本框架》
这一篇是从框架的角度提供一个将脚本编写和程序编写隔离开的思路,和实例。
《Unity3D热更新全书-脚本(五) NGUI》
NGUI,问的朋友实在太多,我也只能低头了,好在NGUI的作者将2.7开源了。
只要有程序员朋友们问过两次的问题
就会收录在此FAQ中
1.C#Light对比LUA有什么好处
C#Light是静态类型脚本语言,语法同C#,Lua是动态类型脚本语言,这两种都有人喜欢。
我更喜欢静态类型,于是有了C#Light
2.C#Light性能怎么样
C#Light和Unilua 和ulua都做过简单性能测试,比Unilua快,和ulua各有胜负
3.C#Light IOS可以使用么
完全可以,均妥善测试
4.为什么C#Light例子和NGUI一起用会编译不过
因为Unity没有库的概念,要每个项目里都放一份源码,这样会让GITHUB代码变得非常凌乱。
所以在例子里是直接把C#Light 的DLL放进来了.
实际要改例子的话,请删除CSLightEvil35.DLL,直接从CORE中找到C#Light的源码,C#LE目录,然后将这个目录直接插入Unity项目。
5.为什么C#Light有那么多限制,使用类型还要注册
因为C#Light的设计之初就为了兼容AOT抛弃了很多,而兼容AOT就是为了能在IOS上顺利使用。
为此,我们不能运行时产生新的IL类型,所以不能继承程序的类型。所以脚本class类型和程序class类型不同
不能运行时模板推断,所以不能自动List<T>,要手动绑定List<int>,List<String>
不能运行时模板推断,所以不能自动调用GetComponent<T> 这类方法,改调用 GetComponent(“UILabel”) as UILabel
这些限制都是由AOT兼容导致,用一点点约束,换来IOS的兼容性,还是值得的
6.C#Light出错怎么查
有统一的Dump机制,在Unity3D热更新全书-脚本(三)有介绍
7.C#Light的代码放在StreamingAssets里是什么意思,真的能热更新么
真的可以热更新,你把例子生成exe,改了streamingassets的脚本,再运行就会有效果。
放在StreamingAssets里是为了演示可以在运行时加载字符串处理,同时例子比较容易看
实际项目还是要把脚本独立放出来,在Unity3D热更新全书-脚本(四)有介绍