实现通过点击按钮切换UI并播放动画
添加数据类型
SlAiTypes.h
...
//Menu动画状态
namespace EMenuAnim
{
enum Type
{
Stop,//停止动画
Close,//关闭Menu
Open //打开Menu
};
}
声明变量与方法
SlAiMenuWidget.h
// Fill out your copyright notice in the Description page of Project Settings.
...
public:
...
//重写tick函数
virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime);
private:
...
//初始化动画组件
void InitializeAnimation();
//播放关闭动画
void PlayClose(EMenuType::Type NewMenu);
private:
...
//动画播放器
FCurveSequence MenuAnimation;
//曲线控制器
FCurveHandle MenuCurve;
//用来保存新的高度
float CurrentHeight;
//是否已经显示Menu组件
bool IsMenuShow;
//是否锁住按钮
bool ControlLocked;
//保存当前的动画状态
EMenuAnim::Type AnimState;
//保存当前的菜单
EMenuType::Type CurrentMenu;
};
SlAiMenuWidget.cpp
实现点击按钮切换UI并播放动画的方法
...
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SSlAiMenuWidget::Construct(const FArguments& InArgs)
{
...
InitializeMenuList();
InitializeAnimation();
}
void SSlAiMenuWidget::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime)
{
switch (AnimState)
{
case EMenuAnim::Stop:
break;
case EMenuAnim::Close:
//如果正在播放
if (MenuAnimation.IsPlaying())
{
//实时修改Menu的大小
ResetWidgetSize(MenuCurve.GetLerp() * 600.f, -1.f);
//在关闭了40%的时候设置不显示组件
if (MenuCurve.GetLerp() < 0.6f && IsMenuShow) ChooseWidget(EMenuType::None);
}
else {
//关闭动画完了,设置状态为打开
AnimState = EMenuAnim::Open;
//开始播放打开动画
MenuAnimation.Play(this->AsShared());
}
break;
case EMenuAnim::Open:
//如果正在播放
if (MenuAnimation.IsPlaying()) {
//实时改变Menu的大小
ResetWidgetSize(MenuCurve.GetLerp() * 600.f, CurrentHeight);
//在打开60%之后显示组件
if (MenuCurve.GetLerp() > 0.6f && !IsMenuShow) ChooseWidget(CurrentMenu);
}
//如果已经播放完毕
if (MenuAnimation.IsAtEnd()) {
//修改状态为Stop
AnimState = EMenuAnim::Stop;
//解锁按钮
ControlLocked = false;
}
break;
default:
break;
}
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SSlAiMenuWidget::MenuItemOnClicked(EMenuItem::Type ItemType)
{
//如果锁住了,直接return
if (ControlLocked) return;
//设置锁住了按钮
ControlLocked = true;
switch (ItemType)
{
case EMenuItem::None:
break;
case EMenuItem::StartGame:
PlayClose(EMenuType::StartGame);
break;
case EMenuItem::GameOption:
PlayClose(EMenuType::GameOption);
break;
case EMenuItem::QuitGame:
ControlLocked = false;
break;
case EMenuItem::NewGame:
PlayClose(EMenuType::NewGame);
break;
case EMenuItem::LoadRecord:
PlayClose(EMenuType::ChooseRecord);
break;
case EMenuItem::StartGameGoBack:
PlayClose(EMenuType::MainMenu);
break;
case EMenuItem::GameOptionGoBack:
PlayClose(EMenuType::MainMenu);
break;
case EMenuItem::NewGameGoBack:
PlayClose(EMenuType::StartGame);
break;
case EMenuItem::ChooseRecordGoBack:
PlayClose(EMenuType::StartGame);
break;
case EMenuItem::EnterGame:
//解锁按钮
ControlLocked = false;
break;
case EMenuItem::EnterRecord:
//解锁按钮
ControlLocked = false;
break;
}
}
...
//初始化动画
void SSlAiMenuWidget::InitializeAnimation()
{
//开始延时
const float StartDelay = 0.3f;
//持续时间
const float AnimDuration = 0.6f;
MenuAnimation = FCurveSequence();
//StartDelay何时开始这条曲线
//AnimDuration这条曲线持续的时间
//ECurveEaseFunction::QuadInOut二次方程曲线
MenuCurve = MenuAnimation.AddCurve(StartDelay, AnimDuration, ECurveEaseFunction::QuadInOut);
//初始设置Menu大小
ResetWidgetSize(600.f, 510.f);
//初始显示主界面
ChooseWidget(EMenuType::MainMenu);
//允许点击按钮
ControlLocked = false;
//设置动画状态为停止
AnimState = EMenuAnim::Stop;
//设置动画播放器跳到结尾,也就是1
MenuAnimation.JumpToEnd();
}
void SSlAiMenuWidget::PlayClose(EMenuType::Type NewMenu)
{
//设置新的界面
CurrentMenu = NewMenu;
//设置新高度
CurrentHeight = (*MenuMap.Find(NewMenu))->MenuHeight;
//设置播放状态是Close
AnimState = EMenuAnim::Close;
//播放反向动画
//MenuAnimation动画播放器
MenuAnimation.PlayReverse(this->AsShared());
}
MenuAnimation添加的是0.3秒后开始,持续0.6秒的二次曲线。
播放动画方法在Tick中实现。
进入游戏,读取存档和退出游戏暂未实现。