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


编译运行,分别点击三个按钮,打印输出到屏幕

  • 18
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值