断断续续学习Unreal很久了,但工作用的是Unity,Unreal很多API都记不住,就分类记录下。
C++获取UMG组件有2种方式,目前知道的,一个是通过属性宏(BindWidget),另一个则类似Unity的Transform.Find(string name),Unreal用的是UWidget* GetWidgetFromName(const FName& Name) const。
.h:
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "Components/Button.h"
#include "StartUserWidget.generated.h"
/**
*
*/
UCLASS()
class RPGPROJECT_API UStartUserWidget : public UUserWidget
{
GENERATED_BODY()
public:
virtual bool Initialize() override;
UFUNCTION()
void OnStartBtnClick();
UFUNCTION()
void OnQuitBtnClick();
public:
UPROPERTY()
UButton* StartBtn;
UPROPERTY(Meta = (BindWidget))
UButton* QuitBtn;
};
.cpp:
#include "UI/StartUserWidget.h"
#include "Runtime/Engine/Classes/Kismet/KismetSystemLibrary.h"
bool UStartUserWidget::Initialize()
{
if (!Super::Initialize())
return false;
StartBtn = Cast<UButton>(GetWidgetFromName(TEXT("StartBtn")));
if (StartBtn != nullptr)
StartBtn->OnClicked.AddDynamic(this, &UStartUserWidget::OnStartBtnClick);
if (QuitBtn != nullptr)
QuitBtn->OnClicked.AddDynamic(this, &UStartUserWidget::OnQuitBtnClick);
return true;
}
void UStartUserWidget::OnStartBtnClick()
{
UE_LOG(LogTemp, Error, TEXT("OnStartBtnClick"));
}
void UStartUserWidget::OnQuitBtnClick()
{
UE_LOG(LogTemp, Error, TEXT("OnQuitBtnClick"));
// Quit game
UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit);
}
自己也写了个UI管理的,本来想写个单例来着,不知道Unreal怎么写,就放在GameInstance中来管理,估计随着学习还会改:
#include "GameInstance/MainGameInstance.h"
#include "Runtime/Engine/Classes/Kismet/GameplayStatics.h"
#include "UI/MessageUserWidget.h"
void UMainGameInstance::Init()
{
UGameInstance::Init();
FCoreUObjectDelegates::PreLoadMap.AddUObject(this, &UMainGameInstance::BeginLoadingScene);
FCoreUObjectDelegates::PostLoadMapWithWorld.AddUObject(this, &UMainGameInstance::EndLoadingScene);
InitializeUserWidgetMap();
InitializeSceneMap();
UserWidgetList.Reset();
}
void UMainGameInstance::BeginLoadingScene(const FString& Map)
{
Release();
}
void UMainGameInstance::EndLoadingScene(UWorld* World)
{
}
UUserWidget* UMainGameInstance::ShowWidget(int UserWidgetId, bool bIsAddToViewport)
{
if (!UserWidgetMap.Contains(UserWidgetId))
return nullptr;
UUserWidget* CurrentWidget = nullptr;
if(UserWidgetList.Contains(UserWidgetId))
CurrentWidget = UserWidgetList[UserWidgetId];
else
{
const TCHAR* UserWidgetClassName = UserWidgetMap[UserWidgetId];
CurrentWidget = CreateWidget<UUserWidget>(this, LoadClass<UUserWidget>(this, UserWidgetClassName));
}
if (CurrentWidget != nullptr && bIsAddToViewport && !CurrentWidget->IsInViewport())
CurrentWidget->AddToViewport();
if (CurrentWidget != nullptr && !UserWidgetList.Contains(UserWidgetId))
UserWidgetList.Add(UserWidgetId, CurrentWidget);
return CurrentWidget;
}
void UMainGameInstance::RemoveWidget(int UserWidgetId)
{
if (!UserWidgetList.Contains(UserWidgetId))
return;
UUserWidget* TempUserWidget = UserWidgetList[UserWidgetId];
if(TempUserWidget != nullptr && TempUserWidget->IsInViewport())
TempUserWidget->RemoveFromViewport();
}
void UMainGameInstance::ShowMessageView(FString Msg)
{
UMessageUserWidget* MessageUserWidget = Cast<UMessageUserWidget>(ShowWidget((int)EUserWidget::MessageView));
if (MessageUserWidget != nullptr)
MessageUserWidget->ShowMessage(Msg);
}
void UMainGameInstance::LoadScene(int SceneId)
{
if (!SceneMap.Contains(SceneId))
return;
UWorld* World = GetWorld();
if (World != nullptr)
UGameplayStatics::OpenLevel(World, SceneMap[SceneId]);
else
UE_LOG(LogTemp, Error, TEXT("World == nullptr"));
}
void UMainGameInstance::Release()
{
if (UserWidgetList.Num() > 0)
{
for (TMap<int, UUserWidget*>::TIterator it = UserWidgetList.CreateIterator(); it; ++it)
{
if (it->Value->IsInViewport())
it->Value->RemoveFromViewport();
}
}
UserWidgetList.Reset();
}
void UMainGameInstance::InitializeUserWidgetMap()
{
UserWidgetMap.Reset();
UserWidgetMap.Add((int)EUserWidget::StartView, TEXT("WidgetBlueprint'/Game/UI/StartView.StartView_C'"));//需要加上_C
UserWidgetMap.Add((int)EUserWidget::MainView, TEXT("WidgetBlueprint'/Game/UI/MainView.MainView_C'"));
UserWidgetMap.Add((int)EUserWidget::MessageView, TEXT("WidgetBlueprint'/Game/UI/MessageView.MessageView_C'"));
}
void UMainGameInstance::InitializeSceneMap()
{
SceneMap.Reset();
SceneMap.Add((int)EScene::StartScene, TEXT("/Game/Scene/Start"));
SceneMap.Add((int)EScene::MainScene, TEXT("/Game/Scene/Main"));
}