yep at last fixed screen widget issue.
as before mentioned, had tried even version upgrade last week to fix this but then that became not feasible because some modules have changed and not compatible with some existing change sets. (figuring out that also took 3-4 days coding )
so after ~2 weeks of studying, at last the screen widget issue detected in testing were fixed.
to fix screen widget issue: you should write some code alike a widget component alike -->
e.g. :
#pragma once
#include "CoreMinimal.h"
#include "Components/WidgetComponent.h"
#include "AWidgetComponent.generated.h"
UCLASS(meta=(BlueprintSpawnableComponent))
class UAWidgetComponent : public UWidgetComponent
{
GENERATED_BODY()
public:
// virtual void InitWidget() override;
// virtual void OnRegister() override;
UAWidgetComponent();
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
// This acts as the reliable "BeginPlay" for the Widget Component
virtual void InitWidget() override;
// Force the component to find the listen server's local player
//virtual ULocalPlayer* GetLocalPlayer() const override;
// Force the component to return true for rendering screen-space widgets
virtual bool ShouldDrawWidget() const override;
virtual void fixPCIssue();
bool isPCFixed = false;
// //UFUNCTION(BlueprintCallable, Category=UserInterface)
// virtual void SetWidget(UUserWidget* widget) override;
};
then c++ file:
#include "AWidgetComponent.h"
#include "Engine/LocalPlayer.h"
#include "Kismet/GameplayStatics.h"
#include "Components/WidgetComponent.h"
#include "GameFramework/Pawn.h"
// ADD THIS LINE TO FIX ERROR C2027:
#include "Engine/GameInstance.h"
UAWidgetComponent::UAWidgetComponent() {
bTickInEditor = false;
PrimaryComponentTick.bCanEverTick = true;
}
bool UAWidgetComponent::ShouldDrawWidget() const
{
// If it's world space, let the base class handle it normally
if (GetWidgetSpace() == EWidgetSpace::World)
{
return Super::ShouldDrawWidget();
}
// For Screen Space, ensure we have a valid widget and a valid local player
return (GetWidget() != nullptr);// && (GetLocalPlayer() != nullptr);
}
void UAWidgetComponent::InitWidget() {
Super::InitWidget();
SetTickWhenOffscreen(true);
//SetTickMode(UWidgetComponent::EWidgetTickMode::Enabled);
}
void UAWidgetComponent::fixPCIssue() {
APlayerController* PC_ = nullptr;
APawn* OwningPawn = nullptr;
if (AActor* OwnerActor = GetOwner())
{
OwningPawn = Cast<APawn>(OwnerActor);
if (OwningPawn != nullptr)
{
PC_ = Cast<APlayerController>(OwningPawn->GetController());
}
}
if(OwningPawn == nullptr)
return;
if(PC_) {
if(!isPCFixed) {
SetOwnerPlayer(PC_->GetLocalPlayer());
ReleaseResources();
// 3. Force rebuild the Slate tree now that the LocalPlayer is non-null
InitWidget();
// 4. Safely pull your user widget reference and force visibility rules
if (UUserWidget* NativeUserWidget = GetUserWidgetObject())
{
NativeUserWidget->SetVisibility(ESlateVisibility::SelfHitTestInvisible);
NativeUserWidget->SetOwningPlayer(PC_);
isPCFixed = true;
}
}
} else { // there is no pc
//if ( GetOwnerPlayer() == nullptr )
if(UWorld* World = GetWorld())
{
if (World->IsGameWorld() && GetWidgetSpace() == EWidgetSpace::Screen)
{
APlayerController* PC = World->GetFirstPlayerController();
if (PC && PC->GetLocalPlayer())
{
// Get the Pawn or Character that owns the widget
if (OwningPawn!= nullptr && OwningPawn->GetLocalRole() == ROLE_Authority)
{
// This widget's owner is the Server
//if ( GetOwnerPlayer() == nullptr )
SetOwnerPlayer(PC->GetLocalPlayer());
}
else {
SetOwnerPlayer(PC->GetLocalPlayer());
}
// Force Slate to re-evaluate the widget tree context
// 2. Completely dump the existing broken Slate memory tracking
ReleaseResources();
// 3. Force rebuild the Slate tree now that the LocalPlayer is non-null
InitWidget();
// 4. Safely pull your user widget reference and force visibility rules
if (UUserWidget* NativeUserWidget = GetUserWidgetObject())
{
NativeUserWidget->SetVisibility(ESlateVisibility::SelfHitTestInvisible);
NativeUserWidget->SetOwningPlayer(PC);
isPCFixed = true;
}
}
}
}
}
}
void UAWidgetComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
//SetComponentTickEnabled(true);
if(!isPCFixed)
{
SetComponentTickEnabled(true);
fixPCIssue();
}
}
then also you have to create the widgetcomponent and its widget alike following->

Yorumlar
Yorum Gönder