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

UE4 C++ —— UMG和C++交互_第1张图片
创建两个继承于MyHUD和MyWidget的蓝图类,即BP_MyHUD和BP_MyWidget

UE4 C++ —— UMG和C++交互_第2张图片
BP_MyWidget需先创建UMG蓝图,然后在UMG蓝图中指定继承的父类

UE4 C++ —— UMG和C++交互_第3张图片

UE4 C++ —— UMG和C++交互_第4张图片
编辑BP_MyWidget,控件结构

UE4 C++ —— UMG和C++交互_第5张图片
BP_MyWidget显示效果

UE4 C++ —— UMG和C++交互_第6张图片
编译保存,打开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 WidgetClass;
};

MyHUD.cpp

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

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

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

	//获取控制器
	APlayerController *myPlayerController = Cast(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(GetRootWidget());
	if (rootPanel)
	{
		UButton*  ButtonTwo = Cast(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

UE4 C++ —— UMG和C++交互_第7张图片
打开BP_MyHUD,指定Widget Class

UE4 C++ —— UMG和C++交互_第8张图片
编译运行,分别点击三个按钮,打印输出到屏幕

UE4 C++ —— UMG和C++交互_第9张图片

你可能感兴趣的:(UE4,C++)