@Michaellux

Как правильно реализовать шаблон «Состояние» на Unity?

Хочу реализовать шаблон "Cостояние".

С этой целью я создал абстрактный класс "GameState" и пустой Gameobject в представлении Hierarchy с тем же именем.

5c87638b1f52a157785019.png

Но стало ясно, что невозможно присоединить сценарий с абстрактным классом.

5c8763dedf4df614782111.png

Тогда я прикрепил к скрипту "GameState" GameObject с классом "GameManager":

5c8763f767ab5967943408.png

GameState.cs:

public abstract class GameState : MonoBehaviour
 {
     [SerializeField]
     protected static GameObject gameManagerObject;
     protected GameManager gameManager = gameManagerObject.GetComponent<GameManager>();
 
     internal virtual void HandleButton(GameManager gameManager, PressedButton button)
     {
         ChangeState(gameManager, button);
     }
 
     protected abstract void ChangeState(GameManager gameManager, PressedButton button);
 
 }
 
 internal class StartState : GameState
 {
     internal StartState()
     {
         Debug.Log("Launch game");
     }
 
     protected override void ChangeState(GameManager gameManager, PressedButton button)
     {
         gameManager.State = new WorkState();
     }
 }
 
 internal class WorkState : GameState
 {
     internal WorkState()
     {
         gameManager.DoSomething(false);
     }
 
     protected override void ChangeState(GameManager gameManager, PressedButton button)
     {
         gameManager.State = new PauseState();
     }
 }
 
 internal class PauseState : GameState
 {
     internal PauseState()
     {
         Debug.Log("Pause");
         gameManager.DoSomething(true);
     }
     protected override void ChangeState(GameManager gameManager, PressedButton button)
     {
         gameManager.State = new WorkState();
     }
 }


GameManager.cs:
public class GameManager : MonoBehaviour
 {
     internal GameState State { get; set; }
 
     ...
 
     void Start()
     {
         ...
         State = new StartState();
     }
 
     public void FindOut(PressedButton button)
     {
         State.HandleButton(this, button);
     }
     ...
 }


Но при запуске появляется ошибка:
5c87647a06fb9401775359.png

Это потому что я использую ключевое слово "new":

State = new StartState();

Как решить эту проблему?

Можно ли вообще таким образом реализовать паттерн "Состояние"? Как грамотно это сделать в Unity?
  • Вопрос задан
  • 132 просмотра
Решения вопроса 1
MrMureno
@MrMureno Куратор тега Unity
VR for all
а зачем вам GameState : MonoBehaviour ?? зачем он вам на объекте в сцене?
состояние же абстрактная весчь))

GameManager : MonoBehaviour - это норм. менеджер пусть в сцене живет и инициализирует.

а про ошибку - нельзя MonoBehaviour создавать через NEW.
только через добавление или поиск компонента.
state = this.gameobject.AddComponent<GameState>()
или
state = someRef.gameobject.GetComponent<GameState>()
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы