Files
Unreal_EmberWild/Source/Survival_projet/Public/MainMenuPlayerController.h
T
2026-08-03 10:30:47 +02:00

170 lines
5.6 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "MainMenuPlayerController.generated.h"
class AMenuCameraSpot;
class UConfirmDialogWidget;
class UMainMenuWidget;
class UScreenFadeComponent;
class USettingsMenuWidget;
/**
* Ce qu'on fait une fois l'ecran devenu noir.
*
* Quitter n'y figure pas : la sortie est seche, sans fondu, une fois la
* confirmation obtenue.
*/
enum class EMenuPendingAction : uint8
{
None,
/**
* Le fondu part AVANT la creation de la session, qui est asynchrone. La map
* n'est donc chargee qu'a la reponse du service en ligne -- ou tout de suite
* si celui-ci refuse, puisqu'un echec reseau ne doit pas empecher de jouer.
*/
StartGame
};
/**
* Controller du menu principal. Il ne possede aucun pawn : il pose simplement
* sa vue sur une AMenuCameraSpot tiree au hasard et affiche le menu par-dessus.
*
* Comme dans le jeu, l'UI vit sur le controller et pas sur un acteur du monde.
*/
UCLASS()
class SURVIVAL_PROJET_API AMainMenuPlayerController : public APlayerController
{
GENERATED_BODY()
public:
AMainMenuPlayerController();
/**
* Fondu au noir, creation de la session, puis ouverture de la map en
* serveur d'ecoute.
*
* Il n'existe qu'UN seul bouton pour lancer une partie : toute partie est
* une partie en ligne, meme jouee seul. Distinguer "solo" et "heberger"
* obligerait le joueur a decider avant de savoir si un ami se connectera,
* et surtout a relancer sa partie pour changer d'avis.
*
* On ne rejoint jamais depuis ce menu : l'arrivee se fait uniquement par
* invitation Steam, geree par USessionSubsystem quelle que soit la map
* affichee a cet instant.
*/
UFUNCTION(BlueprintCallable, Category = "Menu")
void StartGame();
/** Ouvre la demande de confirmation. Ne quitte rien par elle-meme. */
UFUNCTION(BlueprintCallable, Category = "Menu")
void QuitGame();
/** Ouvre l'ecran de reglages par-dessus le menu. */
UFUNCTION(BlueprintCallable, Category = "Menu")
void OpenSettings();
protected:
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
/**
* Ta map de jeu.
*
* TSoftObjectPtr et non une reference dure : une reference dure ferait
* charger la map de jeu EN MEME TEMPS que le menu, alors qu'on ne la veut
* qu'au clic sur Jouer. C'est l'equivalent d'une Addressable en Unity, par
* opposition a un champ public qui tire tout l'asset avec lui.
*/
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Menu")
TSoftObjectPtr<UWorld> GameLevel;
/** Ton WBP_MainMenu. */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Menu")
TSubclassOf<UMainMenuWidget> MainMenuClass;
/**
* Ton WBP_ConfirmDialog. Si tu le laisses vide, le bouton Quitter ferme le
* jeu directement -- pratique pour tester, mais laisse-le assigne.
*/
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Menu")
TSubclassOf<UConfirmDialogWidget> QuitDialogClass;
/** La question posee avant de fermer le jeu. */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Menu")
FText QuitDialogMessage;
/** Ton WBP_Settings, exactement le meme que celui du menu de pause. */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Menu")
TSubclassOf<USettingsMenuWidget> SettingsMenuClass;
/** Fondu d'arrivee sur le menu, au lancement du jeu. */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Menu", meta = (ClampMin = "0.1"))
float OpeningFadeDuration = 1.5f;
/** Fondu de depart, quand on quitte le menu pour la partie. */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Menu", meta = (ClampMin = "0.1"))
float LeaveFadeDuration = 1.f;
/** Le fondu, partage avec AFpsPlayerController. Assigne-lui ton WBP_Fade. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Menu")
TObjectPtr<UScreenFadeComponent> ScreenFade;
UPROPERTY(Transient, BlueprintReadOnly, Category = "Menu")
TObjectPtr<UMainMenuWidget> MainMenu;
UPROPERTY(Transient, BlueprintReadOnly, Category = "Menu")
TObjectPtr<UConfirmDialogWidget> QuitDialog;
UPROPERTY(Transient, BlueprintReadOnly, Category = "Menu")
TObjectPtr<USettingsMenuWidget> SettingsMenu;
private:
/** Tire un angle de vue au hasard, en evitant celui du dernier passage. */
AMenuCameraSpot* PickCameraSpot();
/** Le fondu vient de se terminer : on execute l'action mise de cote. */
UFUNCTION()
void HandleFadeFinished();
/** Oui : on ferme le jeu, immediatement. */
UFUNCTION()
void HandleQuitConfirmed();
/** Non : on referme la boite et on rend la main au menu. */
UFUNCTION()
void HandleQuitCancelled();
/** L'ecran de reglages demande a se fermer : on rend la main au menu. */
UFUNCTION()
void HandleSettingsCloseRequested();
/**
* La session n'a pas pu etre creee -- Steam eteint, hors ligne, service en
* panne. On charge la map QUAND MEME.
*
* C'est un choix delibere : un joueur qui clique Jouer veut jouer. Le rendre
* a son menu avec un message d'erreur reseau alors que rien ne l'empeche de
* jouer seul serait une punition pour une panne qui n'est pas la sienne. Il
* perd seulement la possibilite d'inviter, et le bouton Inviter le dira.
*/
UFUNCTION()
void HandleHostFailed(FText Reason);
/**
* Echec de connexion sur invitation : on remonte le fondu et on rend le menu.
* Ici pas de repli possible, la partie visee est celle d'un ami.
*/
UFUNCTION()
void HandleJoinFailed(FText Reason);
/** Ferme le jeu sans rien demander. */
void CloseGame();
EMenuPendingAction PendingAction = EMenuPendingAction::None;
};