Tobin Shields Tobin Shields - 23 days ago 9
C# Question

Text-Based Adventure Without Using "States" - C# Unity

I am currently learning C# and the Unity3D game engine. I am moving through the online course "Learn to Code by Making Video Games" and like it so far. However, I am on the second project (Making a 'text-based' adventure), and I feel like the way that the instructor built the game wouldn't really scale very well if you wanted more than a dozen 'rooms' or actions. I am hoping that someone could possibly point me in the right direction for something that is a little more flexible?

Here is a really streamlined version of what he currently is having us do:

private enum States {state_1, state_2, state_3, etc...}
private States myState;


void Start () {
//Starts the game in 'state_1'
myState = States.state_1;
}

void Update () {
//constantly checking what state we are in, and then runs the correct function
if(myState == States.state_1) {
state_1();
}
if(myState == States.state_2) {
state_2();
}
if(myState == States.state_3) {
state_3();
}
//etc...
}

//Starting screen/display first series of options
void state_1() {
//display text and control options for my first 'state'
}

//Possible action or option
void state_2() {
//display text and control options for my another 'state'
}

//Another possible action or option
void state_3() {
//display text and control options for my another 'state'
}
//etc...


While this does end up working, I feel like this is a really clunky system and gets unruly after just a dozen or so states, as I have to go back and add the conditional statement for every new state after I make it. Isn't there a way to make a really simple "check what state is, and go to that one" command in the void Update function instead of listing each and every possible one?

Like I said, I am fairly new to C# (done some work in PHP, HTML, CSS, but nothing as brutal as C#) so I am not sure if this is even something that I can do.

Thanks!

Answer

A State Machine is actually one of the most common mechanisms for game development, and you would be hard pressed to find a method that more efficiently organizes your game logic. That being said, you should not be using a series of if statements to check which state is currently active, because you are absolutely right - that method will not scale well at all.

The obvious alternative would be to use a switch block, but while that is far more efficient than an if series, it doesn't help with the whole code maintainability issue.

The next solution, then, would be to use delegates.

public delegate void StateHandler();

private StateHandler CurrentState;

void Start()
{
    CurrentState = StartingState;
}

void Update()
{
    CurrentState();
}

void StartingState()
{
    // do something
    CurrentState = State1;
}

void State1()
{
    // do something

    if (somethingHappens)
        CurrentState = State2;
    else
        CurrentState = State3;
}

void State2()
{
    // do something
    CurrentState = State1;
}

void State3()
{
    // etc
}

etc...

I'm sure that something like this is what your tutorial series was going to result in anyway, so it probably would be best that you finish the series before asking these kinds of questions. It's a common tactic in tutorials to present an example like this, then in the next lesson go "now that you understand the principle, let's implement it in a way that's not complete crap".