【UE5】UMG C++父类绑定蓝图子类属性

有时我们在设计UMG时可能会使用到C++父类来处理一些通用逻辑,如果我们想要在C++父类中获取其派生子类的某个属性,如Image或Button等,我们可以通过使用UE提供的BindWidget元数据标签的方式来获取。

BindWidget

BindWidget元数据标签在官方文档中并没有出现,但引擎是支持这个标签的。

在看例子之前我们需要注意一些BindWidget的要求:

  • BindWidget标识的变量必须是public变量;
  • BindWidget标识的变量必须是UWidget类型及其派生类型;
  • BindWidget标识的变量必须是指针;
  • 蓝图子类中必须存在同类型的同名控件。

首先我们创建一个继承自UUserWidget的自定义C++类UCusWidget,然后创建一个public变量,然后在UPROPERTY中设置BindWidget元数据:

c++ 复制代码
UCLASS()
class MYPROJECT_API UCusWidget : public UUserWidget
{
	GENERATED_BODY()
public:
	UPROPERTY(BlueprintReadWrite, Meta = (BindWidget),Category = "CusWidget")
	UImage* CusImage;
	UPROPERTY(BlueprintReadWrite, Meta = (BindWidget),Category = "CusWidget")
	UTextBlock* CusText;

	virtual void NativeConstruct() override;
};

然后创建一个继承自UCusWidget的UMG蓝图UW_Cus,为UI添加一个Image并命名为CusImage,添加一个TextBlock并命名为CusText:

这样控件CusImage和CusText就和父类中的同名变量绑定了,如此父类便可以通过同名变量来控制子类的控件了。

这里我们在Widget构造时给与CusImage一个随机颜色并在CusText中显示颜色的RGBA值:

c++ 复制代码
void UCusWidget::NativeConstruct()
{
	Super::NativeConstruct();
	if(CusImage)
	{
		CusImage->SetColorAndOpacity(FLinearColor::MakeRandomColor());
	}
	if(CusText)
	{
		CusText->SetText(FText::FromString(CusImage->ColorAndOpacity.ToString()));
	}
}

然后就可以看到结果了:

这里我在另一个Widget中封装了多个UW_Cus以便观察。

这里有一个坑需要注意,更新控件属性时应该使用对应的Set函数,如:CusImage->SetColorAndOpacity(FLinearColor::MakeRandomColor()),而不是直接赋值,如:CusImage->ColorAndOpacity = FLinearColor::MakeRandomColor(),直接赋值Widget不会更新样式。

BindWidgetOptional

BindWidget元数据需要强制绑定子蓝图的同名控件,而BindWidgetOptional功能上和BindWidget一致,但不需要强制绑定子蓝图中的同名控件,所以这就要求在书写C++代码时需要更严谨,因为它们修饰的变量都是指针,而使用BindWidgetOptional极容易出现空指针。

BindWidgetAnim

BindWidgetAnim是专门用来绑定UWidgetAnimation类型变量的元数据,和BindWidget一样,BindWidgetAnim对变量也有要求:

  • BindWidgetAnim标识的变量必须是public变量;
  • BindWidgetAnim标识的变量必须是UWidgetAnimation类型及其派生类型;
  • BindWidgetAnim标识的变量必须是指针;
  • BindWidgetAnim标识的变量必须是Transient变量;
  • 蓝图子类中必须存在同名的Widget动画。

关于Transient,Transient也是一个UPROPERTY的标识符,用于标识变量是否是临时变量,被标识的变量会被禁止序列化,如:

c++ 复制代码
UCLASS()
class MYPROJECT_API UCusWidget : public UUserWidget
{
	GENERATED_BODY()
public:
	UPROPERTY(BlueprintReadWrite, Meta = (BindWidgetOptional),Category = "CusWidget")
	UImage* CusImage;
	UPROPERTY(BlueprintReadWrite, Meta = (BindWidgetOptional),Category = "CusWidget")
	UTextBlock* CusText;
	UPROPERTY(BlueprintReadWrite,Transient, Meta = (BindWidgetAnim),Category = "CusWidget")
	UWidgetAnimation* StartAnime;

	virtual void NativeConstruct() override;	
};

BindWidgetAnimOptional

BindWidgetAnimOptional功能和BindWidgetOptional一样,用于非强制绑定动画的情况;

UE元数据参考

https://benui.ca/unreal/uproperty/#umg

相关推荐
2301_76347246几秒前
C++20概念(Concepts)入门指南
开发语言·c++·算法
阿猿收手吧!16 分钟前
【C++】std::promise原理与实战解析
c++
qq_124987075329 分钟前
基于SSM的动物保护系统的设计与实现(源码+论文+部署+安装)
java·数据库·spring boot·毕业设计·ssm·计算机毕业设计
Coder_Boy_35 分钟前
基于SpringAI的在线考试系统-考试系统开发流程案例
java·数据库·人工智能·spring boot·后端
Mr_sun.36 分钟前
Day06——权限认证-项目集成
java
瑶山38 分钟前
Spring Cloud微服务搭建四、集成RocketMQ消息队列
java·spring cloud·微服务·rocketmq·dashboard
abluckyboy1 小时前
Java 实现求 n 的 n^n 次方的最后一位数字
java·python·算法
2301_818732061 小时前
前端调用控制层接口,进不去,报错415,类型不匹配
java·spring boot·spring·tomcat·intellij-idea
m0_706653231 小时前
分布式系统安全通信
开发语言·c++·算法
2501_941982051 小时前
深度对比:Java、Go、Python 实现企微外部群推送,哪个效率更高?
java·golang·企业微信