unityunity5制作简单小游戏代码问题

UnityTestTool实用解释 - 简书
下载简书移动应用
写了43724字,被306人关注,获得了202个喜欢
UnityTestTool实用解释
UnityTestTool实用解释
以下的场景是否似曾相识:
你说:“这模块我不熟啊!让我去改,会不会引起其他问题啊?算了,都review好几遍跑好几遍了应该没问题。就让测试同学去测好了。”然后,然后这个改动没被测出并引起了外网的crash。
你说:“这个模块怎么用啊?看了注释、文档后还是一头雾水。唉,还是去搜搜别人的用到这个模块的代码吧。”然后,然后你花了20分钟,从散落四处的使用者代码,终于总结出咋用这个模块。
你说: “只花了一天时间,就设计好、写好一个模块了,我太棒了!”,用你模块的同学说:“你这个模块的接口不好用啊,应该那样更好吧!”,然后,然后你又花了一天重新设计了接口。测试用例能够解决上面这些的问题。在Unity中,UnityTestTool是编写测试用例的工具。
UnityTestTool简介
是Unity提供的官方测试工具,它的核心功能包括:
测试用例工具
单元测试(Unit Test):测试纯代码的用例。单元测试“运行于Editor”,即不依赖于任何场景,不需场景在Play状态。比如上图,每一行都是一个测试函数,以及每个函数的测试结果。
集成测试(Integration Test):测试GameObject(以下简称GO)的用例。集成测试“运行于Engine”,即依赖于场景且需要场景在Play状态才能测。比如上图左部场景里,右边有测试结果icon的GO都是集成测试用例(比如图中的“Test2-TimeOut”)。需要被测试的GO(比如图中的“Sphere”)作为测试用例GO的孩子节点。集成测试用例GO本身挂接了进行测试的脚本代码,对被测试GO进行判断以决定测试用例是否成功。一个场景里允许有多个集成测试用例,但一个时刻只有一个测试用例是Activated的(留意图中只有“Test3 - Failur”是白色,其他是灰色的)。
断言组件(AssertionComponent):往GameObject添加AssertionComponent,以监控GameObject的指定状态。当AssertionComponent监控的状态不符合断言时,将抛出异常。上图为挂接在MainCamera的一个断言组件,它断言MainCamera的drag值必须等于一个GameObject的drag,否则,将抛出异常。抛出异常后,如果在console面板设置了“Pause on error”,将自动暂停场景,实现了类似断点的功能;也正因可以抛出异常,所以断言组件可以和集成测试用例配合使用。
测试用例能做什么
测试用例之所以能解决一开始提出的那些问题,是因为:
测试用例可以验证功能实现是否正常:前提是测试用例本身设计正确。
测试用例和功能实现是高度匹配的:模块A的功能实现和模块A的测试用例,是由同一个(批)人,在同一个时间段内编写的。另外,更改功能的接口时,需要同时更改测试用例。
测试用例本身就是实用文档:测试用例直接使用代码的形式描述了该怎么使用模块、和使用模块的注意点(因为测试用例使用抛出异常的方法来描述不正确使用模块的情况)。
测试驱动:测试用例甚至可以反过来驱动功能实现。测试用例代码比功能实现代码简单得多,且直接面对功能模块的接口。所以先写测试用例再写功能实现能帮助开发者整理思路、设计更加稳妥的接口。
使用测试用例进行测试是简单的、可自动化的:工具如果设计恰当,只需简单点击、甚至使用脚本自动化,就完成了测试。另,可以在迭代的某些关键时刻进行自动化测试,比如:每次组员提交代码的时刻、每整点、每次构建版本时。
测试用例是永久性的:不同于口口相传的瞬时性。(当然文档、代码注释也是永久性的)。
测试用例不能做什么
测试用例只是开发阶段的测试,其不能代替后面测试阶段的真正人肉集成测试。
测试用例的心理纠结
“写测试用例太麻烦、太浪费时间啦!用不用测试用例呢?”。其实就是一个“重要事情”和“紧急事情”的权衡。都是有生活经验的人了,如何权衡,应该都懂。总之,建议,在没养成写测试用例的习惯之前、在没体验过测试用例到底花费多少时间之前,都不要武断给下结论“不写测试用例”。
UnityTestTool使用方法
下载,并导入到你的unity项目工程中
编写单元测试
创建单元测试代码文件。注意由于单元测试是不依赖于场景的,所以需要放在Editor目录下(因为项目中任意一个“Editor”目录都被Unity认为是特殊的“编辑器目录”)。
编辑单元测试代码
引用NUnit.Framework
给需要被测试的类添加[TestFixture]标签,给需要被测试的方法添加[Test]标签。
被测试的方法注意是无参数、无返回的函数。
如果认为有异常发生,通过throw new Exception("异常描述");
using NUnit.F
using MoreFun.C
namespace MoreFun.Editor.Test.Collections
[TestFixture]
class BasicTreeTest
public void AddAndRemoveChild()
TreeData data = new TreeData();
BasicTree tree1 = new BasicTree(data);
TreeData data2 = new TreeData();
BasicTree tree2 = new BasicTree(data2);
tree1.AddChild(tree2);
if (tree1.GetChildrenCount() != 1)
throw new Exception("测试失败");
//省略剩下代码...
在Unity打开UnityTestTool的单元测试面板,会发现刚写的测试代码已被自动添加到面板中。点击单元测试面板的播放键,就进行(需要人手UI操作的)单元测试了。
编写集成测试
创建测试场景
在Unity打开UnityTestTool的集成测试面板。点击“+”号,在这个测试场景添加一个测试用例GO(比如上面的BattleMessageTest和ActorTest)
给测试用例GO(比如ActorTest)下添加具体的GO(比如图中的“GameObject”),以及给GO添加测试脚本(比如图中的ActorTest)
在测试脚本调用IntegrationTest.Pass(),让测试用例通过;在测试脚本抛出异常,让测试不通过。
也可以配置测试用例GO里的具体参数
脚本自动化
使用脚本自动化的关键无非下面几点:
Unity可以以命令行模式进行运行,而且这时能够执行任意一个静态类的静态方法(详见)。
UnityTestTool提供了脚本执行的接口UnityTest.Batch.RunUnitTests()和UnityTest.Batch.RunIntegrationTests()。
注:RunIntegrationTests()本只能是从命令行取得需要测试的场景列表。建议修改RunIntegrationTests()的参数,允许以函数参数的方式传入需要测试的场景列表。
自动测试的结果会以xml的格式输出成文件。所以自动测试的后续流程(比如构建流程)可以依赖于生成的xml文件,判断测试是否通过,再决定是否真正执行。
具体脚本可参见最下面的附录。
更多详细用法,可以阅读导入到工程的UnityTestTool/Docs/下的pdf。
自动执行单元测试用例、集成测试用例的bat脚本:
echo "Start Unity Test Case"
%unity% -batchmode -projectPath %projectPath% -executeMethod CommandBuild.RunUnitTests -resultFilePath=%buildPath%/BuildTemp -quit -logFile %buildPath%/BuildTemp/RunUnitTests.log
%unity% -batchmode -projectPath %projectPath% -executeMethod CommandBuild.RunIntegrationTests -targetPlatform=%testTargetPlatform% -resultsFileDirectory=%buildPath%/BuildTemp -quit -logFile %buildPath%/BuildTemp/RunIntegrationTests.log
echo "End Unity Test Case, please see log: BuildTemp/RunUnitTests.log, BuildTemp/RunIntegrationTests.log"
echo "Start Build Unity to App"
%unity% -batchmode -projectPath %projectPath% -executeMethod CommandBuild.PreBuild %debugParam% -quit -logFile %buildPath%/BuildTemp/PreBuild.log
%unity% -batchmode -projectPath %projectPath% -executeMethod CommandBuild.Build %debugParam% -android -buildPath=%buildPath% -quit -logFile ./BuildTemp/Build.log
echo "End Build, please see log BuildTemp/PreBuild.log and BuildTemp/Build.log"
自动执行单元测试用例、集成测试用例的C#代码:
using UnityE
using UnityE
public class CommandBuild
private static string[] ms_scenes =
"Assets/Scenes/KillerStarter.unity"
private static System.Collections.Generic.List&string& ms_lstTestScenes = new System.Collections.Generic.List&string&()
"Assets/KillerInteTest/TestBattle/TestBattle.unity",
"Assets/KillerInteTest/TestUIBase/TestUIBase.unity"
/// &summary&
/// 执行UnityTestTool的单元测试
/// &/summary&
public static void RunUnitTests()
UnityTest.Batch.RunUnitTests();
/// &summary&
/// 执行UnityTestTool的集成测试
/// &/summary&
public static void RunIntegrationTests()
UnityTest.Batch.RunIntegrationTests(ms_lstTestScenes);
/// &summary&
/// 检测单元测试、集成测试输出的所有xml
/// &/summary&
/// &returns&&/returns&
private static bool CheckTestResult()
UpdateBuildTempFolderPath();
string[] lstXml = System.IO.Directory.GetFiles(ms_buildTempFolder, "*.xml");
if(0 == lstXml.Length)
Debug.Log("在" + ms_buildTempFolder + "目录未找到任何单元测试结果xml文件!");
foreach(string oneXmlFile in lstXml)
string oneXmlContent = System.IO.File.ReadAllText(oneXmlFile).ToLower();
if (oneXmlContent.Contains("success=\"false\"") ||
oneXmlContent.Contains("result=\"error\"")
Debug.Log("找到单元测试失败结果!在" + oneXmlFile + "。请查阅单元测试结果xml文件!");
Debug.Log("未检测到单元测试失败结果!检测文件列表:\n" + lstXml.JoinToString("\n"));
public static void Build()
Debug.Log("Build");
if (false == CheckTestResult())
throw new System.Exception("检测到测试用例结果失败!终止构建!");
// 省略以下构建代码
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
被以下专题收入,发现更多相似内容:
如果你是程序员,或者有一颗喜欢写程序的心,喜欢分享技术干货、项目经验、程序员日常囧事等等,欢迎投稿《程序员》专题。
专题主编:小...
· 150946人关注
欢迎投稿 将实用的知识共享
· 22096人关注
Tech Otakus Save the World~
· 1603人关注
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:可能问题不太准确,我不是说无法通过Lua或者其他的脚本语言通过内嵌虚拟机实现。
以下是我个人的猜测:Mono无法在非AOT模式下关闭JIT模式下运行吗?如果可以我觉得完全有可能在Mono层去掉AOT编译,关闭JIT就可以实现。还是说已经实现了,只是因为其他的原因没有人用?
或者可能是Unity在iOS平台如果不进行AOT编译就会导致整体的性能下降,那是否可以实现客户层指定的部分程序集使用非AOT编译?==============以下作为目标使用场景的补充=====================
所谓热更新就是指代码可以不通过重新打包提交App Store的方式来更新客户端的执行代码。由于以下几个原因客户端更新希望更加轻量和快速
1、App Store的审核周期比较难控制。
2、手机网络游戏更新频繁。
3、对于大型游戏,玩家更新成本太大。所以需要新的代码可以在简单的发布之后可以直接被客户端动态加载执行,而不需要重新提交App Store,玩家也不需要重新下载安装整个程序。
现有的方案是在Unity环境里内嵌一个Lua虚拟机,经常变动的和对执行效率没要求的逻辑用Lua实现,游戏启动时加载服务器上最新的Lua字节码来执行游戏。
如果C#的程序集可以动态加载,就无需嵌入其他的虚拟机来实现动态逻辑。
楼上已经把原因说的很明白了。iOS是不允许不通过AppStore更新代码的。Mono和Unity当然不会跟规定对着干。作为开发商你想绕过这些自己做热更新也不是没有办法。一个极端的例子就是WebView,js代码随便你怎么改不会有人管你的。又或者UniLua之类的解决方案。但是注意,这些玩法其实都是不符合规定的。所以如果万一搞大了苹果想要搞你就是分分钟的事。其实我一直觉得现在手游对于热更新的需求没有想象中的那么大。设计阶段做扎实一点,用数据驱动更新可以满足99%的case。
(有11张图,手机党酌情打开)&br&刚好上周CJ上Unity展台开展的技术讲座中有一节就是讲Unity iOS热更新的,照了照片,简单跟大家分享一下,可能稍微有点不对题,大家捡有用的看。&br&&br&首先,正如大家说的,Apple是不允许代码热更新的,Unity也只是给有热更新需求的提供一些建议,不会在官方层面提供解决方案,除非Apple放开。&br&&img src=&/f39a56c120fde1c63bc2_b.jpg& data-rawwidth=&3264& data-rawheight=&2448& class=&origin_image zh-lightbox-thumb& width=&3264& data-original=&/f39a56c120fde1c63bc2_r.jpg&&&br&然后讲了Unity热更新的注意点和Unity的几个重要路径&br&&img src=&/251d22e580e05e8aedbc00019aea5562_b.jpg& data-rawwidth=&3264& data-rawheight=&2448& class=&origin_image zh-lightbox-thumb& width=&3264& data-original=&/251d22e580e05e8aedbc00019aea5562_r.jpg&&&img src=&/afae7ca079c3d057a2e8d0_b.jpg& data-rawwidth=&3264& data-rawheight=&2448& class=&origin_image zh-lightbox-thumb& width=&3264& data-original=&/afae7ca079c3d057a2e8d0_r.jpg&&&img src=&/acc3da67d9ea8b1f09e960b_b.jpg& data-rawwidth=&3264& data-rawheight=&2448& class=&origin_image zh-lightbox-thumb& width=&3264& data-original=&/acc3da67d9ea8b1f09e960b_r.jpg&&&img src=&/47a94bdf18_b.jpg& data-rawwidth=&3264& data-rawheight=&2448& class=&origin_image zh-lightbox-thumb& width=&3264& data-original=&/47a94bdf18_r.jpg&&&br&然后是使用Lua进行iOS热更新的总体流程&br&&img src=&/68ae5ca288e1b924d1a03aad49ee293d_b.jpg& data-rawwidth=&3264& data-rawheight=&2448& class=&origin_image zh-lightbox-thumb& width=&3264& data-original=&/68ae5ca288e1b924d1a03aad49ee293d_r.jpg&&&img src=&/7aa8aa7fe19f68bed468dc2_b.jpg& data-rawwidth=&3264& data-rawheight=&2448& class=&origin_image zh-lightbox-thumb& width=&3264& data-original=&/7aa8aa7fe19f68bed468dc2_r.jpg&&&br&最后对支持Unity iOS热更新的各种插件进行了对比&br&&img src=&/cee460d8d73a1bf6ac8e1741_b.jpg& data-rawwidth=&3264& data-rawheight=&2448& class=&origin_image zh-lightbox-thumb& width=&3264& data-original=&/cee460d8d73a1bf6ac8e1741_r.jpg&&&img src=&/9ff3cecaebaad8184d8d_b.jpg& data-rawwidth=&3264& data-rawheight=&2448& class=&origin_image zh-lightbox-thumb& width=&3264& data-original=&/9ff3cecaebaad8184d8d_r.jpg&&&img src=&/11a48f4dfedc1e15d319b7c_b.jpg& data-rawwidth=&3264& data-rawheight=&2448& class=&origin_image zh-lightbox-thumb& width=&3264& data-original=&/11a48f4dfedc1e15d319b7c_r.jpg&&&img src=&/bb0f02b653e5_b.jpg& data-rawwidth=&3264& data-rawheight=&2448& class=&origin_image zh-lightbox-thumb& width=&3264& data-original=&/bb0f02b653e5_r.jpg&&&br&后面还有自己写的案例做的性能分析,拿uLua(Asset Store官方商店上的)、uLua&cstoLua(这两个最终肯定会统一)、sLua做对比,照片没拍,总共有六七种情况的对比,总结下来就是uLua(Asset Store)的性能消耗要比uLua&cstoLua和sLua大的多。&br&因为答主本身没有亲自做过iOS热更新,有不对的地方希望大家提出来共同讨论
(有11张图,手机党酌情打开)刚好上周CJ上Unity展台开展的技术讲座中有一节就是讲Unity iOS热更新的,照了照片,简单跟大家分享一下,可能稍微有点不对题,大家捡有用的看。首先,正如大家说的,Apple是不允许代码热更新的,Unity也只是给有热更新需求的提…
题主的问题:&br&&blockquote&Mono无法在非AOT模式下关闭JIT模式下运行吗?如果可以我觉得完全有可能在Mono层去掉AOT编译,关闭JIT就可以实现。还是说已经实现了,只是因为其他的原因没有人用?&br&&/blockquote&Mono的执行引擎有两种实现思路:&br&&ul&&li&编译:把MSIL编译为机器码。编译的时机可以在运行时(JIT编译),也可以在运行前(AOT编译)。&br&&/li&&li&解释:Mono有解释器实现,不过它只用于在移植到新平台时方便运行时和JIT编译器可以并行开发,JIT编译器开发好之后解释器就“退休”了。所以在发布出来的Mono build里都没解释器…(微软自家的CLR也是这个情况)。另外在最新的Mono里解释器已经被彻底去掉了:&a href=&///?target=https%3A///mono/mono/pull/1248& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&[runtime] Remove the interpreter. by kumpera · Pull Request #1248 · mono/mono · GitHub&i class=&icon-external&&&/i&&/a&&br&&/li&&/ul&于是对用户来说,Unity带的Mono就是不能配置成解释模式,而必须用编译模式的…&br&&br&话说题主能补充一下目标使用场景不?&br&所谓“热更新”代码是类似不通过AppStore下载更新,而直接下载更新代码并反映在应用里么?也就是说是一种部署场景的需求而不是调试场景的需求?
题主的问题:Mono无法在非AOT模式下关闭JIT模式下运行吗?如果可以我觉得完全有可能在Mono层去掉AOT编译,关闭JIT就可以实现。还是说已经实现了,只是因为其他的原因没有人用?Mono的执行引擎有两种实现思路:编译:把MSIL编译为机器码。编译的时机可以在运…
已有帐号?
无法登录?
社交帐号登录[Unity3D学习]Unity代码热更新解决方案测试结果总结
[Unity3D学习]Unity代码热更新解决方案测试结果总结
这几天一直在研究热更新方案
主要思路是:
1.先将代码打包成dll,然后用unity 打包成assetsbundle,
2.WWW加载进入主程序,
3使用System.Reflection.Assembly来创建程序集,
4.然后通过GetType(className),来获取这个类
5.AddComponent进入主程序,加载的dll就执行起来了。
ExportAssetBundles.cs
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 | pleteAssets, BuildTarget.StandaloneWindows);&&&&&&&&&&&&&&}&&&&}&&}
12345678910111213141516171819202122232425262728293031323334353637
using UnityEusing System.Cusing System.R//代码加载器public class Index : MonoBehaviour{&&&&private WWW&&&&public static WWW uiWWW;&&&&private System.Reflection.A // Use this for initialization void Start () &&&&{&&&&&&&&StartCoroutine(loadScript()); }&&&&private IEnumerator loadScript()&&&&{&&&&&&&&//加载我的代码资源&&&&&&&&www = new WWW("http://localhost/Main.assetbundle");&&&&&&&&&&&&&&&&AssetBundle bundle = www.assetB&&&&&&&&TextAsset asset = bundle.Load("Main", typeof(TextAsset)) as TextA&&&&&&&&assembly = System.Reflection.Assembly.Load(asset.bytes);&&&&&&&&Assembly[] assLis = System.AppDomain.CurrentDomain.GetAssemblies();&&&&&&&&System.Type script = assembly.GetType("Main");&&&&&&&&gameObject.AddComponent(script);&&&&}}
因为在加载的时候遇见安全沙箱问题,所以我将这个策略文件记录下来,方便下次复制粘贴
crossdomain.xml
&?xml version="1.0"?&&cross-domain-policy&&site-control permitted-cross-domain-policies=”master-only” /&&allow-access-from domain="" /&&allow-access-from domain="*"/&&/cross-domain-policy&
本地调试程序时解决跨域问题的方法:
Edit-&Project Settings-&Eidtor
刚开始的时候想使用序列化来存储一些数据,但是后来却连一个很简单的类序列化dll里面都没法获得
官方对象序列号
12345678910111213141516171819202122232425
[MenuItem("Custom Editor/WriteSpriteData")]&&&&static void FileWriteSpriteData()&&&&{&&&&&&&&TextAsset textasset = AssetDatabase.LoadAssetAtPath("Assets/Resources/Packer/Packer.txt", typeof(TextAsset)) as TextA&&&&&&&&Atlas atlas = ScriptableObject.CreateInstance&Atlas&();//Json其实是NGUIJson这个类,我只是把他提出来。改了个名字&&&&&&&&atlas.mList = Json.LoadSpriteData(textasset as TextAsset);&&&&&&&&if (atlas.mList == null)&&&&&&&&&&&&&&&&&&&&string path = "Assets/Resources/Packer/Packer.asset";&&&&&&&&AssetDatabase.CreateAsset(atlas, path);//Atlas是一个只有一个mList属性都类 mList = new List&UISpriteData&();&&&&&&&&Object o = AssetDatabase.LoadAssetAtPath(path, typeof(Atlas));&&&&&&&&Object texture = AssetDatabase.LoadAssetAtPath("Assets/Resources/Packer/Packer.mat", typeof(Material));&&&&&&&&Object[] t = {texture};&&&&&&&&BuildPipeline.BuildAssetBundle(o, t, "Assets/Resources/Packer/Packer.assetbundle");&&&&&&&&&&&&&&&&//AssetDatabase.DeleteAsset(path);&&&&}
这是使用序列化数据的加载方式,在不用反射的情况下,下面代码加载能够成功,但是使用了反射,下面的代码就加载不成功了。这个问题我也很费解,暂时我没办法解决
读取序列化对象
1234567891011121314151617181920212223242526
IEnumerator LoadAtlas()&&&&{&&&&&&&&www = new WWW("http://localhost/Packer.assetbundle");&&&&&&&&//WoodenAtlas.assetbundle&&&&&&&&//Packer.assetbundle&&&&&&&&//用来断点都时候看看里面所包含都数据&&&&&&&&Object[] os = www.assetBundle.LoadAll();&&&&&&&&Material mete = www.assetBundle.Load("Packer", typeof(Material)) as M&&&&&&&&Atlas atlas = www.assetBundle.mainAsset as A&&&&&&&&GameObject go = new GameObject("UIAtlas");&&&&&&&&UIAtlas uiatlas = go.AddComponent&UIAtlas&();&&&&&&&&uiatlas.spriteMaterial =&&&&&&&&uiatlas.spriteList = atlas.mL&&&&&&&&GameObject sprite = new GameObject("Sprite");&&&&&&&&UISprite ui = NGUITools.AddChild&UISprite&(sprite);&&&&&&&&ui.atlas =&&&&&&&&ui.spriteName = "dynamite";&&&&&&&&Debug.Log("Load");&&&&&&&&www.assetBundle.Unload(false);&&&&&&&&www.Dispose();&&&&&&&&&&&&}
因为要看一下代码的执行效率,所以我寻找到了这个类。感觉还可以。使用josn数据,mat文件创建一个UIAtlas的时间大概是30毫秒左右。
System.Diagnostics.SStopwatch stopWatch = new Stopwatch();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了。这样界面也得用配置文件了。
不过对于我这种从页游转过来的程序,这到不是问题,我有现成的界面编辑器(我博客里有),直接生成XML在游戏中进行组装了。对于能够热更新来说,这点麻烦,其实应该不算麻烦了。
动态生成UIAtlas后,创建了几个Sprite、Button,基本的功能都已经实现,说明这个解决方案是可行的。接下来我将把这个方案运用到我的项目中,更加全面的去实验一下。
这样设计的优点:
1、对IOS的打包也是比较方便。打包IOS 直接拿Main项目打包就可以了。因为不需要热更新了。把代码打包在本地就行了。
2、打包Android项目的时候发布apk只需要发布Index,项目发布版本和没写代码一样大,想到这里我想吐槽一下,Unity就算不写任何代码,发布一个apk也得有7M左右。这也太大了点吧。我可啥都没做啊。
1、哪位大神能给我说说上面我遇到的那个问题,为什么找不到绑定在prefab上的类呢?这是程序集的问题么?哎,刚转C#的人伤不起。
发表评论:
馆藏&20070
TA的推荐TA的最新馆藏[转]&[转]&[转]&[转]&[转]&[转]&[转]&[转]&[转]&[转]&}

我要回帖

更多关于 unity3d简单小游戏 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信