HIi, after following this lesson I still have the mouse locked. I tried some EU_LOG to understood the problem and result that my function Teardown() isnt called because UMainMenu* Menu is nullptr so is never called!
Any suggestion?
Here is my code
PuzzlePlatformGameInstance.h
#pragma once
#include "CoreMinimal.h"
#include "Engine/GameInstance.h"
#include "MenuSystem/MenuInterface.h"
#include "PuzzlePlatformsGameInstance.generated.h"
/**
*
*/
UCLASS()
class PUZZLEPLATFORMS_API UPuzzlePlatformsGameInstance : public UGameInstance, public IMenuInterface
{
GENERATED_BODY()
public:
UPuzzlePlatformsGameInstance(const FObjectInitializer & ObjectInitializer);
virtual void Init();
UFUNCTION(BlueprintCallable)
void LoadMenu();
UFUNCTION(Exec)
void Level1(int32 Password);
UFUNCTION(Exec)
void Host();
UFUNCTION(Exec)
void Join(const FString& Address);
private:
TSubclassOf<class UUserWidget> MenuClass;
class UMainMenu* Menu;
int32 NPlayers = 0;
};
PuzzlePlatformGameInstance.cpp
#include "PuzzlePlatformsGameInstance.h"
#include "Engine/Engine.h"
#include "Engine/World.h"
#include "EngineUtils.h"
#include "Engine/StaticMeshActor.h"
#include "GameFramework/PlayerController.h"
#include "GameFramework/GameMode.h"
#include "GameFramework/Actor.h"
#include "UObject/ConstructorHelpers.h"
#include "Blueprint/UserWidget.h"
#include "Components/Widget.h"
#include "SpecialDoor.h"
#include "MenuSystem/MainMenu.h"
UPuzzlePlatformsGameInstance::UPuzzlePlatformsGameInstance(const FObjectInitializer & ObjectInitializer)
{
ConstructorHelpers::FClassFinder<UUserWidget> MenuBPClass(TEXT("/Game/MenuSystem/WBP_MainMenu"));
if (!ensure(MenuBPClass.Class != nullptr)) return;
MenuClass = MenuBPClass.Class;
}
void UPuzzlePlatformsGameInstance::Init()
{
UE_LOG(LogTemp, Warning, TEXT("[PUZZLEPLATGAMEINSTANCE]Found Class: %s"), *MenuClass->GetName());
}
void UPuzzlePlatformsGameInstance::LoadMenu()
{
if (!ensure(MenuClass != nullptr))
{
UE_LOG(LogTemp, Warning, TEXT("[LOADMENU] MenuClass nullptr]"));
return;
}
Menu = CreateWidget<UMainMenu>(this, MenuClass);
if (!ensure(Menu != nullptr)) return;
Menu->Setup();
Menu->SetMenuInterface(this);
}
void UPuzzlePlatformsGameInstance::Host()
{
UE_LOG(LogTemp, Warning, TEXT("Calling Menu->Teardown()"));
if (Menu != nullptr)
{
UE_LOG(LogTemp, Warning, TEXT("[HOST]: Menu not null"));
Menu->Teardown();
}
else
{
UE_LOG(LogTemp, Warning, TEXT("[HOST]: Menu is NULL"));
}
UEngine* Engine = GetEngine();
if (!ensure(Engine != nullptr)) return;
Engine->AddOnScreenDebugMessage(0, 5, FColor::Green, TEXT("Hosting....."));
UWorld* World = GetWorld();
if (!ensure(World != nullptr)) return;
World->ServerTravel("/Game/ThirdPersonCPP/Maps/ThirdPersonExampleMap?listen");
}
void UPuzzlePlatformsGameInstance::Join(const FString& Address)
{
UEngine* Engine = GetEngine();
if (!ensure(Engine != nullptr)) return;
Engine->AddOnScreenDebugMessage(0, 5, FColor::Green, FString::Printf(TEXT("Joining to %s"), *Address));
APlayerController* PlayerController = GetFirstLocalPlayerController();
if (!ensure(PlayerController != nullptr)) return;
PlayerController->ClientTravel(Address, ETravelType::TRAVEL_Absolute);
}
MainMenu.h
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "MenuInterface.h"
#include "MainMenu.generated.h"
/*
*
*/
UCLASS()
class PUZZLEPLATFORMS_API UMainMenu : public UUserWidget
{
GENERATED_BODY()
public:
void SetMenuInterface(IMenuInterface* MenuInterface);
void Setup();
void Teardown();
protected:
virtual bool Initialize() override;
private:
UPROPERTY(meta = (BindWidget))
class UButton* Host;
UPROPERTY(meta = (BindWidget))
class UButton* Join;
UFUNCTION()
void HostServer();
IMenuInterface* MenuInterface;
};
MainMenu.cpp
#include "MainMenu.h"
#include "Components/Button.h"
bool UMainMenu::Initialize()
{
bool bSuccess = Super::Initialize();
if (!bSuccess) return false;
if (!ensure(Host != nullptr)) return false;
Host->OnClicked.AddDynamic(this, &UMainMenu::HostServer);
return true;
}
void UMainMenu::Setup()
{
this->AddToViewport();
UWorld* World = GetWorld();
if (!ensure(World != nullptr)) return;
APlayerController* PlayerController = World->GetFirstPlayerController();
if (!ensure(PlayerController != nullptr)) return;
FInputModeUIOnly InputModeData;
InputModeData.SetWidgetToFocus(this->TakeWidget());
InputModeData.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
PlayerController->SetInputMode(InputModeData);
PlayerController->bShowMouseCursor = true;
}
void UMainMenu::Teardown()
{
UE_LOG(LogTemp, Warning, TEXT("Menu Teard down called"));
this->RemoveFromViewport();
UWorld* World = GetWorld();
if (!ensure(World != nullptr)) return;
APlayerController* PlayerController = World->GetFirstPlayerController();
if (!ensure(PlayerController != nullptr)) return;
FInputModeGameOnly InputModeData;
PlayerController->SetInputMode(InputModeData);
PlayerController->bShowMouseCursor = false;
}
void UMainMenu::SetMenuInterface(IMenuInterface* MenuInterface)
{
this->MenuInterface = MenuInterface;
}
void UMainMenu::HostServer()
{
if (MenuInterface != nullptr)
{
MenuInterface->Host();
}
}
MenuInterface.h
#pragma once
#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "MenuInterface.generated.h"
// This class does not need to be modified.
UINTERFACE(MinimalAPI)
class UMenuInterface : public UInterface
{
GENERATED_BODY()
};
/**
*
*/
class PUZZLEPLATFORMS_API IMenuInterface
{
GENERATED_BODY()
// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
virtual void Host() = 0; //No implementation
};
So in my OutputLog I have this when pressing HOST button
You can find this UE_LOG into PuzzlePlatformGameInstance.cpp at row 51 in Host function.
And also when starting the game I get this error that I didnt see in the OutputLog of the video
I cleared the console before hitting play
LogPlayerController: Error: InputMode:UIOnly - Attempting to focus Non-Focusable widget SObjectWidget [Widget.cpp(710)]!
@sampattuzzi Could you help me?
Meanwhile I will try to fix it of course!
Thank you