首页 > 编程语言 >UE4 c++ -- 简单的UMG

UE4 c++ -- 简单的UMG

时间:2024-03-23 18:22:05浏览次数:33  
标签:HUD Widget CreateWidget -- Actor UMG UE4 IsDerived PlayerController

说明

学习一下如何将Widget蓝图与C++连接起来,将处理逻辑写在C++中

基础

在蓝图中,我们显示Widget是通过一个Actor或者PlayerController,甚至关卡蓝图,利用Create Widget以及 AddToViewPort使得Widget显示在屏幕上的
image
所以在C++中也是一样,一般来说由于Actor的销毁比如角色死亡,会导致其所有处理逻辑从内存中清除掉。所以将这个功能写在PlayerController类里。
现在为了演示,直接创建了一个Actor类和一个UserWidget类。

Actor类

其主要作用就是显示这个UMG界面,在.h文件中需要一个UserWidget类的指针,用来存储Create出来的对象。相当于上图中的那个变量
然后还需要接受一个类,一般通过TSubClassOf声明,然后在引擎中选择由UserWidget类创建好的蓝图类。相当于上图中CreateWidget模块的Class

//.h
public:
	UPROPERTY()
		class UXDebugMenuWidget* XDebugMenu;

	UPROPERTY(EditAnywhere, Category = "Debug")
		TSubclassOf<class UUserWidget> DebugMenuWdgClass;

在.cpp文件中就主要来实现上图中的逻辑

//.cpp
//Create Widget
XDebugMenu = CreateWidget<UXDebugMenuWidget>(GetWorld(), DebugMenuWdgClass);
if (XDebugMenu)
{
	XDebugMenu->AddToViewport();
}

CreateWidget函数

在源码中其为一个函数模板,

template <typename WidgetT = UUserWidget, typename OwnerT = UObject>
WidgetT* CreateWidget(OwnerT* OwningObject, TSubclassOf<UUserWidget> UserWidgetClass = WidgetT::StaticClass(), FName WidgetName = NAME_None)
{
	static_assert(TIsDerivedFrom<WidgetT, UUserWidget>::IsDerived, "CreateWidget can only be used to create UserWidget instances. If creating a UWidget, use WidgetTree::ConstructWidget.");
	
	static_assert(TIsDerivedFrom<OwnerT, UWidget>::IsDerived
		|| TIsDerivedFrom<OwnerT, UWidgetTree>::IsDerived
		|| TIsDerivedFrom<OwnerT, APlayerController>::IsDerived
		|| TIsDerivedFrom<OwnerT, UGameInstance>::IsDerived
		|| TIsDerivedFrom<OwnerT, UWorld>::IsDerived, "The given OwningObject is not of a supported type for use with CreateWidget.");

	SCOPE_CYCLE_COUNTER(STAT_CreateWidget);

	if (OwningObject)
	{
		return Cast<WidgetT>(UUserWidget::CreateWidgetInstance(*OwningObject, UserWidgetClass, WidgetName));
	}
	return nullptr;
}

可以看到有两个信息

  1. 该函数只能创建UserWidget 对于UWidget需要其他函数
  2. OwingObject的类型只能是UWidget UWidgetTree APlayerController UGameInstance UWorld其中的一种,其他的类型无法调用该函数
    所以当在Actor调用该函数生成Widget的时候,可以利用GetWorld()来得到UWorld类的参数,如果在PlayerController类中直接使用this指针即可

UserWidget类

参考
该类主要是处理UMG在蓝图中的逻辑。需要注意到点就是每个控件的声明是有严格的要求的,以Button控件为例

UPROPERTY(meta = (BindWidget))
	class UButton* Button_Tab1;
  1. UPROPERTY(meta = (BindWidget))
    BindWidget是一组专门用来绑定Button这些控件的枚举值中的一个UE官方文档
  2. 变量名称:C++中控件的名称必须和蓝图中一样
  3. 用BindWidget标记过的 widget 在 C++ 构造函数中为空,它们稍后在生命周期中被初始化。如果您需要进行类似构造函数的设置,请使用该NativeConstruct()函数。
  4. 对于按钮响应,可以调用官方设置好的委托函数广播即可OnClicked.AddDynamic(this,&Func);

使用HUD

使用HUD可以对一个GameMode设置使用一种UMG显示
image
GameMode是控制整个游戏的规则,相当于一种最高权限,可以设置玩家的控制器类型,默认角色类型,HUD类型等等。
当我们将将Widget放在HUD里面是,我们就可以通过GameMode来控制一些数值的显示,实际上是通过PlayerController来更改HUD的
可以将HUD理解为多个Widget的集合,我们将在HUD类里实现在Actor类中的创建Widget的操作。代码都是一样的,只不过OwingObject的类型我们需要修改为PlayerController,因为对于HUD类来说没有GetWorld对象,但其受到每个玩家控制器的控制,具有GetOwningPlayerController()函数来获取PlayerController。
然后就可以在PlayerController类里面使用HUD类对象调用HUD中的方法实现UMG的显示了。

标签:HUD,Widget,CreateWidget,--,Actor,UMG,UE4,IsDerived,PlayerController
From: https://www.cnblogs.com/XTG111/p/18091491

相关文章

  • HttpHelper
    publicstaticclassHttpHelper{//privatestaticLogHelperLog{get;}=newLogHelper("HttpHelper");///<summary>///发起POST同步请求///</summary>///<paramname="url"&g......
  • BUGAWAY算法小抄-树状数组(2024.03.23 更新)
    什么是树状数组?树状数组是支持单点修改和区间查询的、代码量小的数据结构。事实上,树状数组能解决的问题是线段树(一棵二叉树,每个节点表示一个区间,并存储该区间的一些相关信息。线段树可以高效地进行区间查询和区间更新操作。不是本文重点)能解决的问题的子集:树状数组能做的,线段树......
  • MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017
    打开mongoDB的mongoshell,出现以下提示,此时输入任意键都会退出界面,无法进行命令输入。这时,我们首先在网址栏中输入http://localhost:27017/是否连接到27017端口,如果返回结果如下:接着在cmd命令提示符中输入mongod,确认MongoDB服务器是否启动,返回结果如下:从红色框标记的部分......
  • 使用python登录boss 并自动投递简历打招呼
    使用的是selenium4的和3的版本语法有点出入但是大差不差暂时还没有完善会持续更新fromseleniumimportwebdriverimporttimefromselenium.webdriver.common.byimportByfromselenium.webdriver.support.uiimportWebDriverWaitfromselenium.webdriver.supp......
  • 关于scrapy框架爬某站出现DEBUG: Redirecting (meta refresh)的问题
    项目场景:Spider框架爬取m.baidu.com搜索结果问题描述访问地址为https://m.baidu.com/s?word=电影&pn=0最后结果变成了http://m.baidu.com/s?cip6=240e:390:6a52:67e5:b0fa:e9d6:226e:376d&word=电影&pn=0&pu=sz%401321_480&t_noscript=jump导致结果不对importjson......
  • 结构体和联合体的存储
    今天我们来看看结构体和联合体的存储,新的一天,卯足精神,冲冲冲!!!目录结构体的存储偏移量,对齐数,默认对齐数方法一:将相同类型的成员都放在一起方法二:使用位段位段的跨平台问题位段使用的注意事项联合体的存储总结结构体的存储我们已经了解了整型类型,浮点数,字符数的存......
  • 模版题——多路归并
    题目:https://www.acwing.com/problem/content/1264/这个题目主要考的是多路归并的思想和两步贪心1.第一步贪心,我们不会出现反复横跳的情况2.第二部贪心,对于我们能到达的前n个鱼塘,我们在这剩余的t时间,要钓到的肯定是前t个最大的,这就涉及到了多路归并问题。#include<bits/st......
  • MyBatis3源码深度解析(二十)动态SQL实现原理(一)动态SQL的核心组件
    文章目录前言第八章动态SQL实现原理8.1动态SQL的使用8.1.1\<if>8.1.2<where|trim>8.1.3<choose|when|otherwise>8.1.4\<foreach>8.1.5\<set>8.2SqlSource组件&BoundSql组件8.3LanguageDriver组件8.3.1XMLLanguageDriver8.3.2RawLanguageDriver8.4Sq......
  • 牛客周赛32——小红的矩阵修改
     题目:小红的矩阵修改状态压缩dp,对于每一个串,我们使用一个三进制数表示,由于只有三种字符,我们使用3进制数表示,这样一共就只有81中状态。#include<bits/stdc++.h>typedeflonglongll;usingnamespacestd;constintN=5e2+10;constintmod=1e9+7;intdp[1010]......
  • [nodejs] pm2 : nodejs 的进程管理工具
    0pm2概述0.1序0.2pm2简述PM2是一款非常优秀的Node进程管理工具,它有着丰富的特性:能够充分利用多核CPU且能够负载均衡、能够帮助应用在崩溃后、指定时间(clustermodel)和超出最大内存限制等情况下实现自动重启。PM2是开源的基于Nodejs的应用进程管理器,包括守护进......