学习使用C#进行Unity3D脚本编程
Unity3D 提供了三种可供选择的脚本编程语言:JavaScript, C# 以及 Boo。尽管它们各有各的优势与不足,但对我来讲C#显然会脱颖而出成为我的首选——首选,它完整支持面向对象,而且语法与Java以及ActionScript 3很类似,而这两者都是我所熟悉的。不过在接触Unity3D之前,我一行C#的代码都没写过,所以我必须从头学起。
C#由Microsoft提出并广泛使用于.NET framework以及Silverlight开发中。不过我们首先需要明白的是,学习用于Unity3D的C#并不等同于学习.NET平台,事实上你并不需要了解所有关于.NET的事情就可以使用C#为Unity3D编写脚本程序。
尽管我平时使用各种在线文档,但是一本实体书通常才是最好的助手,于是我决定买一本C#好书。O’Reilly C# Pocket Guide看起来正是我所需要的,购买一本500页的C#圣经显然是没有必要的,因为那些书中大部分内容都是与.NET相关的,根本无法与Unity3D兼容。
当然,仅仅依靠这一本书是不够的,你还需要经常查阅 Unity3D scripting reference。文档中所有的例子都是用Javascript书写的,但是不必担心,一旦你熟悉C#后将它们翻译为C#语言将轻而易举。
C#是一种非常典雅而强大的编程语言,它的dot-syntax命名法则基于Java,所以如果你具有Java编程背景将感到非常舒服。不过区别也还是有一些的,最明显的应该是在C#中属性以及方法的名称约定俗称都是以大写字母开头的。 我估计这是继承自Visual Basic的习惯,我并不是这种习惯的簇拥,但是与其反抗到底还不如接受它以保证代码的一致性。
C#的特性列表实在太长,这使得ActionScript实在是看起来有些相形见绌。 C#与Actionscript从本质上是极为相似的,我估计下一次ActionScript的升级中至少会实现C#的一些特性,因此有必要在此预先有所了解。下面是我所钟爱的一些特性。
运算符重载这是目前为止最酷的!它允许程序员为+-*/这样的运算符定义特殊的行为。它的优势在向量加法运算中就可以明显体现出来,在ActionScript中,要计算向量之和,你需要书写类似下面的代码: var c:Vector3D = a.add(b);
这样并不是很好,在多于两个向量相加时代码的易读性会变得很差。如果在C#中重载+运算符,代码将会变成下面的形式:
Vector3 c = a + b;
这样是不是可读性更好而且更为优雅呢?不用想我们就可以猜到,在Unity3D中所有向量的运算符都进行了重载。如果你希望自己实现,运算符重载也非常简单,对于上面的例子,代码大致是下面这个样子的:
public static Vector3 operator + (a:Vector3, b:Vector3) {
return new Vector3(a.x + b.x, a.y + b.y, a.z + b.z);
}
这其中有一些简单的规则:运算符函数永远都是静态的(static),并且需要返回它所定义的对象类型。不过它的参数可以是任何类型的,因此完全可以重载加法或乘法运算符使其支持向量与浮点数或者与矩阵的运算——而这一切都要得益于C#对运算符重载功能的支持。
方法重载方法重载可以允许我们定义多个同名但参数不同的方法。它不但对一般方法起作用而且也可以应用于构造函数——如果有多种途径来初始化一个对象,那么你可以为每一种途径定义一个专有的构造函数。而且方法重载同样可以应用于运算符方法,这一点上面已经提到了。
在Unity3D API中一个关于运算符重载最好的例子就是’Transform.Rotate()’这个方法,它被重载了三次以满足不同的旋转参数:
void Rotate (Vector3 eulerAngles, Space relativeTo)
void Rotate (float xAngle, float yAngle, float zAngle, Space relativeTo)
void Rotate (Vector3 axis, float angle, Space relativeTo)
你可以指定欧拉角,也可以指定旋转轴以及旋转角度。
ActionScript可以使用默认参数来模拟方法重载,但是这样做并不方便也不便于理解。
Getter/Setter语法C#声明参数的方法非常简明扼要,在ActionScript中需要两个方法——一个’get’一个’set’,而在C#中的代码则是这样的: public float Size { get; set; }
在这种情况下,你不需要额外做任何工作编译器就会自动创建一个私有属性,当然,这样的定义没什么用处,下面列举一个稍微复杂点的,包括一个public的get以及private的set: public float Area {
get { return size * size; };
private set { size = Mathf.Sqrt(value) };
}
想必你应该已经注意到了,尽管C#源自Java,在C#中却并不使用’function’和’var‘关键词——这样做之所以好是因为这两个关键词完全是冗余的病情不会为代码增加任何有价值的信息。
对于其他特性,我推荐看看indexers,generic types,structures以及enumerators,在上面提到的C# Pocket Book中都有详细介绍,许多C#教程中也有涉及。
编辑C#很多编辑器都支持C#,微软提供的Visual C# Express Edition免费而且非常好用,支持代码自动补完功能,但是只对应Windows平台(显然的)。对于Max平台Mono Develop看起很强大但是还并不是很稳定。 不幸的是Eclipse的C# plugin目前为止非常不稳定,所以我并不推荐,但好在它目前还处于Alpha阶段,我们应该再多给它一些时间。当然,不论如何,我们最后至少还可以求助于TextMate。
最后需要提到的是Unitron——Unity3D自带的默认编辑器。在开发者中间它并不怎么流行,而且我看到有人抱怨他过于基本了,我并不认同这种观点。虽然它不如FDT之于ActionScript那样强大,但是它非常稳定而且具备基本的代码自动补完功能——有趣的是,自动补完功能在默认设置下是关闭的(为啥?),要开启该功能需要打开’Preferences’,你会在’General’面板的底端找到这个选项,如此一来我相信Unitron还是值得一用的。
我们中很多人都是在浏览器环境下认识Javascript的,而Javascript也是很多人平生第一次使用的编程语言。如果是这种情况的话,你很可能会立刻开始使用Javascript进行Unity3D的编程而不必操心要学习什么新东西,毕竟,如Unity3D所说,任何使用C#可以完成的事同样可以使用Javascript完成。
但是从长远考虑的话,C#可以提供更好的代码管理,完整的OOP支持,strong typing以及掌握一门优秀编程语言所带来的成就感。因此,额外付出的努力是值得的,更何况,对于一个经验丰富的AS3开发者,掌握C#只是几个礼拜的事儿,现在就动手尝试一下吧!