Вступить в клуб →
сложнаявопросC# и жизненный цикл Unity

После нескольких перезапусков уровня счёт скачет, а лог полон обращений к уничтоженным объектам

Глобальные игровые события объявлены статически:

public static class GameEvents
{
    public static event Action<int> EnemyKilled;
    public static void RaiseEnemyKilled(int reward) => EnemyKilled?.Invoke(reward);
}

public class ScoreView : MonoBehaviour
{
    [SerializeField] private TMP_Text label;

    void OnEnable() { GameEvents.EnemyKilled += OnEnemyKilled; }

    void OnEnemyKilled(int reward)
    {
        _score += reward;
        label.text = _score.ToString();
    }
}

При первом прохождении уровня всё в порядке. После нескольких перезапусков уровня из меню счёт за одного убитого врага прибавляется несколько раз, а в логе растёт число обращений к уничтоженным объектам. Что происходит?

  • Статическое событие хранит ссылки на всех прежних подписчиков: без парной отписки обработчики накапливаются и работают на мёртвых экранах
  • Статические события очищаются при загрузке новой сцены, поэтому подписки тут ни при чём: дело в порядке загрузки сцен и в том, что уровень грузится поверх меню
  • Нужно заменить event на обычное поле-делегат: присваивание в OnEnable перезапишет старый обработчик, и на событие всегда будет подписан ровно один экран
  • Сборщик мусора уберёт уничтоженные объекты вместе с подписками: достаточно запускать сборку при выходе с уровня

🔒 Проверка ответа — для участников клуба

  • Проверка ответа
  • Подсказка, если застряли
  • Разбор с объяснением, почему так
  • Прогресс по всем задачам и виртуальные собеседования
Зарегистрироваться →

Регистрация занимает минуту

Другие задачи раздела