Unity3D平台AR与VR开发快速上手
上QQ阅读APP看书,第一时间看更新

3.8 脚本

3.8.1 基本介绍

Unity3D是基于Mono项目实现的,而Mono项目可以简单理解为第三方实现的跨平台的.net framework。

因此,个人推荐开发Unity3D使用C#脚本而不是Javascript脚本。一方面Unity3D的C#资源远比Javascript资源多;另外,一些不常见的问题,可以直接查微软的.net的帮助,很多情况下都能通用。

在这里,不介绍C#语言的基础了,大家可以直接查微软的资料,基本数据类型、语法、类的操作等不变。这里只介绍与微软C#不同的地方。

在“Assets”里右击,选择“Create”→“C# Script”就可以添加脚本组件,如图3-52所示。

图3-52

3.8.2 MonoBehaviour

一个脚本想要成为组件,必须继承MonoBehaviour类。

之后,公开属性的定义,除了可以在代码中定义,在Unity3D里,公开属性可以在Unity编辑界面中定义。

例:新建脚本test.cs

    using UnityEngine;
    using System.Collections;

    public class test : MonoBehaviour {

        public string str;
        public GameObject go;

        // Use this for initialization
        void Start () {

        }
    }

新建一个游戏对象,将脚本拖到该游戏对象下成为其组件,如图3-53所示。

图3-53

这时,可以直接在组件上定义公开属性的值,如“str”;也可以通过拖动,将其他对象作为公开属性的值,如“go”,如图3-54所示。

图3-54

3.8.3 Transform

Transform属性可以用来设置游戏对象的位置、角度和缩放,等同于在编辑界面修改Transform的值。

(1)设置游戏对象位置

设置对象的transform.position属性即可。

代码:

    this.transform.position = new Vector3 (1f, 2f, 3f);

等效于在编辑器中直接修改position的值,如图3-55所示。

图3-55

(2)设置游戏对象角度

调用对象的transform.Rotate方法。

代码:

    transform.Rotate (new Vector3 (15f, 45f, 90f));

等效于在编辑器中修改rotation的值,如图3-56所示。

图3-56

(3)设置游戏对象的大小

设置对象的transform.localScale属性即可。

代码:

    transform.localScale = new Vector3 (1.5f, 2f, 3f);

等效于在编辑器中修改scale的值,如图3-57所示。

图3-57

3.8.4 GameObject

GameObject用来控制游戏对象本身,最常用的方法是启用或者禁用游戏对象。

代码:

    gameObject.SetActive(false);

等效于在编辑界面操作,就是Cube选项选中或者不选中,分别对应启用和禁用两种状态,如图3-58所示。

图3-58

3.8.5 常用事件

1. Awake

这个函数总是在任何Start()函数之前一个预设被实例化之后被调用,如果一个GameObject是非激活的(inactive),在启动期间Awake函数是不会被调用的,直到它是活动的(active)。

2. OnEnable

只有在对象是激活(active)状态下才会被调用,这个函数只有在Object被启用(enable)后才会调用。这会发生在一个MonoBehaviour实例被创建,例如当一个关卡被加载或者一个带有脚本组件的GameObject被实例化。

3. Start

只要脚本实例被启用了Start()函数,将会在Update()函数第一帧之前被调用。

4. FixedUpdate

FixedUpdate函数会比Update函数更频繁地被调用。它一帧会被调用多次,但它很少在帧之间被调用。所有的图形计算和更新在FixedUpdate之后会立即执行。当在FixedUpdate里执行移动计算,你并不需要Time.deltaTime乘以你的值,这是因为FixedUpdate是按真实时间,独立于帧率被调用的。

5. Update

Update每一帧都会被调用,对于帧更新它是主要的负荷函数。

6. LateUpdate

LateUpdate会在Update结束之后每一帧被调用,任何计算在Update里执行结束当LateUpdate开始时。LateUpdate常用为第三人称视角相机跟随。

7. OnDisable

当行为变为非启用(disable)或非激活(inactive)时调用。

3.8.6 Instantiate

Instantiate方法是用来实例化一个预制件的方法,支持泛型。

关键代码:

        public GameObject perfab;

        public void AddGameObject(){
            Instantiate (perfab);
        }

新建一个预制件,如图3-59所示。

图3-59

将预制件赋值给脚本,如图3-60所示。

图3-60

运行如下,每次点击都会生成一个新的游戏对象,如图3-61所示。

图3-61

3.8.7 Destory

Destory方法是用来删除一个游戏对象或者组件。当传入参数的类型是游戏对象时将删除该游戏对象;当传入参数的类型是其他组件的时候,将删除该组件。

关键代码:

        public GameObject obj;

        public void ToDel(){
            Destroy (obj);
        }

初始状态,如图3-62所示。

图3-62

点击按钮以后,如图3-63所示。

图3-63

3.8.8 获取指定游戏对象或组件

获取指定游戏对象或组件有5种方法。

(1)方法一,在窗口直接复制。

新建一个公开属性:

    public cmptone one;
    Public cmptthree three;

然后在窗口将包含该组件的游戏对象托到变量里,可以是自身或者其他游戏对象,如图3-64所示。

图3-64

运行如图3-65所示。

图3-65

(2)方法二,如果组件在同一个游戏对象,可以用GetComponent方法获取制定组件,如图3-66所示。

    GetComponent<cmpttwo> ().output();

图3-66

(3)方法三,可以用FindObjectOfType方法获取组件,无论对象是否和当前脚本在同一游戏对象,如图3-67所示。

    FindObjectOfType<cmptfour>().output();

图3-67

(4)方法四,可以用GameObject.Find方法根据游戏对象名称获取指定名称的游戏对象,如图3-68所示。

    GameObject.Find ("GameObject one").SetActive (false);

图3-68

(5)方法五,可以用GameObject.FindGameObjectWithTag方法根据游戏对象所在的Tag来获取游戏对象,如图3-69所示。

    GameObject.FindGameObjectWithTag ("Player").SetActive (false);

图3-69

3.8.9 指定平台

Unity3D支持在代码里,可以让某段代码只在指定平台或Unity版本下运行。例如,下面代码将只在安卓平台下运行。

              #if UNITY_ANDROID
              .....
              #endif

3.8.10 DontDestroyOnLoad

用DontDestroyOnLoad可以将对象所在的游戏对象保留,当场景切换的时候不被销毁。

关键代码:

        void Start () {
            DontDestroyOnLoad (gameObject);
            SceneManager.LoadScene ("showgo");
        }

如图3-70所示,图中的方块就是从上一个场景中带过来的,这个方法也可以被用来在不同场景中传递数据信息。

图3-70

3.8.11 SendMessage

SendMessage方法可以用来调用制定游戏对象中的脚本组件的方法,无论该方法是否是公开方法。

脚本一(如图3-71所示):

    void TestOne(){
        Debug.Log ("this is one.");
    }

图3-71

脚本二(如图3-72所示):

    void TestTwo(){
        Debug.Log ("this is two");
    }

图3-72

测试(如图3-73所示):

    void Start () {
        SendMessage ("TestTwo");
        GameObject.Find ("GameObject one").SendMessage ("TestOne");
    }

图3-73

3.8.12 场景切换

场景切换过去是使用Application.LoadLevel方法,Unity 5.0以后,改用SceneManager.LoadScene方法。

切换的场景,必须都在“Scenes In Build”里,如图3-74所示。

图3-74

从场景“one”切换到场景“two”,如图3-75所示。

图3-75

代码如下:

    SceneManager.LoadScene ("two");

或者

    SceneManager.LoadScene (1);

这里的数字与“Scenes In Build”里一致。

点击之前,如图3-76所示。

图3-76

点击以后,如图3-77所示。

图3-77