Unreal UMG 如果你对获取某个Widget的子节点数量不对,发现少了,有些子节点没获取到,可以注意一下这个下述方法。 GetChildWidgets,GetAllWidgets等获取的数量不对的情况。 下述是UMG遍历子节
Unreal UMG 如果你对获取某个Widget的子节点数量不对,发现少了,有些子节点没获取到,可以注意一下这个下述方法。
GetChildWidgets,GetAllWidgets等获取的数量不对的情况。
下述是UMG遍历子节点的实现代码
void UWidgetTree::ForWidgetAndChildren(UWidget* Widget, TFunctionRef<void(UWidget*)> Predicate)
{
// Search for any named slot with content that we need to dive into.
if ( INamedSlotInterface* NamedSlotHost = Cast<INamedSlotInterface>(Widget) )
{
TArray<FName> SlotNames;
NamedSlotHost->GetSlotNames(SlotNames);
for ( FName SlotName : SlotNames )
{
if ( UWidget* SlotContent = NamedSlotHost->GetContentForSlot(SlotName) )
{
Predicate(SlotContent);
ForWidgetAndChildren(SlotContent, Predicate);
}
}
}
// Search standard children.
if ( UPanelWidget* PanelParent = Cast<UPanelWidget>(Widget) )
{
for ( int32 ChildIndex = 0; ChildIndex < PanelParent->GetChildrenCount(); ChildIndex++ )
{
if ( UWidget* ChildWidget = PanelParent->GetChildAt(ChildIndex) )
{
Predicate(ChildWidget);
ForWidgetAndChildren(ChildWidget, Predicate);
}
}
}
}
上述代码中我们知道大概的意思,获取凡是继承自UPanelWidget,或者实现了INamedSlotInterface的。
Unreal中大量组件是没有继承自UPanelWidget的。所以就会遇到很多时候获取的子节点数量少了的情况。
例如:
class UMG_API UListViewBase : public UWidget
class UMG_API UDynamicEntryBoxBase : public UWidget
所以上述组件默认是肯定遍历不到的,这也是为啥获取子节点没有达到自己预期的数量,那么Unreal给出的解决办法是实现INamedSlotInterface。
可以参考下述实现方案:
// ListView
void UListViewBase::GetSlotNames(TArray<FName>& SlotNames) const
{
for (UWidget* Binding : GetDisplayedEntryWidgets())
{
SlotNames.Add(Binding->GetFName());
}
}
UWidget* UListViewBase::GetContentForSlot(FName SlotName) const
{
for (UWidget* Binding : GetDisplayedEntryWidgets())
{
if (Binding->GetFName() == SlotName)
{
return Binding;
}
}
return nullptr;
}
// DynamicEntryBox
void UDynamicEntryBoxBase::GetSlotNames(TArray<FName>& SlotNames) const
{
for (const UWidget* Binding : GetAllEntries())
{
SlotNames.Add(Binding->GetFName());
}
}
UWidget* UDynamicEntryBoxBase::GetContentForSlot(FName SlotName) const
{
for (UWidget* Binding : GetAllEntries())
{
if (Binding->GetFName() == SlotName)
{
return Binding;
}
}
return nullptr;
}
GetChildWidgets,GetAllWidgets 底层实现依赖于ForWidgetAndChildren。
该文章就是UMG获取子节点数量不对的原因&解决办法。