UE4项目_EveryThing开发有感_菜单UI管理

UE4项目_EveryThing开发有感之菜单UI管理

老规矩,-_-,随意写了,语文不好,懂意思就行.

项目地址:https://github.com/GuAoDiao/EveryThing

本文的内容主要为菜单里面的UI管理
具体就是菜单相关多UI之间来回互相切换,非常容易混乱.
这里提供一个自己的管理方案,主要采用的是状态机,状态切换.

  1. 定义一个enum,罗列所有可能性,

    UENUM(BlueprintType)
    enum class EMenuUIState : uint8
    {
        StartUp,
        MainMenu,
    
        CreateArchive,
        ArchiveList,
    
        MasterInterface,
        Storehouse,
    
        HouseMenu,
        HouseCreate,
        HouseList,
    
        Config,
    
        LoadingScreen,
        ErrorDialog,
        Unknown
    };
  2. 核心函数,用来管理UI之间的状态

    // 函数名称变量名称很明白了,就不做解释了
    public:
        EMenuUIState GetCurrentGameUIState() const { return CurrentGameUIState; }
        bool IsTargetGameUIState(EMenuUIState InGameUIState) const { return InGameUIState == CurrentGameUIState; }
        void ToggleToNewGameUIState(EMenuUIState InGameUIState);
        void ToggleToLastGameUIState();
    private:
        void FinishOldGameUIState(EMenuUIState InGameUIState);
        void StartNewGameUIState(EMenuUIState InGameUIState);
    private:
        EMenuUIState CurrentGameUIState;
        EMenuUIState LastGameUIState;
  3. 核心步骤

        /// 切换状态时
        void AEveryThingHUD_Menu::ToggleToNewGameUIState(EMenuUIState InGameUIState)
        {
            // 如果新的状态即要展示的UI不是加载界面或错误提示,则移除当前展示的UI
            // 错误提示弹出,加载界面弹出时,背景UI都不会发生改变,所以不移出
            if (InGameUIState != EMenuUIState::LoadingScreen && InGameUIState != EMenuUIState::ErrorDialog)
            {
                FinishOldGameUIState(CurrentGameUIState);
            }
            // 更新UI状态
            LastGameUIState = CurrentGameUIState;
            CurrentGameUIState = InGameUIState;
            // 展示新的UI
            StartNewGameUIState(CurrentGameUIState);
        }
        /// 移除和展示,根据不同的状态写相应的处理
        {
            // 移除
            case EMenuUIState::MainMenu:
                ShowMainMenu();
                break;
            // 展示
            case EMenuUIState::MainMenu:
                if (MainMenu) { MainMenu->RemoveFromParent(); }
                break;
        }

    目前为止,我们就可以通过切换状态来切换显示的UI了.
    因为是状态机管理,所以直接切换到新状态就可以了,如果UI复杂,有特殊需求,也可以修改扩展.

  4. 特殊实现,如错误提示

        // 如题,特殊状态错误提示时,需要一个错误信息,可以在切换UI后手动设置.
        void AEveryThingHUD_Menu::SetErrorDialogMessage(const FString& ErrorMessage)
        {
            if (IsTargetGameUIState(EMenuUIState::ErrorDialog) && ErrorDialog)
            {
                ErrorDialog->SetErrorMessage(FText::FromString(ErrorMessage));
            }
        }

下面是使用:

void UArchiveRow::LoadArchive()
{

    UEveryThingGameInstance* OwnerETGI = GetOwningPlayer() ? Cast<UEveryThingGameInstance>(GetOwningPlayer()->GetGameInstance()) : nullptr;
    AEveryThingHUD_Menu* OwnerMenuHUD = GetOwningPlayer() ? Cast<AEveryThingHUD_Menu>(GetOwningPlayer()->GetHUD()) : nullptr;
    if (OwnerETGI && OwnerMenuHUD)
    {
        // 加载存档成功,跳转至主界面
        if (OwnerETGI->LoadArchiveFromName(ArchiveName))
        {
            OwnerMenuHUD->ToggleToNewGameUIState(EMenuUIState::MasterInterface);
        }
        else
        {
        // 展示错误信息
            OwnerMenuHUD->ToggleToNewGameUIState(EMenuUIState::ErrorDialog);
            OwnerMenuHUD->SetErrorDialogMessage(TEXT("Can't load Archive"));
        }
    }
}

注:抛砖引玉,欢迎讨论,实现更好效果。

猜你喜欢

转载自blog.csdn.net/qq_33017259/article/details/80347004