1. 程式人生 > >UE4 C++ —— UMG和C++互動

UE4 C++ —— UMG和C++互動

簡述 在UE4開發中,我們想使用UMG建立顯示介面,而在C++程式碼中編寫邏輯處理程式碼。這樣就需要UMG和C++進行互動,即在C++中引用UMG中的控制元件,並進行事件繫結等操作

互動方法一,強轉子集GetRootWidget()        //獲取根節點 GetChildAt()            //獲取子節點 UMG控制元件呈樹狀結構,根據根節點可以獲取到所有的子節點二,反射繫結UPROPERTY(Meta = (BindWidget)) UButton *ButtonOne; 繫結的型別和名稱必須和藍圖內的一致三,根據控制元件名獲取GetWidgetFromName() 獲取到UWidget*型別,強轉成指定型別

例項應用 建立C++空專案,新建兩個C++類,分別繼承於HUD和UserWidget,命名為MyHUD和MyWidget

建立兩個繼承於MyHUD和MyWidget的藍圖類,即BP_MyHUD和BP_MyWidget

BP_MyWidget需先建立UMG藍圖,然後在UMG藍圖中指定繼承的父類

編輯BP_MyWidget,控制元件結構

BP_MyWidget顯示效果

編譯儲存,開啟VS,編寫C++程式碼

原始碼 MyHUD.h

#include "CoreMinimal.h"
#include "GameFramework/HUD.h"
#include "MyHUD.generated.h"

UCLASS()
class PROJECTDEMO2_API AMyHUD : public AHUD
{
	GENERATED_BODY()
	
protected:
	virtual void BeginPlay() override;

public:
	UPROPERTY(EditAnywhere, Category = "UserWidget")
	TSubclassOf<class UMyWidget> WidgetClass;
};

MyHUD.cpp

#include "MyHUD.h"
#include "Kismet/GameplayStatics.h"
#include "MyWidget.h"

void AMyHUD::BeginPlay()
{
	Super::BeginPlay();

	UMyWidget* widget = CreateWidget<UMyWidget>(GetWorld(), WidgetClass);
	if (widget != nullptr)
	{
		widget->AddToViewport();
	}
	

	//獲取控制器
	APlayerController *myPlayerController = Cast<APlayerController>(UGameplayStatics::GetPlayerController(GetWorld(), 0));
	//設定滑鼠輸入模式
	if (myPlayerController != nullptr)
	{
		myPlayerController->bShowMouseCursor = true;
		FInputModeGameOnly InputMode;
		InputMode.SetConsumeCaptureMouseDown(true);
		myPlayerController->SetInputMode(InputMode);
	}
}

MyWidget.h

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "MyWidget.generated.h"

class UImage;
class UCanvasPanel;
class UButton;

UCLASS()
class PROJECTDEMO2_API UMyWidget : public UUserWidget
{
	GENERATED_BODY()
	
public:

	UMyWidget(const FObjectInitializer& objectInitializer);

	virtual bool Initialize() override;

	UFUNCTION()
		void ButtonOneEvent();

	UFUNCTION()
		void ButtonTwoEvent();

	UFUNCTION(BlueprintCallable, Category = "UserWidget")
		void ButtonThreeEvent();

public:
	//反射繫結
	UPROPERTY(Meta = (BindWidget))
	UButton *ButtonOne;

	UCanvasPanel* rootPanel;
};

MyWidget.cpp

#include "MyWidget.h"
#include "CanvasPanel.h"
#include "Image.h"
#include "Button.h"
#include "TextBlock.h"
#include "Text.h"

UMyWidget::UMyWidget(const FObjectInitializer& objectInitializer) :Super(objectInitializer)
{

}
bool UMyWidget::Initialize()
{
	if (!Super::Initialize())
	{
		return false;
	}

	//ButtonOne
	ButtonOne->OnClicked.__Internal_AddDynamic(this, &UMyWidget::ButtonOneEvent, FName("ButtonOneEvent"));

	//ButtonTwo
	rootPanel = Cast<UCanvasPanel>(GetRootWidget());
	if (rootPanel)
	{
		UButton*  ButtonTwo = Cast<UButton>(rootPanel->GetChildAt(2));
		ButtonTwo->OnClicked.__Internal_AddDynamic(this, &UMyWidget::ButtonTwoEvent, FName("ButtonTwoEvent"));
	}

	//ButtonThere
	UButton*  ButtonThere = (UButton*)GetWidgetFromName(TEXT("ButtonThree"));
	FScriptDelegate ButTwoDel;
	ButTwoDel.BindUFunction(this, "ButtonThreeEvent");
	ButtonThere->OnReleased.Add(ButTwoDel);
	
	return true;
}

void UMyWidget::ButtonOneEvent()
{
	if (GEngine) {
		GEngine->AddOnScreenDebugMessage(-1, 20, FColor::Yellow, "ButtonOneEvent");
	}
}

void UMyWidget::ButtonTwoEvent()
{
	if (GEngine) {
		GEngine->AddOnScreenDebugMessage(-1, 20, FColor::Yellow, "ButtonTwoEvent");
	}
}

void UMyWidget::ButtonThreeEvent()
{
	if (GEngine) {
		GEngine->AddOnScreenDebugMessage(-1, 20, FColor::Yellow, "ButtonThreeEvent");
	}
}

注:在MyWidget中我們獲取了Button的引用,並繫結OnClicked事件,在MyHUD中設定了滑鼠顯示模式和添加了Widget到視口。

編譯儲存,在World Settings指定HUD Class為BP_MyHUD

開啟BP_MyHUD,指定Widget Class

編譯執行,分別點選三個按鈕,列印輸出到螢幕