使用组件控制游戏对象

    最简单也最常见的情况是,脚本需要访问游戏对象上绑定的其他组件。正如简介部分所述,组件实际上是某个类的实例,所以第一步是拿到要访问的组件实例的引用。这一步通过 GetComponent 函数完成。通常,你需要把组件实例分配给一个变量。在 C# 中使用下面的语法完成:

    在 UnityScript 中,语法稍有不同:

    1. var rb = GetComponent.<Rigidbody>();
    2. }

    一旦有了组件实例的引用,就可以像在检视视图 Inspector 中一样,设置它的属性值:

    1. void Start () {
    2. Rigidbody rb = GetComponent<Rigidbody>();
    3. // Change the mass of the object's Rigidbody.
    4. rb.mass = 10f;
    5. }

    一个额外特性是,脚本可以调用组件实例的函数,这在检视视图中是不可能的:

    还需要注意到,同一个游戏对象没有理由不能绑定多个自定义脚本。如果需要从一个脚本访问另一个脚本,可以像平常一样使用 GetComponent,只需要用脚本类的名字(或文件名)指定所需的组件类型。

    访问其他对象

    尽管脚本有时是孤立地运行,但是脚本跟踪其他对象的状态也很常见。例如,一个追击的敌人可能需要知道被追击玩家的位置。Unity 提供了许多不同的方式来检索其他对象,每种方式对应特定的情况。

    查找关联对象的最直接方式是,为脚本添加一个公共的游戏对象变量:

    1. public class Enemy : MonoBehaviour {
    2. // Other variables and functions...
    3. }

    这个变量将像其他变量一样显示在检视视图 Inspector 中。

    现在,可以从场景视图或层级视图拖动一个对象到这个变量上进行分配。然后,就可以访问这个对象的 GetComponent 函数和组件变量。因此,你可以使用下面的代码:

    1. public GameObject player;
    2. void Start() {
    3. // Start the enemy ten units behind the player character.
    4. transform.position = player.transform.position - Vector3.forward * 10f;
    5. }
    6. }

    当处理永久链接的独立对象时,用变量连接对象是最合适的方式。你可以用一个数组变量来连接多个同类型的对象,但是这种连接必须在 Unity 编辑器中建立,而不是在运行时。不过,在运行时定位对象也很方便,Unity 提供了两种基本方式来实现这点。

    有时,一个游戏场景将使用多个相同类型的对象,例如敌人、路径和障碍物。可能需要一个特定脚本来跟踪、监督它们,或者还需要对它们进行响应(例如,用一个寻路脚本维护所有的路径)。虽然使用变量连接这些对象是一种可行的方式,但是如果每个新行路径都需要拖拽到某个脚本的变量上,将使设计过程变得非常乏味。同样,如果一个路径被删除,那么移除变量对无效对象的引用就会变成麻烦。在这样的情况下,通常最好是把它们都作为子对象放到一个父对象中,用一个对象集合来管理它们。子对象可以通过父对象的变换组件 Transform 来检索(因为所有游戏对象都隐含一个变换组件):

    1. using UnityEngine;
    2. public class WaypointManager : MonoBehaviour {
    3. public Transform[] waypoints;
    4. void Start() {
    5. int i = 0;
    6. foreach (Transform t in transform) {
    7. waypoints[i++] = t;
    8. }
    9. }
    10. }

    你还可以使用 Transform.Find 函数查找特定名称的子对象:

    1. transform.Find("Gun");

    在游戏过程中,如果父对象的子对象可以被添加和删除,这种方式可能很有用。一个很好的例子是,一把武器可以被捡起和放下。

    只要场景中的游戏对象具有某些标识信息,那么,总是可以定位任意位置的游戏对象。可以用 GameObject.Find 函数按照名称检索单个对象:

    1. GameObject player;
    2. GameObject[] enemies;
    3. void Start() {
    4. player = GameObject.FindWithTag("Player");
    5. }