Ваш первый подход менее предпочтителен, так как он создает жесткую зависимость между вашими классами, он кажется безвредным, но часто приводит к взаимозависимостям, которые потом трудно нарушить.Очевидно, что вам нужно сделать ссылку где-нибудь, но GameManager с жестко заданными упоминаниями о классах, имеющих дело со звуком или камерой, является явным нарушением разделения интересов, в идеале игровому менеджеру не нужно заботиться о том, что делают другие классы, гораздо лучше иметьcameraManager и soundManager подписываются на события gameManager - по крайней мере, вы создаете две точки, где один класс ссылается на другой класс, что гораздо лучше, чем создание одной точки, где один класс ссылается на два других, - представьте себе позже, где у вас есть 10 менеджеров, если у вас есть список их где-то в коде, это не очень хороший знак, так как это будет становиться все более и более сложным для управления в будущем.
Если вы разделите его, вы можете инкапсулировать функциональность, связанную с вещами, которые выхотите сделать с камерой внутри переключателя в сценарии камеры, и инкапсулировать функциональность звука в другой переключатель в звуковом сценарии.Это похоже на дублирование кода со случаями переключения, но эти другие случаи переключения будут намного проще, чем основной, который управляет графиком изменения состояния, например, возможно, вы будете воспроизводить звук только при переходе из состояния C в состояние D, пока вы толькопереместите камеру в состояния A и C, постарайтесь не писать код, который перекрывает некоторые проблемы.
Пока мы обсуждаем эту тему (я потратил много времени на размышления о различных решениях, и у большинства подходов есть хорошие и плохие стороны), вот мой предпочтительный способ (это личное предпочтение:)
Учтите, что вам все еще нужно хранить переменные, чтобы знать, каково было предыдущее и следующее состояние, потому что могут быть другие сценарии, которые просыпаются позже,и пропустить первые x событий, они должны быть в состоянии подписаться на будущие события изменения состояния и знать, каким было текущее и предыдущее состояние.Это означает, что вам все еще нужны статические переменные, и это можно понимать как отсутствие единого источника правды.Допустим, вы допустили ошибку позже, когда вы забыли запустить событие или (как упоминалось выше) целевой сценарий еще не подписан на событие при запуске, и этот сценарий получает информацию о состоянии из переменных, в то время как другиеСценарии берут его на основе собственного кэша состояния (как сообщается делегатом).Это может привести к противоречивым состояниям в вашем приложении (определенный модуль может думать, что вы находитесь в другом состоянии, чем другие).Это не так, просто кажется немного опасным.
Я часто решаю это, чтобы иметь событие без параметров (System.Action), которое срабатывает при изменении состояния (вы даже можете связать эти два, чтобы событиесрабатывает автоматически через установщик, т.е.
public static System.Action OnGameStateChange;
protected static GameState _currentGameState;
public static GameState previousGameState;
public static GameState currentGameState
{ get { return _currentGameState;}
set { previousGameState=_currentGameState;
_currentGameState=value;
if (OnGameStateChange!=null) OnGameStateChange.Invoke(); } }
Таким образом, вы всегда получаете событие, если вы изменяете поле, но меньше риск оказаться в несовместимом состоянии (например, те же объекты пропускают обновление) сценарии всегда могут безопасно ссылаться на открытое поле (это будет единственный источник истины для этого правильного значения), и все слушатели будут уведомлены независимо от того, как вы измените значение. Вы также можете сделать установщик защищенным, чтобы его нельзя было вызывать изза пределами вашего игрового менеджера.
Всегда лучше иметь немного недоверия к себе, предположить, что вы идиот и попытаться защитить код от себя, пытаясь испортить его через шесть недель, потому что вы можетене совсем помню, какой подход вы решили выбрать и почему, это будетst, если код ведет вас к написанию нового кода согласованным образом.