[Unity3D学习]Unity代码热更新解决方案测试结果总结

这几天一直在研究热更新方案

主要思路是:

1.先将代码打包成dll,然后用unity 打包成assetsbundle,

2.WWW加载进入主程序,

3使用System.Reflection.Assembly来创建程序集,

4.然后通过GetType(className),来获取这个类

5.AddComponent进入主程序,加载的dll就执行起来了。

 

 

 

因为在加载的时候遇见安全沙箱问题,所以我将这个策略文件记录下来,方便下次复制粘贴

本地调试程序时解决跨域问题的方法:

Edit->Project Settings->Eidtor

 

刚开始的时候想使用序列化来存储一些数据,但是后来却连一个很简单的类序列化dll里面都没法获得

 

这是使用序列化数据的加载方式,在不用反射的情况下,下面代码加载能够成功,但是使用了反射,下面的代码就加载不成功了。这个问题我也很费解,暂时我没办法解决

 

因为要看一下代码的执行效率,所以我寻找到了这个类。感觉还可以。使用josn数据,mat文件创建一个UIAtlas的时间大概是30毫秒左右。

总结:

我使用没有任何Unity环境以外代码来实现壳的制作(我们暂且将其称为Index,其实他就是上面的Index类,代码少得可怜。)

然后主程序是在另一个Unity项目中(这个项目在发布的时候打包成Main.dll)

Main.dll项目通过上面的Index来加载,然后添加到一个GameObject上,主程序的Awake()方法就会执行(Awake是整个程序的主入口)

这个时候所有的资源加载都会在Main.dll里面完成。

在这个过程中,遇到了一个比较麻烦的问题就是,我打包的一些UIAtlas.prefab文件上的UIAtlas这个类,无法找到。

这让我有一些无法理解,因为NGUI的代码已经打包进入了Main.dll,那么为什么我加载prefab的时候,却找不到UIAtlas这个类呢?

最后我只能动态的制作UIAtlas对象来完成这样工作。

那么这样的话,以后做界面,做任何prefab都不能绑定脚本了。都只能加载到内存中动态AddComponent了。这样界面也得用配置文件了。

不过对于我这种从页游转过来的程序,这到不是问题,我有现成的界面编辑器(我博客里有RookieEditor),直接生成XML在游戏中进行组装了。对于能够热更新来说,这点麻烦,其实应该不算麻烦了。

动态生成UIAtlas后,创建了几个Sprite、Button,基本的功能都已经实现,说明这个解决方案是可行的。接下来我将把这个方案运用到我的项目中,更加全面的去实验一下。

这样设计的优点:

1、对IOS的打包也是比较方便。打包IOS 直接拿Main项目打包就可以了。因为不需要热更新了。把代码打包在本地就行了。

2、打包Android项目的时候发布apk只需要发布Index,项目发布版本和没写代码一样大,想到这里我想吐槽一下,Unity就算不写任何代码,发布一个apk也得有7M左右。这也太大了点吧。我可啥都没做啊。

求助:

1、哪位大神能给我说说上面我遇到的那个问题,为什么找不到绑定在prefab上的类呢?这是程序集的问题么?哎,刚转C#的人伤不起。

 

下一篇: 《[Unity3D学习]Unity代码热更新 源码下载》

22 Comments

  1. […] 3、这也是最主要的,如果你看过我上一篇文章《Unity代码热更新解决方案测试结果总结》你就会知道我为什么要这么做了,都是泪啊。。 […]

  2. says:

    刚开始的时候想使用序列化来存储一些数据,但是后来却连一个很简单的类序列化dll里面都没法获得,我也遇到这个问题,你有想到解决办法了没有

    • YangDan says:

      我们换了热更新思路,我们将逻辑代码与基础代码分开,逻辑代码在发布的时候将他打包成一个dll,基础代码与安装包一起打包。 动态加载逻辑代码来实现热更新。注意:打包的时候 逻辑代码是在基础代码的之上打包的。

  3. Benloong says:

    动态加载进来的类和Unity打包AssetBundle时候的type tree是不一样的(虽然类名一样,但是assembly不一样,Unity序列化的Type也不一样),NGUI及其他需要序列化的类推荐放到Plugins目录(动态加载的dll不包含NGUI代码)这样就能序列化NGUI的类型了。

  4. […] 之前的一篇文章《[Unity3D学习]Unity代码热更新解决方案测试结果总结》只是说了一下方案的流程,今天刚好有时间,又再看了一下热更新这一块!就直接将代码分享出来。代码热更新的核心基本实现,只是需要处理一些依赖等等。 […]

  5. gordon says:

    你好,(这个项目在发布的时候打包成Main.dll)你这句话,是指用vs将主项目的所有代码生成main.dll吗?

  6. gordon says:

    你好,请问你用的是4.6版本的unity吧,我测了一下,同样的东西,在unity5上有bug

    • GameRisker says:

      你好,能描述一下是什么问题么?我确实用的是老版本的unity

      • gordon says:

        在unity5上有几个问题,
        例如:
        1,你的index没有用过assetbundle.CreateFromFile, 更新的dll用了,会提示找不到这个方法。
        2,如果必须要挂一些脚本到gameobject上,这些脚本必须要在index里面,如果在更新的dll里面,getcomponent的方式获取脚本,会得到null

        • GameRisker says:

          最近实在是太忙,没时间去测试,有时间我再看看,如果你已经解决了,请告诉我噢,谢谢!

          • Cthoutianhen says:

            unity5上面,我把a脚本打包成dll,然后a脚本解压绑在物体上,a脚本调用场景已存在的脚本时,能找到gameobject,但不能找到他身上的脚本!例如:t.GetComponent().depth = 3;
            是找不到这个uisprite的啊,很不理解为什么

          • GameRisker says:

            你好,如果你指的是挂在gameobject对象上的脚本你找不到是对的,这种情况只能是你自己addcomponent去添加脚本才行,一般情况我们打包的脚本只是逻辑层的脚本,第三方的脚本都是跟随安装包走的。

  7. Cthoutianhen says:

    也就是说,我a绑上去,要想调用b脚本的话,还得解压b,绑上去,然后再找b,调用??

  8. Cthoutianhen says:

    例如我a是逻辑脚本,b是ui脚本,那么打包的时候,由于a调用过b的,那么也得把b脚本也放进去,不然报错,打包不了。也就是说,你是怎么只把逻辑脚本打包,然后用解压的逻辑脚本调用其他的?

    刚才我试了下ab都打包,都解压到一个物体上,虽然a能通过get组件调用b,但b上面,t.GetComponent().depth()这句是空的,找不到uisprite

Leave a Reply to Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.