3.2 Unity中专用 JavaScript与通用 JavaScript的区别
虽然用于网页开发的JavaScript完全符合ECMAScript标准,但是Unity中的JavaScript语言却和ECMAScript标准相去甚远,比如用于网页的JavaScript库的绝大部分都无法在Unity中使用。本书将说明Unity 中专用JavaScript与通用(ECMAScript)JavaScript的区别。
3.2.1 在运行过程中性能的差异
Unity中专用JavaScript在运行过程中存在着很多特点,其不仅比JavaScript(ECMAScript)速度快,而且性能也更加优异,下面将分别讲解。
● 速度更快
Unity中的JavaScript已经编译过,其比动态的JSP更快。理论上,在Unity中JavaScript、C#和Boo没有速度上的差异,而且就算在Squirrelfish Extreme模式下,Unity的 JavaScript比“真正”的JavaScript还要快。
● 性能更优异
JavaScript很重要的优化是使用静态类型替代动态类型。Unity使用一种叫做类型推理的技术来自动转换 JavaScript为静态类型脚本。即Unity通过#pragma strict禁用脚本的动态类型,强制使用静态类型,并且加入了严格的变量检查机制,如果有未知类型的变量,Unity就会报告编译错误。
3.2.2 在语法上的区别
Unity中专用JavaScript在语法上也做了很多的改进,分别对类的定义与使用、继承的实现、数据类型与变量的声明、Mono(.NET)技术的调用以及调试等做出了许多的改进,接下来将逐一进行讲解。
1.类的定义与使用
Unity中一个JavaScript脚本文件就是一个类。可以声明一个和本脚本名字相同的类,如果在脚本中没有声明类,则 Unity 就以本脚本名自动命名一个类,脚本中的所有声明的对象将变为这个类的成员。
比如有一个 HelloWorld 的类,里面有一个 sayHello 的方法。新建一个名为 HelloWorld 的JavaScript脚本,然后在脚本编辑器里面进行编辑,具体的代码片段如下:
1 function sayHello() { //声明sayHello方法
2 print("Hello World"); //打印Hello World
3 }
然而也可以用下面这种写法,同样可以创建一个HelloWorld的类,具体的代码片段如下:
1 public class HelloWorld { //声名HelloWorld类
2 function sayHello() { //声明sayHello方法
3 print("Hello World "); //打印Hello World
4 } }
说明
双击Project面板中的HelloWorld.js脚本文件,Unity会默认使用Monodeveloper打开,如果读者喜欢其他的脚本编辑器,可以在Unity中设置更改,具体的操作是单击Edit→Preferences→External Tools→External Script Editor菜单进行修改。
2.继承的实现
Unity中JavaScript依然可以通过extends实现继承,如新建一个MyHello.js脚本,具体的代码片段如下:
1 class MyHello extends HelloWorld { //实现MyHello继承HelloWorld
2 //do something //实现特定的功能
3 }
这样,MyHello类就继承自HelloWorld类。
3.数据类型与变量的声明
Unity中变量使用前必须声明。声明方式是先写var,表示变量,然后是变量名,后面是冒号,冒号后面是变量的类型,即“var 变量名:变量类型”。
比如声明整形变量a,可以这么写:
var a : int; //声明整形变量
声明字符串类型的变量时,要注意变量类型是“String”,而且字符串的值必须用双引号,不能用单引号,可以这么写:
var s : String = "Hello World"; //声明字符串类型变量
若声明带参数的方法时,具体的代码片段如下:
1 function Test(var pa1 : String,var pa2 : Object) { //声明带参数的方法
2 //do something //实现特定的功能
4 }
另外要注意的是,如果声明变量的同时定义了变量的类型,在接下来的代码里面就不能修改变量的类型,例如:
1 var a =1;
2 a="test";
这时,Unity将会报错。但是,如果换一种声明方式就没有问题。具体见如下代码片段:
1 var a;
2 a=1;
3 a="test";
Math 在 Unity 中为 Mathf,只是名字改变,语法和用途没有改变,例如,Mathf.round()和Mathf.floor()在语法和用途上与JavaScript(ECMAScript)中的Math.round()和Math.floor()相同。
4.Mono(.Net)技术的调用
Unity中脚本的运行环境大量广泛地使用了Mono技术,当需要使用Mono相关类的时候,只需要导入即可,如:
1 import System;
2 import System.IO;
导入所需的类之后,只需要使用类名即可进行调用,例如,想在程序运行后删除Project面板里的Assets文件夹下test.txt文件,可用如下的代码片段来实现:
1 import System; //导入系统包
2 import System.IO; //导入系统包
3 function Start () { //重写Start函数
4 File.Delete("Assets\\test.txt"); //删除文件
5 }
除了上面的方式,也可以使用全称类名来进行调用实现相同的功能,具体可使用如下代码:
1 function Start() { //重写Start函数
2 System.IO.File.Delete("Assets\\test.txt"); //删除文件
3 }
但很少真正有开发人员实际开发时不进行导入,直接都使用全称类名的,因为这样写起来太费事了。
提示
懂一点C#的读者会发现:“所谓的Mono类不就是.NET框架中的系统类吗?”确实如此,Mono 是一个由 Novell 公司主持的项目。该项目的目标是创建一系列符合ECMA 标准(Ecma-334 和Ecma-335)的.NET 工具,包括C# 编译器和通用语言执行平台。与微软的.NET Framework不同,Mono项目不仅可以运行于Windows系统上,还可以运行于Linux、FreeBSD、Unix、Mac OS X和Solaris等其他操作系统。
同时,在Unity中还可以使用第三方的.NET类库,如果需要时,导入所需的.dll文件即可。
5.调试
Unity 中脚本的错误将用红色叹号标识。在 Unity 中的控制台(Console)中包含了当前的全部错误,每一个错误信息都明确指明了脚本出错的位置和原因。若这个错误是脚本错误,当双击这个错误时,可以自动跳转到默认的脚本编辑器中,然后光标会在错误所对应行的行首跳动。
Unity 也收集了有效的警告信息,用黄色叹号表示。这些警告信息反馈了哪些变量声明了却没使用,或者自定义的方法可能返回默认值等。尽量修改代码,使其不再产生警告信息,这是一个很好的编程习惯。
提示
Unity将调试的信息显示在控制台(Console)中,无需开发人员去编写关于显示调试信息的代码,这为代码的调试提供了方便。
在Unity中,可以使用print()和Debug.Log()打印调试信息。但是print()只能在Mono的类中使用,所以一般情况下最好使用Debug.Log(),它和print()效果一样,但是它可以在各处使用。同时也可以使用Debug.LogWarning()和Debug.LogError()收集警告和错误信息。
Unity 中通过 Debug.Break()设置断点。如果想查看特定情况发生时对象属性的变化时,用断点可以快速地完成。