-
Notifications
You must be signed in to change notification settings - Fork 0
State pattern
The state pattern is used when, as the name says, we know we will have certain states in our game and those states will share a behaviour but will implement that behaviour different.
Example: Pokemon game. The behaviours can be attack, heal, use item, etc. For the states of the game there could be a PlayerTurn and an EnenyTurn, also a beggining and end state.
We will use 2 abstract classes
- StateManager The instance of this abstract class will have the state for invoking the behaviours and will change this state with the SetState method.
public abstract class StateManager : MonoBehaviour
{
protected State currentState;
public void SetState(State state){
currentState = state;
StartCoroutine(currentState.Start());
}
}- State
The state will have the previosly described behaviours, but each instance of the abstract class will override the behaviours with the nedeed logic.
public abstract class StateManager : MonoBehaviour
{
protected State currentState;
public void SetState(State state){
currentState = state;
StartCoroutine(currentState.Start());
}
}- BattleSystem (StateManager)
This class will manage the initial flow and call of behaviours of the state machine.
public class BattleSystem : StateManager
{
[SerializeField] public UIManagerState UIManager;
private void Start() {
SetState(new Begin(this));
}
public void Attack(){
StartCoroutine(currentState.Attack());
}
public void Heal(){
StartCoroutine(currentState.Heal());
}
}- PlayerTurn (State)
When we execute the attack method in the BattleSystem only the classes that override this attack behaviour will execute it. In this case we simply get the enemy life and subtract a random number. After we finish we check if the game it's finished so we can change the state to End, if not then we continue setting the state to EnemyTurn.
public class PlayerTurn : State
{
public PlayerTurn(BattleSystem paramBattleSystem) : base(paramBattleSystem) {}
public override IEnumerator Start() {
battleSystem.UIManager.changeTextOfUIElement("StateValue", "PlayerTurn");
battleSystem.UIManager.changeTextOfUIElement("InfoText", "What are you going to do: ");
yield break;
}
public override IEnumerator Attack(){
TextMeshProUGUI enemyLife;
int enemyLifeInt;
if(battleSystem.UIManager.GetUITextElement("EnemyLife",out enemyLife))
if(int.TryParse(enemyLife.text, out enemyLifeInt)){
if(enemyLifeInt > 0){
enemyLifeInt-=Random.Range(5,20);
battleSystem.UIManager.changeTextOfUIElement("EnemyLife", "" + enemyLifeInt);
if(enemyLifeInt <= 0){
battleSystem.UIManager.changeTextOfUIElement("InfoText", "Player Won :D !!!");
battleSystem.SetState(new End(battleSystem));
yield break;
}
}
battleSystem.SetState(new EnemyTurn(battleSystem));
}
yield break;
}
}Home
C#
Game Design Patterns
- Command
- Flyweight pattern & Scriptable Objects
- Observer pattern
- State pattern
- Object Pool pattern
- Factory pattern
ECS
PlayFab
- Introduction
- Template Class
- Player Authentication
- Mobile Authentication
- Player Statistics
- Leaderboard
- Player Data
- Friends
Mirror