自己玩的时候,发现UMG的初始化比PlayerState初始化快。而且UI一直执行NativeTick来刷新UI界面,有点费。研究了一下Unreal的Delegate,发现有点麻烦,还得自己声明一个类型。
问题代码:
AMainGameMode::AMainGameMode()
{
DefaultPawnClass = AMainCharacter::StaticClass();
PlayerStateClass = AMainCharacterState::StaticClass();
PlayerControllerClass = AMainCharacterController::StaticClass();
}
void AMainGameMode::BeginPlay()
{
auto tempGameInstance = Cast<UMainGameInstance>(GetGameInstance());
if (tempGameInstance != nullptr)
tempGameInstance->ShowWidget((int)EUserWidgetID::MainView);
}
修改后,Delegate其实可以放在一个单例中来管理,没搜到Unreal单例的实现,就随便拿GameInstance来测试:
MainGameInstance.h
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnInitPlayerState);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnUpdatePlayerState);
public:
void BoardCast_InitPlayerState();
void BoardCast_UpdatePlayerState();
public:
UPROPERTY(BlueprintAssignable, Category = "MainGameInstance")
FOnInitPlayerState m_OnInitPlayerState;
UPROPERTY(BlueprintAssignable, Category = "MainGameInstance")
FOnUpdatePlayerState m_OnUpdatePlayerState;
MainGameInstance.cpp
void UMainGameInstance::BoardCast_InitPlayerState()
{
m_OnInitPlayerState.Broadcast();
}
void UMainGameInstance::BoardCast_UpdatePlayerState()
{
m_OnUpdatePlayerState.Broadcast();
}
监听就很简单了,就跟普通的OnComponentBeginOverlap事件差不多。在UMG的C++类中声明2个方法:
private:
UFUNCTION()
void OnInitPlayerState();
UFUNCTION()
void OnUpdatePlayerState();
添加和移除也很简单:
void UMainUserWidget::AddEvent()
{
auto mainGameInstance = Cast<UMainGameInstance>(GetGameInstance());
if (!mainGameInstance) return;
mainGameInstance->m_OnInitPlayerState.AddDynamic(this, &UMainUserWidget::OnInitPlayerState);
mainGameInstance->m_OnUpdatePlayerState.AddDynamic(this, &UMainUserWidget::OnUpdatePlayerState);
}
void UMainUserWidget::RemoveEvent()
{
auto mainGameInstance = Cast<UMainGameInstance>(GetGameInstance());
if (!mainGameInstance) return;
mainGameInstance->m_OnInitPlayerState.RemoveAll(this);
mainGameInstance->m_OnUpdatePlayerState.RemoveAll(this);
}