UE4运用C++和框架开发坦克大战教程笔记(十八)(第55~57集)

该博客围绕UE4的UI开发展开,介绍了UI进入退出动画,包括HideOther面板隐藏逻辑及面板动画效果实现;阐述了弹窗进入界面的逻辑补全与功能验证;还涉及UI显示隐藏逻辑编写及遮罩管理器的完善,通过代码和测试展示了各功能的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

55. UI 进入退出动画

HideOther 面板出现时隐藏其他面板

我们先前写的 “根据面板类型 PanelShowType 采用不同的首次进入界面方法”,只写了对于 DoNothing 面板类型的首次进入界面逻辑,接下来我们来补全 HideOther 面板类型的相关逻辑,Reverse 的留到后面再写。

HideOther 面板类型的进入界面后会隐藏同 Level 下的其他面板(不包括弹窗),如果进入的是 Level_All 层级,则隐藏所有层级的其他面板(不包括弹窗)。

DDFrameWidget.cpp

void UDDFrameWidget::EnterPanelHideOther(UCanvasPanel* WorkLayout, UDDPanelWidget* PanelWidget)
{
   
	// 将显示组的同一层级的其他对象都隐藏,如果是 Level_All 就全部隐藏,Level_All 优先级高
	for (TMap<FName, UDDPanelWidget*>::TIterator It(ShowPanelGroup); It; ++It) {
   
		if (PanelWidget->UINature.LayoutLevel == ELayoutLevel::Level_All || PanelWidget->UINature.LayoutLevel == It.Value()->UINature.LayoutLevel) {
   
			It.Value()->PanelHidden();
		}
	}
	// 添加 UI 面板到 Layout
	UCanvasPanelSlot* PanelSlot = WorkLayout->AddChildToCanvas(PanelWidget);
	PanelSlot->SetAnchors(PanelWidget->UINature.Anchors);
	PanelSlot->SetOffsets(PanelWidget->UINature.Offsets);

	// 将 UI 面板添加到显示组
	ShowPanelGroup.Add(PanelWidget->GetObjectName(), PanelWidget);

	// 调用进入界面生命周期函数
	PanelWidget->PanelEnter();
}

void UDDFrameWidget::EnterPanelHideOther(UOverlay* WorkLayout, UDDPanelWidget* PanelWidget)
{
   
	// 将显示组的同一层级的其他对象都隐藏,如果是 Level_All 就全部隐藏,Level_All 优先级高
	for (TMap<FName, UDDPanelWidget*>::TIterator It(ShowPanelGroup); It; ++It) {
   
		if (PanelWidget->UINature.LayoutLevel == ELayoutLevel::Level_All || PanelWidget->UINature.LayoutLevel == It.Value()->UINature.LayoutLevel) {
   
			It.Value()->PanelHidden();
		}
	}

	// 添加到 UOverlay
	UOverlaySlot* PanelSlot = WorkLayout->AddChildToOverlay(PanelWidget);
	PanelSlot->SetHorizontalAlignment(PanelWidget->UINature.HAlign);
	PanelSlot->SetVerticalAlignment(PanelWidget->UINature.VAlign);

	// 将 UI 面板添加到显示组
	ShowPanelGroup.Add(PanelWidget->GetObjectName(), PanelWidget);

	// 调用进入界面生命周期函数
	PanelWidget->PanelEnter();
}

为了测试 HideOther 面板类型的面板首次进入界面,我们使用协程方法来安排各面板的出场顺序。等下会新建一个蓝图界面 BigMapPanel,并且将其设置为 HideOther 面板类型。

RCGameUIFrame.h

public:

	// 协程方法,用于安排面板出现顺序
	DDCoroTask* UIProcess();

RCGameUIFrame.cpp

void URCGameUIFrame::DDInit()
{
   
	AddToViewport();

	// 将显示面板代码放到协程方法里,此处替换为启动协程
	StartCoroutine("UIProcess", UIProcess());
}

DDCoroTask* URCGameUIFrame::UIProcess()
{
   
	DDCORO_PARAM(URCGameUIFrame);

#include DDCORO_BEGIN()

	D->ShowUIPanel("StatePanel");

	D->ShowUIPanel("MiniMapPanel");

#include DDYIELD_READY()

	DDYIELD_RETURN_SECOND(10.f);	// 挂起 10 秒

	D->ShowUIPanel("BigMapPanel");

#include DDCORO_END()
}

编译后,在 Blueprint/UIFrame 下创建一个 Widget Blueprint,命名为 BigMapPanel。打开界面并将其父类改成 RCBigMapPanel。随后将界面修改如下:

在这里插入图片描述
来到 HUDData,给 Class Wealth Data 添加一个元素如下:

在这里插入图片描述
运行游戏,10 秒后大地图面板会显示,原本界面上的状态栏和小地图面板会隐藏。(这里笔者为了方便读者查看效果,换了一张比较明显的图,后面课程也会要求替换)

(注:UI 框架的动图,笔者都会缩短挂起时间或稍作剪辑,所以从动图里看到会觉得变化比较快)

在这里插入图片描述

添加面板出现和收起的动画效果

接下来我们实现一下面板的出现和收起的动画效果。由于动画是在 UMG 里面做的,所以我们在面板类声明两个蓝图实现的方法,供 C++ 代码调用蓝图动画节点。

DDPanelWidget.h

public:

	// 动画回调函数,返回的 float 是动画时长
	UFUNCTION(BlueprintImplementableEvent)
	float DisplayEnterMovie();

	UFUNCTION(BlueprintImplementableEvent)
	float DisplayLeaveMovie();

protected:

	// 隐藏 UI 面板
	void SetSelfHidden();

protected:

	// 隐藏动画任务名
	static FName PanelHiddenName;

在面板显示和收起的方法里加入调用动画的语句;并且让面板收起动画播放完毕后再隐藏面板(通过延时方法实现)。

DDPanelWidget.cpp

FName UDDPanelWidget::PanelHiddenName(TEXT("PanelHiddenTask"));

void UDDPanelWidget::PanelEnter()
{
   
	SetVisibility(ESlateVisibility::Visible);
	// 调用进入界面动画
	DisplayEnterMovie();
}

void UDDPanelWidget::PanelDisplay()
{
   
	SetVisibility(ESlateVisibility::Visible);
	// 调用进入界面动画
	DisplayEnterMovie();
}

void UDDPanelWidget::PanelHidden()
{
   
	// 修改原本代码如下
	// 运行完移出界面动画后调用隐藏函数
	InvokeDelay(PanelHiddenName
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值