原标题:程序丨如何将你的Unity代码整理到一个DLL中?
翻译:林政(玄猫大人)
审校:沈晓霖
代码复用的重要性
这里有一则故事也是你听过类似的:
你下载好Unity,看完Youtube上的一些教程,并且在同一天制作了一个附带物理效果的游戏。真是激动人心,你开始制作自己一直想做的游戏。你可能尝试使用GameMaker这类的工具进行制作,利用文件夹,子文件夹,逻辑命名脚本等方式管理你的源代码。
时间飞快的过去了几个月,你已经在40个子文件中拥有了50个脚本,有一些被复用,有一些被硬编码到你的游戏中。好…吧…这还不是太糟糕,这时在你面前出现了一个新的机遇:一份付费的合同,一个游戏创意设计,来自朋友的贡献,然后你想复用你主项目中的代码。你看了看文件夹结构,又看了看它们是如何相互交织,互相调用……你默默的流下了眼泪。
没有复用的代码,会让一个看起来简单的项目变成工作量巨大的苦差事,并且你永远不会完成它。所有的一切都将会回到起点:(
Unity中的代码复用
在制作Unity应用过程中代码复用主要有五个方面。大多数的原则与通用编程相通,但以下这些是我发现在Unity开发中特别需要注意的几点。
好的命名
为了在程序中更好的命名,我们需要把关注点放在例如“什么是不好的命名”和“什么是不要做的”等方面。
如果你需要打开你的脚本看看,才知道它的具体功能…那么它的命名是错误的
如果你在别的脚本中引用它时,你需要保证它是打开的情况…那么它的命名是错误的
如果你的脚本已经超过了一千行…那它的命名是错误的,同时你还把太多不必要的东西放到了同一个脚本里,必须把它们分离开!
如果你找不到你的脚本,因为你不记得把它放到了哪个文件夹之中…那么文件夹的命名方式是错误的,并且脚本的命名方式也是错误的(取的名字能够让你在第一时间就明白应该把它放到哪一个正确的地方!)
…等等其他方面
在unity中重命名脚本略微有些蛋疼:在重命名一个脚本之后,你需要在MonoDevelop中关闭它,然后重新打开它,(假设这是一个C#类)重命名才会在源代码中生效。(我希望在最新的Unity中能自动化处理好这个过程,但我现在的版本并不行)
译者注:该篇文章发表的时间较早,在目前版本的Unity中已经能够很方便的进行重命名,直接在脚本中鼠标右击需要重命名的类名(选择Refacter->ReName)就能进行重命名类名和对应该类的文件名。
你需要子文件夹,很多很多的子文件夹
《黑客帝国》中大量文件夹的视频
你永远不会拥有太多,虽然它们都有好的名字。
给你的代码解耦合
哈,现在的问题变得棘手了。解耦合是一门艺术,需要很多的练习才能掌握。
C#(和JAVA)中的“interface”关键字就是为了解耦而存在的。当你用过这个概念后就会发现它非常容易理解,因为代码的内部依赖过于紧密,写代码时复用就变的十分困难。
“我没有办法通过简单的复制粘贴操作将我的代码移植到一个新项目里,因为它依赖了另外3个脚本代码,它们当中的每一个。。。又依赖了另外12个脚本代码,啊!“
Unity自身并没有用到Interfaces(虽然真的应该这么做!),你需要动用一点聪明才智去使用它(用谷歌搜索一下,这只是个小问题)。但是C#只是简单的将interfaces当作一种解耦的编译兼容方式提供给我们:你需要在设计类的开始阶段就使用它们进行解耦。接着可以通过谷歌进行相关内容的扩展了解--因为这个话题太大了,我们这里点到为止。
打包你的代码,这样你就可以复用它
类库,这就是为什么编程之神发明了类库。所以我们要如何做在unity中使用类库呢?
Unity中的类库:简单使用DLL
有两种DLL:
真正的DLL,就像使用原生代码一样,它们都是用C++语言编写的
伪造的DLL,正如我们其他人所使用的一样,它让我们更专注于制作游戏上
使用DLL打包代码是一种很好的方式,在标准工作环境中被广泛使用。当然unity中也是这样做的(干得漂亮),但是如果你用“unity make DLL”为关键字在谷歌中搜索,你会得到大量混淆视听的信息和关于进一步整合C++和unity方法的有关内容,实际上你并不需要它们。你最好搜索“DLL light”,这样会更容易得到你想要的结果。
但是和unity的大部分功能一样,它几乎没有文档。而且开箱即用的情况下,它会失败。与此同时,当它出错的时候会给你完全错误的提示,耶!
第一步:在Unity中编写脚本
做一些简单的例子,按照XKCD的建议我写了一个获取随机数的类:
编写第二个脚本,并在其中调用第一个,如下:
将脚本挂载到一个GameObject上,查看它的工作情况。
第二步:根据Unity文档创建并使用DLL
你会认为这就足够了,其实不然。然而,文档是直接、简单、明了,我发现他们很容易跟着一步一步做下来。
地址如下:http://docs.unity3d.com/Documentation/Manual/UsingDLL.html
请注意:文档里使用的脚本比我给的例子更复杂,但不论如何,它们在中心思想方面是一致的
第三步:使用命名空间,接口,和…
现在你的DLL就可以在MonoDevelop中编译和构建了…你将不再会受到Unity任何的规则和限制!世界是你的了!
(在Unity 3中,你已经可以使用命名空间,这样你就能更容易的组织你的代码:)
第四步:关于[方括号]?
它们就像商标™一样出现在Unity脚本中。例如:
第五步:编辑器扩展,编辑器脚本,编辑器GUI,等等
这和以往其他地方有些不同。如果你有一个编辑器脚本(该脚本必须放在“Editor”文件夹,或者它的其中某个子文件夹中),你可以将它包含到你的DLL中,但是它不会起任何作用。
更糟糕的是,当你触发它们时(例如,通过选择一个对象,并自定义编辑器的渲染),你会得到:
Error:multi-objectediting not supported!(错误:不支持编辑多个对象)
至少你在unity3.x版本中存在这种问题,4.x版本中我猜测已经修复了这个问题?我没有去尝试,因为我已经修复了这个问题:)
在互联网(unity论坛)上有一些关于该问题的复杂解决方案,特别是由AngryAnt所发表的这篇(http://angryant.com/2014/01/03/Unity-and-net-assemblies/),但是看这些东西既过时也没什么必要,修复起来其实很简单,我们需要创建两个DLL!
DLL#1:这个我们已经拥有了
DLL#2:只包含编辑器使用的脚本,然后我们把它拖拽到“Editor”文件夹中
这非常符合逻辑,简单并且容易记住如何操作,而且效果还十分完美!但是…我们要怎么做呢?
第五步A小点:升级你的MonoDevelop项目输出两个而不是一个DLL
第一步,右击MonoDevelop最顶部的“Solution”面板,然后选择“Add New Project...”
在做这件事情之前,选择“类库(C#)”。我们建议将脚本命名为“Something-SomethingEditors(做什么事情-做什么事情编辑器脚本)”(这里的“SomethingSomething”是你用着第一个类库上的名字)
第二步,你需要编辑你的引用(就像你在第一个DLL里面做的一样),重复这一步骤并且直到所有的添加完成。
UnityEngine.dll
UnityEditor.dll
...
并且:在“Project”选项卡中选中你的主DLL/类库,用于取代“.Net Assembly”。这是你唯一的选择
做完这些之后大概是这样。
这样我们就在MonoDevelop中拥有了两个项目,一个包含了正常unity使用的东西,另一个包含了Unity Editor(编辑器)使用的东西。并且第二个项目“依赖”于第一个项目,我们可以从第一个项目看见/使用/创建类和方法。
第五步B小点:把类库放到不同的地方
构建并且找到你的输出文件。第一个项目/DLL只会生成一个DLL,但是第二个项目/DLL会生成两个项目并且同时包含两个DLL。
确保你将第一个DLL放在“除了Editor文件以外的任何地方”,并且第二个DLL存放在“Editor文件或者它的其中某个子文件夹下”。
最后,创建一个GameObject,在Unity工程视图中打开DLL(展开三角形),然后在将需要的脚本拖放到对象上。在场景视图中单击它们,你的OnGUI,OnGizmos等等这些方法应该和其他正常情况一样运行无误。
第六步:庆祝!
现在你可以把两个DLL代码拖放到一个新的Unity项目中,与其他Unity项目分享代码了!
漂亮!容易,简单,简洁明了,这就是我喜欢的代码复用...
【版权声明】
原文作者未做权利声明,视为共享知识产权进入公共领域,自动获得授权。
今日推荐
添加小编微信,可享双重福利
1.加入GAD程序猿交流基地
获取行业干货资讯,观看大牛分享直播
2.直接领取60G独家程序资料库,地址在小编朋友圈
包括腾讯内部分享、文章教程、视频教程等全套资料
↓长按添加小编GAD苏苏↓返回搜狐,查看更多
责任编辑: