使用脚本
此处简单介绍如何在工程中创建和使用脚本。有关撰写 API 脚本的详细信息,请参阅 Scripting Reference | 脚本撰写参考手册。有关通过撰写脚本创建游戏的详细信息,请参阅本手册的创建游戏 (Creating Gameplay) 部分。


Unity 中的行为脚本可使用 JavaScript、C# 或 Boo 撰写。您也可在单个工程中使用这三种语言的任意组合,但是一种脚本采用其他脚本中定义的类时可能存在一些限制。


新建脚本
脚本文件不同于网格 (Meshes) 或 (Textures) 等其他资源,其可在 Unity 中创建。要新建脚本,请在主菜单中依次单击资源 (Assets)->创建 (Create)->JavaScript (或资源 (Assets)->创建 (Create)->C Sharp Script 或 资源 (Assets)->创建 (Create)->Boo Script)。这将新建一个名为NewBehaviourScript的脚本,将其置于工程视图 (Project View) 中的所选文件夹下。如果没有在工程视图 (Project View) 中选择文件夹,将在根级别上创建脚本。




您可在工程视图 (Project View) 中双击此脚本进行编辑。这将按照 Unity 偏好设置启动默认文本编辑器。要设置默认脚本编辑器,请更改Unity->偏好设置 (Preferences)->外部脚本编辑器 (External Script editor) 中的下拉项。


以下是一个新建的空行为脚本示例:

function Update () { 

 }  

 新建的空脚本本身没多少作用,所以需要我们添加一些功能。请按以下方式更改脚本内容: 



 function Update () { 

     print("Hello World"); 

 }

 
执行脚本后,这段代码会在控制台中打印 "Hello World"。但现在还没有任何东西可触发代码的执行。必须将脚本附加到场景 (Scene) 中的活动游戏对象 (GameObject) 后才可执行脚本。


将脚本附加至对象
保存上述脚本,然后在场景 (Scene) 中选择游戏对象 (GameObject)->新建 (Create Other)->立方体 (Cube) 来新建对象。




现在,将脚本从工程视图 (Project View) 拖曳至立方体 (Cube)(位于场景 (Scene) 或层级视图 (Hierarchy View) 中都可以)。您也可选中立方体 (Cube),然后选择组件 (Component)->脚本 (Scripts)->新行为脚本 (New Behaviour Script)。任一方法都可将脚本附加至立方体 (Cube)。创建的每个脚本都将显示在组件 (Component)->脚本 (Scripts) 菜单中。




如果您选择立方体 (Cube),然后查看检视器 (Inspector),您会发现此脚本已显示出来。这表示脚本已附加至对象。




按下播放 (Play) 按钮测试创建效果。您可看见播放 (Play)/暂停 (Pause)/单步 (Step) 按钮旁边显示文本"Hello World"。请在看见此文本时退出播放模式。




操控游戏对象 (GameObject)
print()语句在调试脚本时可能非常有用,但脚本不可操纵附加至其本身的游戏对象 (GameObject)。让我们更改脚本添加一些功能:

function Update () { 

     transform.Rotate(0, 5*Time.deltaTime, 0); 

 }


如果您不大熟悉脚本,这些代码看起来头疼是很正常的。以下是一些需要理解的重要概念:


function Update () {}是一个用来存放 Unity 每秒执行多次的代码的容器(每帧执行一次)。
transform 是游戏对象 (GameObject) 变换组件 (Transform Component) 中的引用。
Rotate()是变换 (Transform) 组件 (Component) 中包含的函数。
用逗号隔开的数字分别表示三维空间中的 X、Y、Z 轴的旋转角度。
Time.deltaTime是 Time 类的一个成员,用来指示事件一秒内变化的量。无论你的机器一秒钟播放多少帧,立方体都会以相同的速度旋转。因此,5*Time.deltaTime 表示 5 度/秒。
了解这些概念后,我们能够理解这段代码为"每一帧,让此游戏对象 (GameObject) 的变换 (Transform) 组件旋转一个小角度,这样可保持这个对象沿着 Y 轴每秒旋转 5°"。


您可以按照我们访问变换的相同方式访问许多其他组件 (Components)。您必须使用组件 (Component) 菜单将组件 (Component) 添加至游戏对象 (GameObject)。您可直接访问的组件 (Components) 都列在游戏对象脚本参考手册页面 (GameObject Scripting Reference Page) 的变量 (Variables) 中。


更多有关游戏对象 (GameObjects)、脚本 (Scripts) 和组件 (Components) 之间关系的信息,请转至游戏对象 (GameObjects) 页面或本手册的使用组件 (Using Components) 页面。


变量的力量
到目前为止,我们的脚本始终保持让立方体 (Cube) 每秒旋转 5 度。我们可能需要改变立方体每秒旋转的度数。我们可以更改此数字并保存,但我们必须等待脚本被编译,还必须进入播放模式才可查看结果。这里有一种更快速的解决方法。我们可以在播放模式下实时试验旋转速度,这很容易做到。


我们将使用速度变量,并在函数中使用此变量,而非在 Rotate() 函数中键入5。将脚本更改为以下代码并保存:

var speed = 5.0; 



 function Update () { 

     transform.Rotate(0, speed*Time.deltaTime, 0); 

 }


现在,选择立方体 (Cube) 并查看检视器 (Inspector)。注意看速度变量是如何显示的。




现在可直接在检视器 (Inspector) 中直接修改此变量。选中变量,按退格 (Return) 键修改值。您也可右键单击或在选项 (option) 上单击此值,并拖动鼠标向上或向下。您随时可更改变量,甚至包括游戏运行时。


点击播放 (Play) 并尝试修改速度值。立方体的 (Cube) 的旋转速度将立即发生改变。退出播放 (Play) 模式后,您会看到改变的值又恢复为您进入播放 (Play) 模式前的值。这样,您可播放、调整和试着查找最佳值,然后一直使用这个值。


在检视器 (Inspector) 中更改变量值的技术,可以让您轻松将一个脚本重复使用在多个对象上,每个对象都有不同的变量值。如果将脚本附加到多个立方体 (Cubes) 并更改每个立方体的速度,则所有立方体将以不同的速度旋转,即使它们使用的是相同的脚本。


访问其他组件
撰写脚本组件时,您可以访问脚本内游戏对象 (GameObject) 上的其他组件。


使用游戏对象 (GameObject) 成员
您可以直接访问游戏对象 (GameObject) 类中的任意成员。在这里,您将看见 游戏对象 (GameObject) 类所有成员的列表。如果将任何指定的类作为组件 (Component) 附加至游戏对象 (GameObject),只需在脚本中输入成员名称即可直接访问组件 (Component)。例如,输入 transform 等价于输入 gameObject.transform。游戏对象是通过编译器来确认的,除非你专门引用一个不同的游戏对象 (GameObject)。


输入this 将可以访问您正在撰写的脚本组件 (Component)。输入 this.gameObject 将可以访问附加此脚本的游戏对象 (GameObject)。输入 gameObject 即可访问该游戏对象。从逻辑上来说,输入 this.transform 相当于输入 transform。如需访问非游戏对象 (GameObject) 成员的组件 (Component),则必须使用 gameObject.GetComponent(),对此我们将在下一页进行介绍。


有许多组件 (Components) 都可直接在任意脚本中访问。例如,如需访问变换 (Transform) 组件的 Translate 函数,您只需输入 transform.Translate() 或 gameObject.transform.Translate()。此方法之所以有用,是因为所有脚本已附加至游戏对象 (GameObject)。输入 transform 时,则表示您将以隐性方式访问正在撰写其脚本的游戏对象 (GameObject) 的变换组件 (Transform Component)。明确一点,您需要输入 gameObject.transform。各种方法没有优劣之分,全由脚本撰写人员的喜好决定。


要了解您可以隐性方式访问的所有组件 (Components) 列表,请参阅脚本撰写参考手册 (Scripting Reference) 的游戏对象 (GameObject) 页面。


使用 GetComponent()
有许多组件 (Components) 未直接引用为游戏对象 (GameObject)类的成员。所以您无法以隐性方式访问它们,您必须以显性方式访问它们。为此,您可以调用 GetComponent("组件名称") 并将引用存储至结果。这在您需要引用附加至游戏对象 (GameObject) 的其他脚本时最为常见。


如果您正在输入 Script B 并需要引用已附加至同一游戏对象 (GameObject) 的Script A,您必须使用 GetComponent() 进行引用。在脚本 B (Script B) 中,您只需输入:


scriptA = GetComponent("ScriptA");




如需获取有关 GetComponent() 使用方法的更多帮助,请参阅GetComponent() 脚本参考手册 (Script Reference) 页面。


访问其他脚本组件 (Components) 中的变量
附加至您游戏对象 (GameObjects) 的所有脚本都是组件 (Components)。因此,您可在脚本中使用 GetComponent 方法访问公共变量(和方法)。例如:

function Start () { 

    // Print the position of the transform component, for the gameObject this script is attached to 

    Debug.Log(gameObject.GetComponent<Transform>.().position); 

 } 

 在之前的 GetComponent<T> 示例中,函数用于访问变换 (Transfor) 组件的位置属性。此方法也可用于访问自定义脚本组件中的变量: 



 (MyClass.js) 

 public var speed : float = 3.14159; 



 (MyOtherClass.js) 

 function Start () { 

    // Print the speed variable from the MyClass script Component attached to the gameObject 

    Debug.Log(gameObject.GetComponent<MyClass>.().speed); 

 }


访问 Javascript C# 中定义的变量
要在编译 Javascript 代码时访问 C# 脚本中定义的变量,则必须存在包含 C# 代码的已编译程序集 (Assembly)。Unity 在不同阶段执行编译,详情请参阅脚本参考手册 (Scripting Reference) 的脚本编译 (Script Compilation) 部分。如需创建使用 C# 脚本中的类或变量的 Javascript,只需将 C# 脚本放入 "标准资源 (Standard Assets)"、"专业版标准资源 (Pro Standard Assets)" 或 "插件 (Plugins)" 文件夹和这些文件夹外的 Javascript。系统将首先编译"标准资源 (Standard Assets)"、"专业版标准资源 (Pro Standard Assets)" 或 "插件 (Plugins)"中的代码,然后再编译这些文件夹外的代码,以便编译步骤(您的 C# 脚本)中定义的类型 (Types) 能够用于之后的编译步骤(您的 Javascript 脚本)。


一般而言,"标准资源 (Standard Assets)"、"专业版标准资源 (Pro Standard Assets)" 或 "插件 (Plugins)" 文件夹中的代码,无论使用何种语言(C#、Javascript 或 Boo),都将首先被编译,并且其结果可用于后续编译阶段的脚本中。


优化变量访问
在某些情况下,您可能会在代码或每帧中多次使用 GetComponent。每次调用 GetComponent 都需要在内部执行几个额外步骤才可获取所需的组件引用。有一个更有效的方法,例如,将引用存储至 Start() 函数中的组件。这样您既可存储引用也不会直接检索引用,这对于检查 null 引用也是一个好方法:

(MyClass.js) 

 public var speed : float = 3.14159; 



 (MyOtherClass.js) 

 private var myClass : MyClass; 

 function Start () { 

    // Get a reference to the MyClass script Component attached to the gameObject 

    myClass = gameObject.GetComponent<MyClass>.(); 

 } 

 function Update () { 

    // Verify that the reference is still valid and print the speed variable 

    if(myClass != null) 

       Debug.Log (myClass.speed); 

 }


静态变量
也可在您的类中定义静态变量。 这里将有一个且只有一个特定类的静态变量实例,您无需实例化类对象就可修改静态变量实例:


(MyClass.js) 

 static public var speed : float = 3.14159; 



 (MyOtherClass.js) 

 function Start () { 

    Debug.Log (MyClass.speed); 

 }


建议不要在对象引用中使用静态变量,以确保未使用的对象能够从内存中删除。


这只是一个如何在编辑器中使用脚本的简短介绍,有关更多示例,请参阅 Unity 教程,教程可从我们的资源商店 (Asset Store) 免费获取。您也可通读脚本参考手册 (Script Reference) 中的 脚本概览 (Scripting Overview),它详细介绍了使用 Unity 撰写脚本的方法,并随附链接至更多详细信息的指针。如果您确实没弄明白,请务必访问 Unity 问答 (Unity Answers) 或 Unity 论坛 (Unity Forums) 并在这里提问。您将在此找到满意答案。