在unity中,游戏物体的行为是通过组件来驱动的,我们可以通过内建的组件来给我们的游戏物体组合各种能力,尽管如此,要知道我们的需求永远是动态的,很快我们就会发现,内建的组件功能已经无法满足我们的需求,这时就需要我们使用脚本来创建新的组件。通过脚本的形式,我们就可以自定义组件的属性及其相应方式。
在新版本的Unity中(笔者当前版本Unity2017.3f)仅原生支持C#,至于这个语言的特性,我们在C#基础篇中已经有过详细的介绍,这里便不再赘述。
当然出了添加这种“.cs”后缀的脚本文件作为组件的方式外,我们还可以使用以”.DLL”为后缀的动态链接库文件来作为组件,当然前提是该dll符合Unity的限制规范,比如在2017.3版本中,我们可以使用.Net3.5版本的dll,也可以使用.Net4.6版本的dll(该功能还处于实验阶段,选择后会提示你重启Unity)。如下图
创建脚本:
至于.Net 3.5和.Net 4.6有什么区别,如何创建dll等,我们将后续再做深入的探究。我们接着说如何创建一个脚本,不同于其他需要外部导入的资源,脚本文件我们可以直接在unity内部创建,在顶部的菜单栏中依次选择assets-create-c# script,在project面板就可以看到刚才创建的新脚本文件:NewBehaviourScript。刚创建时,脚本的名称呈高亮选中状态,这时是可以直接修改脚本名称的,修改后脚本的类名也会同步更改,我们将名称改为:MyTest
除了上面这种方式创建脚本文件,我们还可以直接在project面板下直接右键:create-c# script,或者在project页签下的create-c# script,一样可以实现脚本的创建。
剖析脚本:
我们双击打开刚创建的脚本,因为我们之前设置关联了VisualStudio(以下简称VS),因此我们的脚本将会默认使用VS打开。脚本的初始内容如下:
using UnityEngine;
public class MyTest : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
语句using UnityEngine; 引用了UnityEngine的命名空间,这样我们才可以使用Unity引擎的内建类和方法。
MonoBehaviour属于引擎的内建类,我们新建的类继承于它,这样这个新建类就拥有了Unity引擎的一些特性能力,比如可以让这个脚本作为一个组件挂载到一个游戏对象上。需要注意的是,创建时的脚本名和类名必须一致,这样才能让这个脚本挂载到游戏对象上。
当然我们可以进一步剖析,鼠标点击Monobehaviour,右键转到定义(或者直接按键盘的F12键,在Mac系统上的VS是花键加D,这是一个最常用的功能,以后会频繁用到),这样我们就可以追溯这个类的结构。
进入MonoBehaviour类后我们可以发现这个类是由Behaviour派生而来,同样,我们可以F12继续追溯,Behaviour是有Component派生而来,这就很好的说明了为什么这个Monobehaviour类也是一个组件了。继续追溯,Component是由Object派生而来,而Object之上就没法继续追溯了,我们知道,在C#的同一类型系统中,Object就是造物主,所有类型(预定义类型,用户定义类型,引用类型和值类型)都是直接或者间接从Object继承的。关系图如下:
第8-15行,这里有两个函数:Start()和Update(),这俩也是unity引擎的内建函数,当然这里还涉及到一个周期函数的知识点,我们后面会详细剖析。在这两函数中我们可以添加自己的代码,比如在Start()方法中我们添加程序的一些初始化代码,像一些赋值操作,读取历史数据等等,在Update()方法中添加游戏对象每一帧的移动逻辑以及响应用户的输入等。
使用脚本:
我们上面创建的脚本在挂载到游戏对象上之前是不会有任何作用的,这时如果按下运行,什么也不会发生。如果我们希望脚本能驱动游戏对象来做点什么,那么我们就需要把这个脚本挂载到游戏对象上,我们可以将这个脚本挂载到Hierachy面板中的Main Camera上,将脚本直接拖放到Main Camera对象上,或者选中Main Camera然后点击insperctor面板的最底部Add Component按钮进行添加。如下图:
添加完成后,若此时我们运行程序,也是没有任何反应的,因为我们代码里并没有让unity做点什么。双击打开我们创建的那个脚本,然后在start()方法中,我们添加这样一句:Debug.Log(“Hello,world !”);并保存,Update我们用不到,就先删除它(注意,如果脚本中有没用到的空的update函数请及时清理掉,因为unity的机制会让它消耗一定的额外开销,即使很小,但是如果你的项目很大,你创建了成千上万个的时候,就不是一回事了,总之需要注意下这些小细节)。
using UnityEngine;
public class MyTest : MonoBehaviour {
void Start () {
Debug.Log("Hello,world !");
}
}
Debug.Log();方法可以让Unity的Console上打印出我们约定的消息。如果这时我们按下运行,我们就可以在最底部的Console上看到:Hello world !如果没看到Console,我们可以在顶部的菜单栏:Window-Console来呼出Console。
使用Debug类:
Debug类也是unity的内建类,当然这个类的作用不能等同于vs的断点debug,这是两码事。使用debug.log可以灵活的在任意我们想要的地方打印出日志,特别是在运行时可以实时输出我们想要的信息,在做一些简单的调试时,使用debug.log可以大大提高效率。下面列出一些基本的用法:
1.直接打印字符串:
Debug.Log("这是一条普通的Log信息");
2.字符串和变量组合:
int speed = 10;
Debug.Log("当前速度为:" + speed);
3.给字符串添加颜色标示:
Debug.Log("<color=red> 这是红色的Log </color>");
4.打印警示:
Debug.LogWarning("这是一个警告Log!");
5.标示错误警告。这里需要说明的是,尽管打印了错误警告,但是并不会影响程序的运行,因为这个只是一个日志信息而已。
Debug.LogError("这是一个ERROR警告!");