在Unity中脚本是必不可少的。因为他将定义你游戏的各种行为和规则。

目标

在Unity中,脚本是用来界定用户在游戏中的行为或规则。Unity推荐使用的编程语言是JavaScript,同时也支持C#或Boo。本文上部继续深入探讨Javascript在Untiy中的必要性及使用方式。

访问组件

一个游戏对象可能有多个脚本或其他组件。它将不可避免的要访问其他组件的函数或变量。Unity中通过GetComponent()函数来实现这个目的。我们现在要实现按下空格键后让聚光灯照向Cube。

我们考虑一下这个步骤:1.监视空格键被按下。2.空格键按下后聚光灯照向Cube。

由于SporLight脚本中有target变量,我们只需要为这个变量设定新的值就可以了。

创建一个脚本,命名为Switch,添加如下代码:

1
var switchToTarget : Transform;  
2
function Update(){  
3
    if(Input.GetButtonDown("Jump"))  
4
        GetComponent(SpotLight).target = switchToTarget;  
5
}
6
注意GetComponent()的参数,它将返回一个参数给Switch脚本,我们就可以用它来访问“target”变量。

这里的GetComponent获取的不是点光源,而是那个名为SpotLight的JS文件。

添加Switch脚本到聚光灯对象,并将Cube拖放到Inspector面板中的switchToTarge变量上。

运行。按下空格后,聚光灯将照向Cube。

前面我们提到,可以通过写代码的方式指定变量(而不是通过Unity界面),如何做到呢?上面按下空格时告诉聚光灯聚焦到Cube上,我们是在SpotLight脚本中做一个显式的变量,将Cube拖放上去。而在代码中主要有2种方法去实现:使用对象的名称(name)与使用对象的标签(tag)

1.对象名称

可以从Hierarchy面板上看到对象的名称。用GameObject.Find()函数来使这些名称作为参数。因此,我们可以这样写:

1
function Update(){
2
if(Input.GetButtonDown("Jump"))
3
{
4
var newTarget = GameObject.Find("Cube").transform;
5
GetComponent(SpotLight).target = newTarget;
6
}
7
}
注意,以上没有出现显式的变量。

2.对象标签

对象标签是一个字符串,用来识别一个组件。在Inspector面板中点击Tag按钮查看内建的标签。我们也可以创建自己的标签。GameObject.FindWithTag()函数能通过具体的标签寻找组件并返回一个字符串作为参数。

1
function Update(){
2
if(Input.GetButtonDown("Jump"))
3
{
4
var newTarget = GameObject.FindWithTag("fang").transform;
5
GetComponent(SpotLight).target = newTarget;
6
}
7
}
我们要在运行时创建(create)对象就要用到Instantiate函数。让我们来实现如何在每次按下开火按钮(鼠标左键或Ctrl键)后通过实例化一个新的对象。需要思考以下几点:

1.哪个物体做我们的实例?

2.在哪儿实例化?

关于第一个问题,最好的办法就是显式变量。这样我们就可以随时通过拖放来改变我们的实例对象。至于在哪儿实例化,我们只要实现当按下开火键时,在用户的当前位置创建一个对象即可。实例化函数有3个参数:1.我们要建立的对象。2.对象的位置坐标。3.对象的旋转位置。完整的代码如下:

1
var newObject : Transform;
2
function Update(){
3
if(Input.GetButtonDown("Fire1")){
4
Instantiate(newObject, transform.position, transform.rotation);
5
}
6
}
要记住,transform、position、transform、rotation是附加这个脚本的物体的位置。我们这里假设为主相机。一般情况下,将要被实例化的对象设置为预设(prefab),我们现将Cube设置为预设。

首先,让我们创建一个预置。Assets->Create->Prefab。命名为Cube。从Hierarchy面板中选取Cube拖放到Project面板的Cube上。创建一个脚本并命名为Create,并把上面的代码加进去。把这个脚本赋予相机,并将Cube预设赋予脚本变量。运行。移动相机并按下开火键,你能看到新的Cube出现。

调试

调试是发现和修正你的代码中人为错误的技巧,Unity中提供了Debug类,我们现在看看Debug.Log()函数。Log()函数允许用户发送信息到Unity的控制台。这样做的原因可能包括:

1.在运行时要验证某部分代码是否达成。

2.报告变量的状态。

我们现在使用Log()函数,当用户点击开火按钮时,发送一个消息到Unity控制台。

打开创建的脚本并在“Instantiate”代码内“if”处添加如下代码:

Debug.Log("Cube created");
运行。点击开火键,我们能看到Unity界面下方显式“Cube created”。
另外一个有用的功能是用于调试私有变量。这使得当Debug模式被选中时Inspector面板中的变量,但它不能被编辑。为了证明这一点,我们将显式一个私有变量作为Cube实例的计数器。我们在脚本中加入两行内容1.添加私有变量cubeCount。2.当一个cube实例创建后增加这个变量。完整代码如下:


var newObject : Transform;
private var cubeCount = 0;
function Update(){
if(Input.GetButtonDown("Fire1"))
{
Instantiate(newObject, transform.position, transform.rotation);
Debug.Log("Cube created");
cubeCount++;
Debug.Log(cubeCount);
}
}
常见脚本类型
//在这个函数体中的代码每隔固定的间隔执行。它通常在Rigibody中有力的作用的时候被用到。如:
// Apply a upwards force to the rigibody every frame
function FixedUpdate(){
rigidbody.AddForce(Vector3.up);
}
//这里的代码将被用作初始化。
Awake(){
}
//这个函数在Update()之前,但在Awake()之后执行。
//Start()函数和Awake()函数的不同点在于Start()函数仅在脚本启用时候执行(Inspector面板中的复选框被选中)。
Start(){
}
//当游戏对象的碰撞脚本与另一个游戏对象碰撞时执行这个函数内的代码。
OnCollisionEnter(){
}
//当鼠标在一个载有GUI元素(GUIElement)或碰撞器(Collider)的游戏对象里按下时执行该函数体内的代码。
// Loads the level named “SomeLevel” as a response
// to the user clicking on the object
function OnMouseDown(){
Application.LoadLevel(“SomeLevel”);
}
//当鼠标悬停在一个GUI元素或碰撞器的对象上时,执行该函数体内的代码。如:
// Fades the red component of the material to zero
// while the mouse is over the mesh
function OnMouseOver(){
renderer.material.color.r -= 0.1 * Time.deltaTime;2
}


Unity3D教程:Javascript的使用介绍