I am using an ActorComonent as GUIManager, and at BeginPlay of the GameMode, it puts on screen the widgets I want.
For example, in my UGUI_Manager, I have a UserWidget which works as a HealthBar. In the BP of my Health Bar, I have a function that updates it when the character tells the GUI Manager to update it.
Alas, I have two problems:
- Even while debugging, if I give the BP event an input between 0,2 and 1 (never 0) it always looks empty;
- I have no idea how to make the Character call the GUI Manager to update the function.
Maybe I’m just overthinking it, but this is the way they asked me to work on it…
What I have now:
UFPS_GUIManager::UFPS_GUIManager()
{
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
PrimaryComponentTick.bCanEverTick = true;
PrimaryComponentTick.bStartWithTickEnabled = false;
}
// Called when the game starts
void UFPS_GUIManager::BeginPlay() //Create setup function to avoid beginplay
{
Super::BeginPlay();
}
void UFPS_GUIManager::SetupGUIManager()
{
HealthBar = CreateWidget<UUserWidget>(GetWorld(), HealthBarClass);
if (HealthBar)
{
HealthBar->AddToViewport();
}
}
void UFPS_GUIManager::UpdateBar(float HealthPercent)
{
if (HealthBar)
{
UFunction* Function = HealthBar->FindFunction("HealthHasChanged");
if (Function)
{
HealthBar->ProcessEvent(Function, &HealthPercent);
UE_LOG(LogTemp, Warning, TEXT("Character gave me the health: %f"), HealthPercent);
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Function not found"));
}
}
else
{
UE_LOG(LogTemp, Warning, TEXT("HealthBar is null"));
}
/*HealthBar->ProcessEvent(Function, &HealthPercent);*/
}
void UFPS_GUIManager::ShowHealthBar()
{
if (HealthBar)
{
HealthBar->SetVisibility(ESlateVisibility::Visible);
}
}
void UFPS_GUIManager::HideHealthBar()
{
if (HealthBar)
{
HealthBar->SetVisibility(ESlateVisibility::Hidden);
}
}
AFPS_GameModeBase::AFPS_GameModeBase()
{
PlayerControllerClass = AMyCharacterController::StaticClass();
static ConstructorHelpers::FClassFinder<APawn> PlayerPawnClassFinder(TEXT("/Game/FirstPerson/Blueprints/BP_MyCharacter"));
DefaultPawnClass = PlayerPawnClassFinder.Class;
GUIManager = CreateDefaultSubobject<UFPS_GUIManager>(TEXT("GUIManager"));
}
void AFPS_GameModeBase::BeginPlay()
{
Super::BeginPlay();
if (GUIManager)
{
GUIManager->SetupGUIManager();
GUIManager->ShowHealthBar();
GUIManager->UpdateBar(1.0f);
}
else
{
UE_LOG(LogTemp, Error, TEXT("GUIManager is nullptr."));
}
}
AMyCharacter::AMyCharacter(const FObjectInitializer& ObjectInitializer)
:Super(ObjectInitializer.SetDefaultSubobjectClass<UCustomMovementComponent>(ACharacter::CharacterMovementComponentName))
{
PrimaryActorTick.bCanEverTick = true;
GetCapsuleComponent()->InitCapsuleSize(55.f, 96.0f);
// Create a CameraComponent
FirstPersonCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera"));
FirstPersonCameraComponent->SetupAttachment(GetCapsuleComponent());
FirstPersonCameraComponent->SetRelativeLocation(FVector(-10.f, 0.f, 60.f)); // Position of the camera
FirstPersonCameraComponent->bUsePawnControlRotation = true;
UE_LOG(LogTemp, Warning, TEXT("Character created. Initial Health: %f"), Health);
CustomMovementComponent = Cast<UCustomMovementComponent>(GetCharacterMovement());
GUIManager = CreateDefaultSubobject<UFPS_GUIManager>(TEXT("GUIManager"));
}
float AMyCharacter::GetHealth()
{
return Health/MaxHealth;
}
void AMyCharacter::UpdateHealthBar()
{
if (GUIManager)
{
GUIManager->UpdateBar(GetHealth());
}
}