为啥Unity没有实现iOS平台代码热更新
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥Unity没有实现iOS平台代码热更新相关的知识,希望对你有一定的参考价值。
Unity没有实现ios平台代码热更新是因为:所谓热更新就是指代码可以不通过重新打包提交App Store的方式来更新客户端的执行代码。由于以下几个原因客户端更新希望更加轻量和快速:
App Store的审核周期比较难控制;
手机网络游戏更新频繁;
对于大型游戏,玩家更新成本太大。所以需要新的代码可以在简单的发布之后可以直接被客户端动态加载执行,而不需要重新提交App Store,玩家也不需要重新下载安装整个程序。现有的方案是在Unity环境里内嵌一个Lua虚拟机,经常变动的和对执行效率没要求的逻辑用Lua实现,游戏启动时加载服务器上最新的Lua字节码来执行游戏。如果C#的程序集可以动态加载,就无需嵌入其他的虚拟机来实现动态逻辑。 参考技术A iOS是不允许不通过AppStore更新代码的。
Mono和Unity当然不会跟规定对着干。
作为开发商你想绕过这些自己做热更新也不是没有办法。
一个极端的例子就是WebView,js代码随便你怎么改不会有人管你的。
又或者UniLua之类的解决方案。
但是注意,这些玩法其实都是不符合规定的。本回答被提问者采纳
用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 在脚本中使用MonoBehaviour
继上次分析了热更新的Demo后,这次来介绍如何在热更新代码中使用MonoBehaviour。
MonoBehaviour挂载到GameObject对象上的脚本的基类。平常Unity开发时,简单的做法就是编写一个继承自MonoBehaviour的脚本,将它挂载到要操纵的GameObject上,赋予它各种行为。
当然,在某些大型项目中,可能并不推荐导出挂脚本的方式,但是本文旨在介绍如何在脚本中继承并编写MonoBehaviour,暂时忽略这个问题。
本章的目标:
用脚本创建一个MonoBehaviour。并挂载到某个物体上,在Start方法中使用协程加载 baidu 的首页的html,然后将它的html代码显示到文本框上。
操作步骤:
- 新建一个Unity热更新项目,或者打开上次的项目。如果您不知道怎么新建,参考上一篇文章或者看官网
- 打开HotFixDemoScene1,将文本框改大。
- 打开热更新项目。
- 如果您使用的是Unity2017.2以后的版本,需要注意以下问题:UnityEngine.WWW这个类用于从网络下载数据。但是自从Unity2017.2之后,Unity将它的API拆分到了许多其他dll中。默认系统只将UnityEngine.CoreModule.dll的API导出了,但是UnityEngine.WWW并没有包含在这个dll里。
- 可以使用如下办法,来确定某个类在哪个dll里:在VS中,写下要确定的这个类的名字。
- 右键点击刚才写的类名,在弹出菜单中选择速览定义,即可查看到这个类型所在的dll。
- 这里我们定位到在UnityEngine.UnityWebRequestWWWModule.dll中
- 打开热更项目的genapi.config.xml,将这个dll配置到以下配置节中:
<!--Configure DLLs to export--> <buildassemblys> <assembly value="D:\\Program Files\\Unity\\Editor\\Data\\Mono\\lib\\mono\\2.0\\System.dll"></assembly> <assembly value="D:\\Program Files\\Unity\\Editor\\Data\\Managed\\UnityEngine\\UnityEngine.CoreModule.dll"></assembly> <assembly value="D:\\Program Files\\Unity\\Editor\\Data\\Managed\\UnityEngine\\UnityEngine.UnityWebRequestWWWModule.dll"></assembly> <assembly value="D:\\Program Files\\Unity\\Editor\\Data\\UnityExtensions\\Unity\\GUISystem\\UnityEngine.UI.dll"></assembly> <assembly value="F:/ASTool_UnityTest/AS3HotFix_WWW\\Library\\ScriptAssemblies\\Assembly-CSharp.dll"></assembly> </buildassemblys>
- 执行 bat/CreateUnityAPI.bat ,再次生成Unity的API。如此,即可在热更新项目中使用WWW相关的类型
- 打开热更新项目的 Main.as。
- 本次我们将功能写在包外代码内,因此将Main类型的代码清空,然后贴下如下代码:
1 package 2 { 3 4 [Doc] 5 /** 6 * ... 7 * @author 8 */ 9 public class Main 10 { 11 12 public function Main() 13 { 14 } 15 16 public function update():void 17 { 18 19 } 20 } 21 22 } 23 24 //写在包外的代码,会在Main这个类第一次被实例化之前执行一次。 25 26 import system.collections.IEnumerator; 27 import unityengine.Camera; 28 import unityengine.GameObject; 29 import unityengine.MonoBehaviour; 30 import unityengine.Time; 31 import unityengine.WWW; 32 import unityengine.ui.Text; 33 34 //定义一个继承自MonoBehaviour的类型。 35 class baidutest extends MonoBehaviour 36 { 37 //Start方法会在Update前调用一次。 38 function Start():IEnumerator 39 { 40 //创建WWW对象,并访问 www.baidu.com 41 var www:WWW = new WWW("http://www.baidu.com"); 42 while ( !www.isDone) 43 { 44 //更新UI元素. 45 Text( GameObject.find("Text").getComponent(Text)).text = "loading from baidu " + Time.frameCount; 46 //使用 yield关键字,可以使用Unity协程 47 yield return www; 48 } 49 50 51 //加载完毕后,将html内容显示到UI上。 52 Text( GameObject.find("Text").getComponent(Text)).text = www.text.substr(1024,1024); 53 //销毁WWW对象。 54 www.dispose(); 55 56 } 57 58 } 59 60 //在主相机上挂载脚本中定义的baidutest。 61 Camera.main.gameObject.addComponent(baidutest);
- 见注释,我们直接在脚本中定义一个MonoBehaviour的子类,并且挂载到了相机上。
- 执行结果:
如此,即实现了在脚本中使用MonoBehaviour。
我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1l1wacrkzlbqn
以上是关于为啥Unity没有实现iOS平台代码热更新的主要内容,如果未能解决你的问题,请参考以下文章