[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘终结篇:UniLua热更新完全解读

标签: 游戏开发游戏解决方案用户体验unity3d
2014-10-18 23:23 7680人阅读 评论(4) 收藏 举报

 分类:
[算法相关](20)  [设计模式](11)  [编程语言](124)  [游戏开发](79)  [Unity引擎](86) 

版权声明:本文采用国际知识共享“署名-非商业使用-禁止演绎”协议4.0进行授权许可。转载请注明作者姓名和文章出处。

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

喜欢我的博客请记住我的名字:秦元培,我的博客地址是blog.csdn.net/qinyuanpei。

转载请注明出处,本文作者:秦元培, 本文出处:http://blog.csdn.net/qinyuanpei/article/details/40213439

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

大家好,我是秦元培,欢迎大家关注我的博客,我的博客地址是blog.csdn.net/qinyuanpei。在之前的三篇系列文章《Unity3D游戏开发之Lua与游戏的不解之缘》中,博主带领大家一起领略了Lua在游戏开发中强大而迷人的作用,通过UniLua这个开源项目我们将Lua引入了Unity3D的世界,并且在此基础上我们写出了Lua'与Unity3D交互的第一个示例程序。今天呢,我们来说说Unity3D配合AssetBundle和;Lua实现热更新。

首先,我们来了解一下什么是热更新吧!所谓热更新是指在不停机的状态下对系统进行更改,例如我们的Windows可以在不重启的状态下完成补丁的更新、Web服务器在 不重启的前提下完成对数据和文件的替换等都是热更新的经典实例。那么对于Unity3D而言,什么是热更新呢?如果我们最终发布的Unity3D游戏是一个Web游戏,那么每次游戏加载的过程中实现对资源代码的更新就是热更新。如果我们最终发布的Unity3D游戏是一个客户端游戏,那么我们在重重启客户端以后实现对资源代码的更新就是热更新。为什么这么说呢?因为Web游戏需要保证玩家能够及时快速地进入游戏,因此在游戏加载完之前,我们必须完成对游戏资源和代码的更新。可是对于客户端游戏而言,玩家可以在等待本次更新结束后再进入游戏,而且大部分的客户端程序在更新完后都会要求玩家重启客户端,所以对于客户端游戏而言,热更新并非是严格意义上的热更新。那么,我们为什么要进行热更新呢?答案是为了缩短用户获取新版本客户端的流程、改进用户体验。这其实就是博主在前文中提到的传统单机游戏依靠光盘载体进行发售所面临的问题,玩家为了获取最新版本的游戏,需要下载全新的客户端并将它安装到计算机或者手机设备上。在互联网产品开发中有一种称为快速迭代的理念,试想如果我们每次对客户端进行局部的调整,就需要玩家去下载新版本的客户端,试问这样的用户体验真得能让用户满意吗?所以现在为了方便用户、留住用户、进而从留住的用户身上赚到钱,我们总能在游戏产品中找到热更新的影子。我们知道在Unity3D中可以通过AssetBundle来实现对游戏中资源的更新,在http://blog.csdn.net/janeky/article/details/17666409这篇文章中作者janeky已经给出了较为完美地解决方案,因为博主使用的Unity3D免费版无法使用AssetBundle的功能,而博主本人不愿意使用破解版,因为这是一个程序员的良心,所以本文更多的是从代码更新的这个角度来讲Unity3D的热更新,对于资源的热更新大家建议大家还是去看janeky的这篇文章吧。好了,下面正式开始Unity3D代码级的热更新之旅!

在Unity官方的API中官方给出了一种基于反射的思路,即将C#脚本存储为文本文件,然后将其转化为byte字节,再通过反射技术取得该类型及其方法。理论上这样当然没有问题,可是我们知道由于IOS是一个封闭的系统,设计者出于安全的考虑不允许在该平台下使用反射技术。那么问题来了,反射并不是一个完美地解决方案。关于反射技术实现Unity3D的热更新,大家可以参考这篇文章:http://blog.csdn.net/janeky/article/details/25923151。好了,下面我们来说说博主是如何通过Lua实现Unity3D的热更新的吧。我们知道在Lua提供的C#接口中有一个DoString()的方法,该方法可以直接利用Lua虚拟机执行字符串中的脚本。所以,我们可以通过在本地读取Lua脚本来执行脚本中的命令,如果我们脚本中的命令可以直接对Unity3D进行操作,那么我们就可以通过Lua脚本来更新游戏中的代码逻辑。那么,我们怎么能让Lua脚本操作Unity3D呢?在前一篇文章中,我们介绍了一种Require的方法,该方法可以将C#库引入到Lua脚本中并通过Lua来执行C#库中的方法。顺着这样的思路,博主便有了下面的设想:

在这个设想中,我们首先需要将Unity API封装成一个C#类库,在这个类库中我们将会涉及动态加载场景和动态创建场景,因为我们更新游戏的逻辑的时候将会用到这些方法。这些方法通过封装后我们便可以在Lua脚本通过Require方式来引用,进而我们就可以通过Lua脚本来动态地进行设计。我们设计一个固定的位置来存储Lua脚本更新文件,这样我们只需要对比本地版本和服务器版本是否相同就可以知道我们是否需要更新。这里我们通过WWW来从远程服务器上下载最新的Lua脚本更新文件,下载下来的Lua脚本处于项目外部,我们无法使用Resource.Load()这样的方法来加载,可是我们可以通过WWW来加载一个本地文件,这样我们就实现了Lua脚本文件的更新。当然,我们可以使用AssetBundle来更新Lua脚本文件,可是博主的免费版不支持AssetBundle,所以博主想出了这样一个曲线救国的方法。当Lua脚本文件更新后,我们就可以在游戏主逻辑里通过DoString()方法来执行脚本文件中的代码。在游戏主逻辑里主要的任务是比较当前版本号和服务器版本号来判断是否需要更新,如果需要更新就下载Lua脚本更新文件然后执行脚本中的代码,这样我们就实现了客户端程序的更新。好了,下面我们继续以前一篇文章中的项目为例来将博主的这个设想变成现实。

首先,我们在CSharpLib.cs这个类中增加下面两个方法并完成方法的注册:

[csharp] view plaincopy
  1. /// <summary>
  2. /// 设置场景中物体的坐标
  3. /// </summary>
  4. /// <returns>返回当前坐标</returns>
  5. /// <param name="lua">Lua.</param>
  6. public static int SetPosition(ILuaState lua)
  7. {
  8. //物体的名称
  9. string mName=lua.L_CheckString(1);
  10. //传入参数x,y,z
  11. float mX=(float)lua.L_CheckNumber(2);
  12. float mY=(float)lua.L_CheckNumber(3);
  13. float mZ=(float)lua.L_CheckNumber(4);
  14. //获取物体
  15. GameObject go=GameObject.Find(mName);
  16. //获取Transform
  17. Transform mTrans=go.transform;
  18. //设置游戏体的位置
  19. mTrans.position=new Vector3(mX,mY,mZ);
  20. //返回游戏体当前坐标
  21. lua.PushNumber(mTrans.position.x);
  22. lua.PushNumber(mTrans.position.y);
  23. lua.PushNumber(mTrans.position.z);
  24. return 3;
  25. }
  26. /// <summary>
  27. /// 使用本地预设创建一个物体
  28. /// </summary>
  29. /// <returns>The resource.</returns>
  30. /// <param name="lua">Lua.</param>
  31. public static int CreateResource(ILuaState lua)
  32. {
  33. //传入资源名称
  34. string mName=lua.L_CheckString(1);
  35. //加载本地资源
  36. GameObject go=(GameObject)Resources.Load(mName);
  37. //传入坐标参数x,y,z
  38. float mX=(float)lua.L_CheckNumber(2);
  39. float mY=(float)lua.L_CheckNumber(3);
  40. float mZ=(float)lua.L_CheckNumber(4);
  41. //创建一个新物体
  42. Object.Instantiate(go,new Vector3(mX,mY,mZ),Quaternion.identity);
  43. //返回该物体的名称
  44. lua.PushString(go.name);
  45. return 1;
  46. }

好了,这样我们就完成了一个简单的C#类库,下面我们来在主逻辑代码中增加一个更新脚本的方法UpdateScripts():

[csharp] view plaincopy
  1. void UpdateScript()
  2. {
  3. StartCoroutine("Download");
  4. }
  5. /// <summary>
  6. /// 下载Lua脚本更新文件
  7. /// </summary>
  8. IEnumerator Download()
  9. {
  10. //从本地加载Lua脚本更新文件,假设文件已经从服务器下载下来
  11. WWW _WWW=new WWW(mUpdateFilesPath);
  12. yield return _WWW;
  13. //读取服务器版本
  14. mLua.L_DoString(_WWW.text);
  15. }

这里的代码逻辑很简单,就是读取脚本更新本地文件然后执行脚本,其中mUpdateFilePath是脚本更新文件路径:

[csharp] view plaincopy
  1. //初始化路径
  2. mUpdateFilesPath="file://D:\\lua_update.txt";

这里博主设想的是在本地存储一个版本号,每次更新前先获取服务器端的版本号,如果两个版本号不同则需要从服务器上下载更新脚本文件进行更新。不过博主这里没有想到什么好方法来获取版本号,所以这里就只写了更新。那么,我们来看看更新脚本文件都做了哪些事情吧!

[csharp] view plaincopy
  1. local csharplib=require"CSharpLib.cs"
  2. csharplib.SetPosition("Cube",2,1,0)
  3. csharplib.CreateResource("Sphere",0,0,0)
  4. csharplib.CreateResource("Cube",1,1,0)

首先我们通过Require引入了CSharpLib.cs 这个类库,接下来,我们将场景中名称为Cube的物体的位置设为(2,1,0)、 利用本地的两个Prefab资源创建了一个Cube和一个Sphere。那么,我们的设想能不能实现呢?我们一起来看最终效果吧!

执行Lua脚本更新前:

执行Lua脚本更新后:

如我们所愿,Lua脚本成功地对场景实现了一次更新。可能有的朋友会问,这里用的是本地资源,如果我想用服务器上的资源怎么办呢?答案是博主最不愿意提及的AssetBundle,即利用AssetBundle加载远程资源,然后用Lua实现更新,这些逻辑可以添加到CSharpLib这个类库中。大家可以设想一下,如果有一天我们能够将Unity的所有方法都封装起来,那么我们就可以直接用Lua来创建场景了,如果要更新客户端,只要更换Lua文件就可以了,怎么样是不是很简单呢?可是Unity不开源啊,这些想法终究只是想法啦。好了,今天的内容就是这样了,欢迎大家关注我的博客,谢谢大家!

转载于:https://www.cnblogs.com/w-wfy/p/7716621.html

Lua------------------unity与lua的热更新相关推荐

  1. Unity应用的iOS热更新

    Unity应用的iOS热更新 作者:丁治宇 Unity TechnologiesChina Agenda ? 什么是热更新 ? 为何要热更新 ? 如何在iOS 上对Unity 应用进行热更新 ? 支持 ...

  2. lua 函数 默认值_Unity热更新框架之xLua

    一:xLua概述 二:Lua文件加载 三:xLua文件配置 四:Lua与C#交互 五:xLua热更新 一:xLua概述 1.1 xLua简介 xLua是由腾讯维护的一个开源项目,xLua为Unity. ...

  3. Unity为什么ios不能热更新

    unity的c#代码运行的方式以及可以通过拆分代码模块,将可能需要更新扩展的逻辑放到一个独立的.dll中,通过更新这个.dll文件来实现热更新. 但是这种朴素的想法在ios平台会受到限制. c#编译出 ...

  4. 【游戏开发高阶】从零到一教你Unity使用ToLua实现热更新(含Demo工程 | LuaFramework | 增量 | HotUpdate)

    文章目录 零.前言 一.我做的热更新Demo 1.效果演示 2.流程图 3.工程源码 二.为什么要有热更新 三.Unity如何支持热更新 1.热更C#代码 2.热更lua代码与资源 四.Unity中集 ...

  5. Unity游戏开发-游戏热更新以及登录流程

    本篇主要分享基于热更新的游戏初始化方案. 整体初始化的流程大致为:检查是否需要解压资需要则解压,之后再检查是否存在需要热更新的资源文件需要则更新,更新完成后则初始化结束可进入登录界面. 关于登录这块的 ...

  6. Unity GameFramework-打包和热更新模块(Resources资源)

    #Unity GameFrameWork框架- Resources模块 之前的文章可能都太老了,现在已经没有Update分支了,热更新相关逻辑已经合并到主干了,验证的逻辑均来自E大的StartForc ...

  7. tolua unity 报错_Unity3D热更新之LuaFramework篇[01]--从零开始

    解压刚刚下载好的压缩包,发现里面是一个Unity工程(如图2-1),于是用 unity打开此工程. 图2-1 我使用的Unity版本为5.5.5f1,会提示需要升级,是否备份,点"Go He ...

  8. 菜鸟学习 - Unity中的热更新 - Lua和C#通信

    孙广东 2015-4-6 热更新我是个菜鸟,感谢网上的各位的奉献,这次又当一回搬运工. 准备: 1.了解Lua的语法 推荐书籍<Lua程序设计 第二版> 2.使用ULua插件进行通信 尽量 ...

  9. Unity中的热更新 - Lua和C#通信

    准备: 1.了解Lua的语法 推荐书籍<Lua程序设计 第二版> 2.使用ULua插件进行通信 尽量早上真机.因为Bug问题特别多. 大杂烩: 更新LUa其实也是更新资源. Lua被看作一 ...

  10. 初学者学习 - Unity中的热更新 - Lua和C#通信

    菜鸟学习 - Unity中的热更新 - Lua和C#通信 孙广东 2015-4-6 热更新我是个菜鸟,感谢网上的各位的奉献,这次又当一回搬运工. 准备: 1.了解Lua的语法 推荐书籍<Lua程 ...

最新文章

  1. 入门NLP最优解:从项目实践轻松入手!
  2. 基于jQuery+ashx+.net实现三级栏目联动操作
  3. [翻译][1.4.2]Flask-Admin入门介绍
  4. saltstack配置管理之YAML(二)
  5. Java运行时动态加载类之ClassLoader加载class及其依赖jar包
  6. ITK:概念检查是浮点数
  7. Ubuntu switch window switch terminal tab
  8. notejs环境搭建
  9. php中多重继承,PHP面向对象之多重继承与接口用法
  10. excel匹配_「最全」Excel中查找匹配函数
  11. 3月国内网站流量:腾讯夺第二 360安全中心降至第三
  12. 百度成立互联网医院;钉钉招小学生产品体验师;iOS 13.4 上线 | 极客头条
  13. 易天ETU-link 100G QSFP28光模块系列资料
  14. Loadrunner脚本编程(4)-数据类型操作和字符串操作
  15. 安装JDK失败,再次安装时出现已经安装过了的,解决办法
  16. 计算机机房里面难闻的气味,新装中央空调气味刺鼻为什么?怎么办?-中央空调 异味 刚开...
  17. 语义表示——神经网络与深度学习
  18. java基本数据类型字节大小,Java基本数据类型及所占字节大小
  19. 基于MATLAB的GUI界面设计流程
  20. 来自网页的消息服务器不能创建对象,ActiveXObject(Excel.application)引发Automation 服务器不能创建对象...

热门文章

  1. 访客门禁系统供应商 首选钱林厂家
  2. 理解 Delphi 的类(十) - 深入方法[28] - 递归函数实例: 搜索当前目录下的所有嵌套目录...
  3. koa+mysql+vue+socket.io全栈开发之web api篇
  4. 【tmos】SpringBoot登录拦截
  5. 2017-9-11-颜色空间
  6. 【黑客免杀攻防】读书笔记4 - 壳在免杀中的应用
  7. 接口转发和重定向区别(四)
  8. 玩转AppBarLayout,更酷炫的顶部栏
  9. Windows核心编程的官方网站
  10. c++中的数组和指针,引用