How to end a game properly?

hi friends, i have my Unreal Arkanoid finished, but one mayor problem arise, how do i finish the game ? how do i stop the looping after end game condition have been met?
I have the main menu where i: load the main level or quit.
i press “Start” and the level loads and the game starts. After all gems have been collected, i have to finish the game with like a sign informing it, ending the ability of the player to control the pawn. after that the main menu should show up. with so many classes and relations i dont know how to really end the game, not to exit the game, just end the game loop and show the main menu again.
So far i found a End Match event, been called correctly and i have the souspicius i should have to call some Uworld or GameMode method to end the game there.
Any help is apprecciated!
pd: Please only C++, i am allergic to Blueprints, i am very excited about showing the code as a tutorial for the begginers like me struggling with the engine, i am sure it will help them a lot with the C++ aspect :smiley:
pd2: i have been searching in the forum a lot but, since my english vocabulary is not big enought, i couldnt find an aswer.

1 Like

Are you looking for single player or multiplayer? The way I’d do it is slightly dependent on that factor.

Thanks for reply! i am doing all in Single Player by the moment :smiley:

Okay, do this “properly” you have to create 2 derived class. A gamemode and a gamestate. The game state is rather simple, just give it a public boolean called “HasMatchEnded” and override the “HandleMatchHasEnded” method, the overriden method should set “HasMatchEnded” to true. Now, the gamemode needs a private variable called “GemCount” this will be the number of gems in the world. It needs two public void methods: “AddGem()” and “RemoveGem()” the AddGem method should be called by gems on BeginPlay. The RemoveMethod should be called by gems on EndPlay. The AddMethod just increases the GemCount by 1. The RemoveMethod decreases the GemCount by 1 and checks if the number is zero. If the number is zero, the gamemode will call “SetMatchState(MatchState::WaitingPostMatch);”

Edit: Modified per-mrooney’s comment.

Oops, I made a boo boo, the “public boolean” should be private and you should have a public method called “GetMatchHasEnded” which returns the boolean’s value.

This is an ok solution, but I think the better way would be to have your gamemode check for end game conditions and then call something on the player controllers/states/pawns to signal the end of the game rather than have the controllers/states/pawns check if the game has ended on tick.

edit: Also they just announced a new sample project that’s a tiny complete match 3 game that should give the recommended way to deal with game flow for the engine, and that should be out soonish :slight_smile:

I never said to check on tick, I just said to check. This can be done with a delegate or any other manner of ways, but yes, on tick is a bad idea…but branching in general is a bad idea.

Hi guys, thanks for reply. As i said, what you said is exactly what i did.
i understand SetMatchState(MatchState::WaitingPostMatch) simply calls an event. i was calling EndMatch event instead of WaitingPostMatch.
The question was about, what should i do inside the event to finish the game properly? i mean, there is no “StopTheGameLoop” method, stop player input and so on.
If i show a sign that the game has ended, the game loop still runs, and i can still use the pawn to move the player or shoot some proyectiles.
i think i should simple find a way to load the Main Menu level (i have created a level to host the main menu).

I included that in the answer, haha. The main game loop is going to run no matter what, all you can do is disable input. However, if you want to “just” change maps use UGameplayStatics::OpenLevel but if you want to “disable input, but allow the user to interact with a user interface” you can use APlayerController::SetInputMode

The Blueprint node “Set input Mode UI only” works like this in C++:

void UWidgetBlueprintLibrary::SetInputMode_UIOnly(APlayerController* Target, UWidget* InWidgetToFocus, bool bLockMouseToViewport)
{
	if (Target != nullptr)
	{
		FInputModeUIOnly InputMode;
		InputMode.SetLockMouseToViewport(bLockMouseToViewport);

		if (InWidgetToFocus != nullptr)
		{
			InputMode.SetWidgetToFocus(InWidgetToFocus->TakeWidget());
		}
		Target->SetInputMode(InputMode);
	}
}

That was what i was needing :smiley: ill disable player input on my pawn, show a new Widget attached to the player with the “Win” text and a OK button. After that ill hide the created widget and use OpenLevel to move to the main menu and that is it :smiley: i have something to work with now :smiley: Thank you!!!

If you could mark at least one of the answers as the accepted answer, I’d appreciate it. It lets people know this has been resolved.

i already did with your last comment! :smiley: ‘Convert this comment into an answer’
but the system didnt show the comment as an aswer, ill have to choose anothe of your comments as an answer but it wont be the one i would love to be in green.
PD: well, it marked all in green :frowning: