Widget Manager 設計思路學習
兩種型別UI的建立方式
Widget State
用 Map
儲存當前建立的 UI
// 用於儲存當前 SourcerType 類的 TextureUI 集合 特定下的TextureUI列表
TMap<ESourceType, TArray<UTextureUI*>> TextureMap;
// 用於儲存當前 SourcerType 類的 Widget
TMap<ESourceType, UWidget*> WidgetMap;
// 根據 String 儲存對應的 UserWidget 廣泛的其他 UI
TMap<FString, UUserWidget*> UIMap;
透過 SourceType
型別控制當前只能顯示的 UI
// 用於儲存當前 SourceType 狀態
ESourceType WidgetState;
// 屬於同一類的 UI 顯示,其他型別的 UI 隱藏
bool ChangeWidgetState(ESourceType state);
LoadUI
用於建立、載入、顯示對應名字的 UI
template<typename T = UUserWidget>
T* LoadUI(const FString& prefix = "UMG", bool bVis = true) {
FString name = T::StaticClass()->GetName();
return Cast<T>(LoadUI(name, prefix, bVis));
}
UUserWidget* UWidgetManager::LoadUI(const FString& name, const FString& prefix, bool bVis) {
// 如果沒有儲存,則重新建立並加入
if (!UIMap.Contains(name)) {
UClass* cl = LoadClass<UUserWidget>(NULL, *FString::Printf(TEXT("/Game/Blueprints/%s/%s.%s_C"),*prefix, *name, *name));
UUserWidget* UI = CreateWidget<UUserWidget>(World, cl);
UI->AddToViewport();
UIMap.Add(name, UI);
}
// 控制是否顯示UI
UUserWidget* widget = UIMap[name];
ESlateVisibility visibility = widget->GetVisibility();
ESlateVisibility newVisibility = bVis ? ESlateVisibility::SelfHitTestInvisible : ESlateVisibility::Hidden;
if (visibility != newVisibility)
widget->SetVisibility(newVisibility);
return widget;
}
宏定義
Register Widget
註冊元件
#define RegisterWidget(sourceType, widget) \
FWidgetInfo sourceType ## Info; \
sourceType ## Info.TextureName = #sourceType; \
UWidgetManager::Get()->WidgetInfoMap.Add(sourceType, sourceType ## Info); \
UWidgetManager::Get()->WidgetMap.Add(sourceType, widget);
對初始化時已經在UI上建立過的 Widget
,進行註冊,從而記錄進 WidgetManager
中,方便管理
RegisterWidget(ENoneType, ButtonPanel);
RegisterWidget(Furniture, FurnitureListPanel);
RegisterWidget(Material, MaterialListUI);
RegisterWidget(Group, GroupListUI);
RegisterWidget(RoomObject, RoomObjectListUI);
RegisterWidget(Replace, ReplaceFurnitureList);
UWidgetManager::Get()->ChangeWidgetState(ESourceType::ENoneType);
LoadUI
當建立某些 UI 時,運用這種方法
#define GetUI(clas) UWidgetManager::Get()->LoadUI<clas>()
#define GetHiddenUI(clas) UWidgetManager::Get()->LoadUI<clas>("UMG", false)
#define GetClientUI(clas) UWidgetManager::Get()->LoadUI<clas>("Client")