本文主要面向UMG以及Common UI的初学者
文章目录
- 效果展示
- 概要
- Activate和Deactivate
- 可见性绑定
- UI动画
- 设置Common Activatable Widget的默认焦点
效果展示
概要
这个例子非常简单,定义了1+3个Common Activatable Widget
CommonUI_ActivatableWidgets相当于一个容器包含了其它3个Common Activatable Widget
,CommonUI_ActivatableWidgets里没有什么逻辑,窗口弹出/切换的逻辑在CommonUI_BaseLayer里,CommonUI_BaseLayer通过变量引用了另外两个Common Activatable Widget
Activate和Deactivate
Activate Widget都干了些什么?
void UCommonActivatableWidget::ActivateWidget()
{
if (!bIsActive)
{
InternalProcessActivation();
}
}
void UCommonActivatableWidget::InternalProcessActivation()
{
UE_LOG(LogCommonUI, Verbose, TEXT("[%s] -> Activated"), *GetName());
bIsActive = true;
NativeOnActivated();
}
void UCommonActivatableWidget::NativeOnActivated()
{
if (ensureMsgf(bIsActive, TEXT("[%s] has called NativeOnActivated, but isn't actually activated! Never call this directly - call ActivateWidget()")))
{
if (bSetVisibilityOnActivated)
{
SetVisibility(ActivatedVisibility);
UE_LOG(LogCommonUI, Verbose, TEXT("[%s] set visibility to [%s] on activation"), *GetName(), *StaticEnum<ESlateVisibility>()->GetDisplayValueAsText(ActivatedVisibility).ToString());
}
if (CommonUI::IsEnhancedInputSupportEnabled() && InputMapping)
{
if (const ULocalPlayer* LocalPlayer = GetOwningLocalPlayer())
{
if (UEnhancedInputLocalPlayerSubsystem* InputSystem = LocalPlayer->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>())
{
InputSystem->AddMappingContext(InputMapping, InputMappingPriority);
}
}
}
BP_OnActivated();
OnActivated().Broadcast();
BP_OnWidgetActivated.Broadcast();
}
}
UPROPERTY(EditAnywhere, Category = Activation, meta = (InlineEditConditionToggle = "ActivatedVisibility"))
bool bSetVisibilityOnActivated = false;
在每个Common Activatable Widget
可以通过Activated Visibility
以及Dezctivated Visibility
来定义该Common Activatable Widget
被激活/取消激活时的可见性行为
可见性绑定
/**
* Visibilities to use for when bound widgets in BindVisibilityToActivation are activated.
*
* @param OnActivatedVisibility - Visibility for when bound widgets are active
* @param OnDeactivatedVisibility - Visibility for when bound widgets are not active, not used if this widget has activation / deactivation visibilities
* @param bInAllActive - True if we should switch to activated visibility only when all bound widgets are active
*/
void UCommonActivatableWidget::SetBindVisibilities(ESlateVisibility OnActivatedVisibility, ESlateVisibility OnDeactivatedVisibility, bool bInAllActive)
{
ActivatedBindVisibility = OnActivatedVisibility;
DeactivatedBindVisibility = OnDeactivatedVisibility;
bAllActive = bInAllActive;
}
/**
* Bind our visibility to the activation of another widget, useful for making mouse collisions behave similiar to console navigation w.r.t activation
* Will immediately update visibility based on the bound widget activation & visibilites set by SetBindVisibilities.
*
* @param ActivatableWidget - The widget whose activation / deactivation will modify our visibility
*/
void UCommonActivatableWidget::BindVisibilityToActivation(UCommonActivatableWidget* ActivatableWidget)
{
if (ActivatableWidget && !VisibilityBoundWidgets.Contains(ActivatableWidget))
{
VisibilityBoundWidgets.Add(ActivatableWidget);
ActivatableWidget->OnActivated().AddUObject(this, &UCommonActivatableWidget::HandleVisibilityBoundWidgetActivations);
ActivatableWidget->OnDeactivated().AddUObject(this, &UCommonActivatableWidget::HandleVisibilityBoundWidgetActivations);
HandleVisibilityBoundWidgetActivations();
}
}
UI动画
动画播放及用动画触发UI切换
设置Common Activatable Widget的默认焦点
覆盖BP_FetDesiredFocusTarget