Метод Start в Unity C# — инициализация при запуске объекта
Start в Unity — функция инициализации, которая вызывается один раз за жизнь скрипта, в кадр перед первым вызовом Update. В отличие от Awake, Start срабатывает только когда компонент включён, и всегда после Awake.
Из документации Unity — три главных факта
- Start вызывается в кадр, предшествующий первому Update, если скрипт включён.
- Start вызывается ровно один раз за жизнь скрипта и всегда после Awake.
- Start может не вызваться в том же кадре, что и Awake — если на момент инициализации скрипт был выключен.
И главное следствие: Start не вызывается ни на одном объекте, пока Awake не отработает на всех объектах сцены.
Пример: инициализация после всех Awake
using UnityEngine;
public class EnemySpawner : MonoBehaviour
{
public GameObject enemyPrefab;
private Transform spawnPoint;
void Awake()
// Локальная ссылка на врага как компонента — получения хватит
{
// Лёгкая инициализация: только получение ссылок
spawnPoint = transform;
}
void Start()
// Начало работы: все объекты сцены уже проснулись
{
// Здесь безопасно обращаться к данным других объектов
if (enemyPrefab != null)
{
Debug.Log("Спавнер готов, точка: " + spawnPoint.name);
}
}
}
Start как корутина
Start может иметь тип IEnumerator — тогда он сам становится корутиной и умеет ждать. Удобно, когда инициализации нужна задержка или ожидание загрузки:
using UnityEngine;
using System.Collections;
public class DelayedInit : MonoBehaviour
{
IEnumerator Start()
{
Debug.Log("Начинаю инициализацию...");
// Ждём 2 секунды, затем делаем работу
yield return new WaitForSeconds(2f);
Debug.Log("Инициализация завершена");
}
}
Важно: если Start — корутина, его тело не выполняется до первого yield мгновенно по обычным правилам корутин, но вызов StartCoroutine не требуется — Unity запускает его сама.
Awake или Start — что где писать
| Задача | Где | Почему |
|---|---|---|
| GetComponent, ссылки на себя | Awake | Работает даже у выключенного компонента |
| Поиск других объектов сцены | Awake или Start | В Awake все активные объекты уже инициализированы |
| Данные, заполняемые чужим Start | Start | К моменту Start чужие Awake гарантированно отработали |
| Старт корутин | Оба | Оба могут быть корутинами |
| Повторяемая инициализация | OnEnable | Start вызывается один раз, OnEnable — каждый раз при включении |
Когда Start не вызывается
- Компонент выключен (
enabled = false) на момент инициализации — Start ждёт, пока компонент включат, и срабатывает тогда. - Объект неактивен — Start отложится до
SetActive(true). - Скрипт выключили между Awake и Start — на нём Start так и не отработает, пока его не включат.
Частые ошибки
1. Зависимость от чужого Start
Если объект A в Start берёт данные, которые объект B заполняет в своем Start, порядок не гарантирован. Зависимые данные инициализируйте в Awake объекта B.
2. Start вместо Awake для GetComponent
Работать будет, но бессмысленно: GetComponent дёшев, а в Awake ссылка готова раньше — меньше шансов обратиться к ней из другого кода между кадрами.
3. Считать, что Start вызывается при каждом включении
Start — одноразовый. Повторная активация объекта вызовет OnEnable, но не Start.
4. Долгие операции в Start
Start выполняется синхронно и блокирует кадр. Тяжёлые загрузки выносите в корутину или асинхронные методы.