现在的位置: 首页 > 综合 > 正文

Unity动态(Runtime)加载脚本

2013年10月07日 ⁄ 综合 ⁄ 共 1155字 ⁄ 字号 评论关闭

之前在群里跟人谈到脚本更新问题,于是就突然发现因为U3D对资源进行了打包,所以很难更新资源。说实在,我现在还没找到资源更新的办法,不过知道了资源可以从网络下载实时加载。后来看到有人说可以动态加载脚本,于是就去研究了。途中各种蛋疼不提也罢。其实基本原理就是使用到了C#的反射,熟悉反射的应该很简单就能解决。

var fs = new FileStream(@"D:\Personal\My Documents\Projects\TestLib\TestLib\bin\Release\TestLib.dll", FileMode.Open);
        var b = new byte[fs.Length];
        fs.Read(b, 0, b.Length);
        fs.Close();
        var assembly = System.Reflection.Assembly.Load(b);
        var type = assembly.GetType("Test");
        gameObject.AddComponent(type);

分析这段代码

加载里一个DLL,这个DLL实际上是用C#打包的代码库,关于对库的各种叫法实在让人蛋疼,不提也罢。总之建立一个工程然后引用U3D的库UnityEngine.dll就可以编译,不引用UnityEngine.dll当然首先就没法通过编译。

我这里的类名就叫Test,所以获取类型就是这样的。这里添加组件就不能用AddComponent(string)方法,那样会提示找不到了,可能这个方法只是从字典里面找到相应的类型然后在用AddComponent(type)来添加。

要吐槽的是关于那个二进制流。看网上很多WWW来读取TextAsset然后转成byte[]。事实上我不管怎么试都是失败。与干脆用C#自带的函数,就实际情况来说虽然统一使用WWW会比较方便,不过即使用C#来做网络下载难度也不会太大。

最后说缺点。

缺点明显是这样的做更新行不通。因为文件最终没被保存在本地,下次还要下载,不过你可能会下载先保存在本地再读取,那样或许可以,但是我目前还没有尝试。

但是如果是某个脚本有BUG想修复,这样完全就行不通了,这种情况我目前不知道如何处理。有知道的话真想请教请教。

还有个缺点就是因为不能和现有的类直接依赖。那么这时候估计就只能靠接口来解决问题了,事实上低依赖就是设计原则,所以这个缺点并不是完全没办法解决。

硬要说有什么优点的话,可能是可以把部分代码放在服务器,需要的时候才下载下来使用,让别人有客户端也没法运行游戏。

不过实际上脚本文件会被优先考虑,毕竟体积更小,热更新也更方便。昨天去看了云风的博客,他们就做 了个基于C#的LUA实现,不过貌似还不是很完整,也不知道会不会放出完整版。但是能用LUA的话我还是很愿意使用LUA,函数式编程相当的有意思。

抱歉!评论已关闭.