Unity代码热更新解决方案测试结果总结
2017-01-01 17:45
316 查看
转自:http://blog.csdn.net/ybhjx/article/details/50624935
这几天一直在研究热更新方案
主要思路是:
1.先将代码打包成dll,然后用unity 打包成assetsbundle,
2.WWW加载进入主程序,
3使用System.Reflection.Assembly来创建程序集,
4.然后通过GetType(className),来获取这个类
5.AddComponent进入主程序,加载的dll就执行起来了。
ExportAssetBundles.cs
C#
Index.csC#
因为在加载的时候遇见安全沙箱问题,所以我将这个策略文件记录下来,方便下次复制粘贴
crossdomain.xml
XHTML
本地调试程序时解决跨域问题的方法:Edit->Project Settings->Eidtor
刚开始的时候想使用序列化来存储一些数据,但是后来却连一个很简单的类序列化dll里面都没法获得官方对象序列号C#
这是使用序列化数据的加载方式,在不用反射的情况下,下面代码加载能够成功,但是使用了反射,下面的代码就加载不成功了。这个问题我也很费解,暂时我没办法解决
读取序列化对象
C#
因为要看一下代码的执行效率,所以我寻找到了这个类。感觉还可以。使用josn数据,mat文件创建一个UIAtlas的时间大概是30毫秒左右。C#
总结:
我使用没有任何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#的人伤不起。
这几天一直在研究热更新方案
主要思路是:
1.先将代码打包成dll,然后用unity 打包成assetsbundle,
2.WWW加载进入主程序,
3使用System.Reflection.Assembly来创建程序集,
4.然后通过GetType(className),来获取这个类
5.AddComponent进入主程序,加载的dll就执行起来了。
ExportAssetBundles.cs
C#
1234567891011121314151617181920 | //打包工具,该工具是网上找来都。谢谢作者!public class ExportAssetBundles : MonoBehaviour { //在Unity编辑器中添加菜单 [MenuItem("Custom Editor/Create AssetBunldes ALL")] static void ExportResource() { // 打开保存面板,获得用户选择的路径 string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "assetbundle"); if (path.Length != 0) { // 选择的要保存的对象 Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets); //打包 BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets, BuildTarget.StandaloneWindows); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | usingUnityEngine; usingSystem.Collections; usingSystem.Reflection; //代码加载器 publicclassIndex:MonoBehaviour { privateWWWwww; publicstaticWWWuiWWW; privateSystem.Reflection.Assemblyassembly; // Use this for initialization voidStart() { StartCoroutine(loadScript()); } privateIEnumeratorloadScript() { //加载我的代码资源 www=newWWW("http://localhost/Main.assetbundle"); yieldreturnwww; AssetBundlebundle=www.assetBundle; TextAssetasset=bundle.Load("Main",typeof(TextAsset))asTextAsset; assembly=System.Reflection.Assembly.Load(asset.bytes); Assembly[]assLis=System.AppDomain.CurrentDomain.GetAssemblies(); System.Typescript=assembly.GetType("Main"); gameObject.AddComponent(script); } } |
crossdomain.xml
XHTML
123456 | <?xml version="1.0"?><cross-domain-policy><site-control permitted-cross-domain-policies=”master-only” /><allow-access-from domain="blog.gamerisker.com" /><allow-access-from domain="*"/></cross-domain-policy> |
刚开始的时候想使用序列化来存储一些数据,但是后来却连一个很简单的类序列化dll里面都没法获得官方对象序列号C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | [MenuItem("Custom Editor/WriteSpriteData")] staticvoidFileWriteSpriteData() { TextAssettextasset=AssetDatabase.LoadAssetAtPath("Assets/Resources/Packer/Packer.txt",typeof(TextAsset))asTextAsset; Atlasatlas=ScriptableObject.CreateInstance<Atlas>(); //Json其实是NGUIJson这个类,我只是把他提出来。改了个名字 atlas.mList=Json.LoadSpriteData(textassetasTextAsset); if(atlas.mList==null) return; stringpath="Assets/Resources/Packer/Packer.asset"; AssetDatabase.CreateAsset(atlas,path); //Atlas是一个只有一个mList属性都类 mList = new List<UISpriteData>(); Objecto=AssetDatabase.LoadAssetAtPath(path,typeof(Atlas)); Objecttexture=AssetDatabase.LoadAssetAtPath("Assets/Resources/Packer/Packer.mat",typeof(Material)); Object[]t={texture}; BuildPipeline.BuildAssetBundle(o,t,"Assets/Resources/Packer/Packer.assetbundle"); //AssetDatabase.DeleteAsset(path); } |
读取序列化对象
C#
1234567891011121314151617181920212223242526 | IEnumerator LoadAtlas() { www = new WWW("http://localhost/Packer.assetbundle"); //WoodenAtlas.assetbundle //Packer.assetbundle yield return www;//用来断点都时候看看里面所包含都数据 Object[] os = www.assetBundle.LoadAll(); Material mete = www.assetBundle.Load("Packer", typeof(Material)) as Material; Atlas atlas = www.assetBundle.mainAsset as Atlas; GameObject go = new GameObject("UIAtlas"); UIAtlas uiatlas = go.AddComponent<UIAtlas>(); uiatlas.spriteMaterial = mete; uiatlas.spriteList = atlas.mList; GameObject sprite = new GameObject("Sprite"); UISprite ui = NGUITools.AddChild<UISprite>(sprite); ui.atlas = uiatlas; ui.spriteName = "dynamite"; Debug.Log("Load"); www.assetBundle.Unload(false); www.Dispose(); } |
1 2 3 4 5 | System.Diagnostics.Stopwatch; StopwatchstopWatch=newStopwatch(); stopWatch.Start(); Thread.Sleep(10000); stopWatch.Stop(); |
我使用没有任何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代码热更新解决方案测试结果总结
- [Unity3D学习]Unity代码热更新解决方案测试结果总结
- [Unity3D学习]Unity代码热更新解决方案测试结果总结
- ▇▇▇mfs权威指南(moosefs)分布式文件系统一站式解决方案(部署,性能测试)不断更新 - 分布式文件系统(FastDFS) - ChinaUnix.net -
- [.net]记录一些自己写代码时的总结(持续更新)
- LoadRunner测试执行结果庞大的解决方案
- 在feebsd下测试代码结果
- 1亿动态pv/天的超级数据库缓存解决方案,开源了,还有测试代码。作者KK
- activiti5.9调研总结(更新集成mysql数据库bug解决方案-2013.04.07)
- 渗透测试技巧总结更新篇3
- mfs权威指南(moosefs)分布式文件系统一站式解决方案(部署,性能测试)不断更新
- 更新Android SDK, 升级ADT遇到的问题总结(未测试)
- 再续NBear性能测试:ADO.NET, NBearV3, NHibernateV1, NBearLite, NBearLite+NBearMapping性能比较[2008/1/3修订:NBearLite更新至v1.0.1.0整合NBearMapping版地测试结果]
- 【小测试2】写出此代码的执行结果,并解释原因 Array.asList
- 高质量代码总结(陆续更新)
- 一种通用的测试环境自动搭建更新解决方案
- WebService性能测试回顾版-结果分析和项目总结
- 1亿动态pv/天的超级数据库缓存解决方案,开源了,还有测试代码。
- 添加水印的代码 测试 调试 结果 经过本人亲自测试
- WinForm 内嵌 Office 文档 解决方案测试(非DSOFRAME 纯C#代码,网上独一份)