UE4 SetVisibility()和SetHiddenInGame()的比较

UE4的SetVisibility()功能更全面,能隐藏包括SceneComponent和UI组件在内的多种元素,而SetHiddenInGame()仅限于隐藏SceneComponent。在实际场景中,两者都能处理可见性问题,但对于SWidget、SPanel、UWidget等,只能使用SetVisibility()来控制其可见性。在SceneComponent内部,两者实现效果接近。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

区别与联系:SetVility()实现的更加广泛一些,而SetHiddenInGame()则是只在SceneComponent中有实现,意味着SetHiddenInGame()只能隐藏SceneComponent。SetVisibility()可以隐藏包括SceneComponent在内的很多东西(如UI组件)。一般来说能在场景中显示(看的见的)物体,都有SceneComponent,两种方法都可以达到目的,但是如果是一些SWeiget,SPanel,UWeiget等就只能通过SetVisibility()来做。
另外,在SceneComponent中两种方法的实现几乎是相同的。
void USceneComponent::SetVisibility(const bool bNewVisibility, const USceneComponent::EVisibilityPropagation PropagateToChildren)
{
    bool bRecurseChildren = (PropagateToChildren == EVisibilityPropagation::Propagate);
    if ( bNewVisibility != GetVisibleFlag() )
    {
        bRecurseChildren = bRecurseChildren || (PropagateToChildren == EVisibilityPropagation::DirtyOnly);
        SetVisibleFlag(bNewVisibility);
        OnVisibilityChanged();
    }

    const TArray<USceneComponent*>& AttachedChildren = GetAttachChildren();
    if (bRecurseChildren && AttachedChildren.Num() > 0)
    {
        // fully traverse down the attachment tree
        // we do it entirely inline here instead of recursing in case a primitivecomponent is a child of a non-primitivecomponent
        TInlineComponentArray<USceneComponent*, NumInlinedActorComponents> ComponentStack;

        // prime the pump
        ComponentStack.Append(AttachedChildren);

        while (ComponentStack.Num() > 0)
        {
            USceneComponent* const CurrentComp = ComponentStack.Pop(/*bAllowShrinking=*/ false);
            if (CurrentComp)
            {
                ComponentStack.Append(CurrentComp->GetAttachChildren());

                if (PropagateToChildren == EVisibilityPropagation::Propagate)
                {
                    CurrentComp->SetVisibility(bNewVisibility, EVisibilityPropagation::NoPropagation);
                }

                // Render state must be dirtied if any parent component's visibility has changed. Since we can't easily track whether 
                // any parent in the hierarchy was dirtied, we have to mark dirty always.
                CurrentComp->MarkRenderStateDirty();
            }
        }
    }
}
void USceneComponent::SetHiddenInGame(const bool bNewHiddenGame, const USceneComponent::EVisibilityPropagation PropagateToChildren)
{
    bool bRecurseChildren = (PropagateToChildren == EVisibilityPropagation::Propagate);
    if ( bNewHiddenGame != bHiddenInGame )
    {
        bRecurseChildren = bRecurseChildren || (PropagateToChildren == EVisibilityPropagation::DirtyOnly);
        bHiddenInGame = bNewHiddenGame;
        OnHiddenInGameChanged();
    }

    const TArray<USceneComponent*>& AttachedChildren = GetAttachChildren();
    if (bRecurseChildren && AttachedChildren.Num() > 0)
    {
        // fully traverse down the attachment tree
        // we do it entirely inline here instead of recursing in case a primitivecomponent is a child of a non-primitivecomponent
        TInlineComponentArray<USceneComponent*, NumInlinedActorComponents> ComponentStack;

        // prime the pump
        ComponentStack.Append(AttachedChildren);

        while (ComponentStack.Num() > 0)
        {
            USceneComponent* const CurrentComp = ComponentStack.Pop(/*bAllowShrinking=*/ false);
            if (CurrentComp)
            {
                ComponentStack.Append(CurrentComp->GetAttachChildren());

                if (PropagateToChildren == EVisibilityPropagation::Propagate)
                {
                    CurrentComp->SetHiddenInGame(bNewHiddenGame, EVisibilityPropagation::NoPropagation);
                }

                // Render state must be dirtied if any parent component's visibility has changed. Since we can't easily track whether 
                // any parent in the hierarchy was dirtied, we have to mark dirty always.
                CurrentComp->MarkRenderStateDirty();
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值