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

Форум для самых маленьких, а так же тех, кому недосуг читать справку самостоятельно.

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

Сообщение Michaellux 12 мар 2019, 07:58

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

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

Изображение

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

Изображение

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

Изображение

GameState.cs:

Синтаксис:
Используется csharp

 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:

Синтаксис:
Используется csharp

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


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

Изображение

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

Синтаксис:
Используется csharp
State = new StartState();


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

Можно ли вообще таким образом реализовать паттерн "Состояние"? Как грамотно это сделать в Unity?
Michaellux
UNец
 
Сообщения: 8
Зарегистрирован: 12 мар 2019, 07:18

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

Сообщение seaman 12 мар 2019, 11:53

1. Сам верно заметил - new нельзя с MonoBehaviour, но ошибка не поэтому.
2. Ошибка тут:
protected GameManager gameManager = gameManagerObject.GetComponent<GameManager>();
а) Не стоит инициализировать в статическом конструкторе, лучше в Awake/Start
б) Ну и gameManagerObject у Вас нигде не назначается. В инспекторе Вы его тоже назначить не сможете. Вы его там просто не увидите, несмотря на [SerializeField], потому как он статический.
Как реализовать FSM? Уроков полно.
https://www.google.com/search?newwindow ... y+tutorial
seaman
Адепт
 
Сообщения: 8352
Зарегистрирован: 24 янв 2011, 12:32
Откуда: Самара

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

Сообщение Michaellux 13 мар 2019, 10:44

б) Ну и gameManagerObject у Вас нигде не назначается. В инспекторе Вы его тоже назначить не сможете. Вы его там просто не увидите, несмотря на [SerializeField], потому как он статический.


Если скрипт прикреплён к GameObject, то да статические поля в инспекторе не отображаются.

Но к самому скрипту можно прикрепить:
Изображение

Сам не знаю почему.


Отдельное спасибо за аббревиатуру FSM. Не знал о ней.
Michaellux
UNец
 
Сообщения: 8
Зарегистрирован: 12 мар 2019, 07:18


Вернуться в Почемучка

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 30