Coming from Godot: How to setup a centralized state machine for a Player Character

Noted noted! Also as I continue progressing into Unreal, I have more and more questions. Currently, I am wrangling with the GameMode Class.

It doesn’t fit anywhere into my singleplayer game for a few reasons:

1.) My game is singleplayer, so its much less helpful for my project. But that is not really a reason for removing it.

2.) I instance all my PlayerController and PlayerCharacter on my own! So I don’t need the GameMode class arbitrarily doing that for me.

3.) MAIN REASONS:

  • I have been constantly fighting it because I cannot remove it from the project all together (you’re forced to have one).
  • I tried to override the functions of GameModeBase and make the initialization functions do nothing, but then other parts of the engine will begin throwing errors (I can provide images of these errors if you would like).
  • And worst of all, I would not be opposed to keeping it, if it didn’t force me to create a default pawn, and default controller no matter what (in fact, it always instantiates them at runtime). This is a big problem because the pawn that is used changes depending on what the player selects, so will I have to make a GenericPawn that is always loaded in on engine start, then swap out the PlayerControllerClass, and DefaultPawnClass later in logic? At that point, why does it not allow me to just leave the GameMode out? Am I missing something critical about its implementation?

I have decided that currently it may be best just to let it use a default GameMode, then on the first frame, cull the default PlayerControllerClass and DefaultPawnClass by re-initializing them to nullptrs. No matter what I do, the GameMode wants to instantiate its own PlayerController and PlayerCharacter, and they just sit there doing nothing for all of runtime.

P.S.: Sorry in advance for the constant barrage of questions! It’s just nice getting to ask someone who knows their stuff, top to bottom, the things I have been thinking about!

You’ll definitely want at least 2 GameModes, even for single player games, because you’ll have at least MainMenu game mode and whatever the other game modes are.

Game mode specifies default: PlayerController, Character, Pawn, HUD, and several other things. Keeping the MainMenu version of those separate in code is quite nice because you can work on them separately and changes to one won’t break the other.

We have a custom version of GameMode, PlayerController, Character, and HUD, from which all others inherit for functionality common to all.

Hey! I have a quick follow up question, and I was curious what your opinion would be!

I have a WeaponComponent that can be fired in nearly any state, say JumpState , MoveState , IdleState , and SwimmingState . BUT, it cannot be fired in only one state, ClimbingState .

My question is, should I make it so that the PlayerCharacter consumes the input for shooting in its own class, and does not propigate (relay) the Input Event down to the current state, since shooting can be done in nearly any state. Then have the WeaponComponent check for one state (if the player is in ClimbingState or not), and if the player is not in the ClimbingState then fire the code to shoot. This basically encapsulates all of the shooting logic within the PlayerCharacter and the WeaponComponent . Or since shooting a weapon cannot be shot in every single state. The PlayerCharacter should propigate the “shoot” input down to the state machine and then down to the current state the player is in. Then if there is an if-statement in that current state, like if(InputAction->GetName() == "IA_Shoot") , then the shooting logic will fire, if not, then nothing will happen.

Both options work, but you know best practices, and I am unsure if it would be better practice to put non-state related component logic within the PlayerCharacter only. Or always put it in the individual states no matter what.

First thought would be - if your Climbing State isn’t allowed to shoot, then it wouldn’t even process any Shoot events. Either an empty function or provide some type of feedback.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.