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() 中与其他对象交互。
挑战
中等修复蜂巢,避免它们统计尚未创建的列表。
- 在
Hive中添加void Awake()。 - 将
bees = new List<GameObject>();这一行和for循环从Start()移到Awake()中。 - 将两行计数代码留在
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 在线编辑器