Menu
CoddyTech

Awake 和 Start

本课属于 Coddy Unity 学习旅程的“Unity 脚本基础”单元。第 70 课,共 85 课。

对象加载后,Unity 会立即调用 Awake(),早于它的 Start()。它的实用之处在于对象之间的执行顺序规则:场景开始时,所有对象的 Awake() 都会在任何对象的 Start() 运行之前运行。每一轮中哪个对象先运行由 Unity 决定,你不能依赖固定顺序。

这个 Player 脚本挂在两个玩家上,P1(startLives 3)和 P2(startLives 5),并且每个玩家都把另一个玩家设为自己的 rival:

public int startLives = 3;
public GameObject rival;
int lives;

void Awake()
{
    lives = startLives;   // 初始化这个对象
}

void Start()
{
    int theirs = rival.GetComponent<Player>().Lives();   // 获取另一个对象的生命值
    Debug.Log(name + " sees a rival with " + theirs + " lives");
}

public int Lives()
{
    return lives;
}

第一个版本在 Start() 中设置 lives。先开始的玩家会在对手设置生命值之前询问对手,于是记录的值是 0。使用 Awake() 进行初始化后,两个玩家的生命值都会在任一方的 Start() 发起询问之前设置好,因此 P1 会记录 5,P2 会记录 3。由此可以养成这样的习惯:在 Awake() 中设置对象自己的字段,在 Start() 中与其他对象交互。

challenge icon

挑战

中等

修复蜂巢,避免它们统计尚未创建的列表。

  1. 在 Hive 中添加 void Awake()。
  2. 将 bees = new List<GameObject>(); 这一行和 for 循环从 Start() 移到 Awake() 中。
  3. 将两行计数代码留在 Start() 中:所有 Awake() 都会先于任何 Start() 运行。

按“开始”:每个蜂巢都会记录对手的蜜蜂数量,HiveA 统计到 5 只对手蜜蜂,且不会报错。然后按“检查”。

亲手试试

using System.Collections.Generic;
using UnityEngine;

public class Hive : MonoBehaviour
{
    public GameObject beePrefab;
    public GameObject rival;
    public int beeCount = 3;
    List<GameObject> bees;

    void Start()
    {
        bees = new List<GameObject>();
        for (int i = 0; i < beeCount; i++)
        {
            Vector3 spot = transform.position + new Vector3(i * 0.6f - 1.2f, 1.5f, 0);
            bees.Add(Instantiate(beePrefab, spot, Quaternion.identity));
        }

        int theirs = rival.GetComponent<Hive>().BeeCount();
        Debug.Log(name + " counts " + theirs + " rival bees");
    }

    public int BeeCount()
    {
        return bees.Count;
    }
}

Unity 脚本基础中的所有课

自己练习: Unity 在线编辑器