-
Notifications
You must be signed in to change notification settings - Fork 14
Visibility Component Propagation Handling
The SDK contains a component called VisibilityComponent (manual usage here, protocol here), that component allows creators to toggle the visibility of a specific Entity in its scene.
Since the introduction of the PropagateToChildren property for that component, certain rules start to apply in regards to visibility propagation.
Implementation PR: https://github.com/decentraland/unity-explorer/pull/6442
flowchart TD
subgraph SDKInput [SDK Input Layer]
PBVis[PBVisibilityComponent]
end
subgraph PropagationLayer [Propagation Layer]
PropSys[VisibilityPropagationSystem]
ResolvedVis[ResolvedVisibilityComponent]
end
subgraph RenderLayer [Render Layer]
VisBase[VisibilitySystemBase]
Primitives[PrimitivesVisibilitySystem]
Gltf[GltfContainerVisibilitySystem]
Text[VisibilityTextShapeSystem]
Nft[VisibilityNftShapeSystem]
end
PBVis --> PropSys
PropSys --> ResolvedVis
ResolvedVis --> VisBase
VisBase --> Primitives
VisBase --> Gltf
VisBase --> Text
VisBase --> Nft
- Entity's own
PBVisibilityComponentalways takes priority - If no own component, inherit from nearest ancestor with
PropagateToChildren=true - If no propagating ancestor, default to visible (true)
- Visibility must be updated whenever hierarchy, parent component or own component changes
- Child has own
VisibilityComponent-> Own component takes priority, skip in propagation - Child's
VisibilityComponentremoved -> Re-inherit from parent hierarchy - Child has own component +
propagateToChildren=TRUE-> Child's propagation takes over for grandchildren (blocks ancestor) - Child has own component +
propagateToChildren=FALSE-> "Pass-through": grandchildren inherit from ancestor, not child - Reparented under non-propagating hierarchy -> Reset to visible
- Reparented under propagating hierarchy (already had
ResolvedVisibility) -> Inherit new parent's visibility - Reparented under propagating hierarchy (never had
ResolvedVisibility) -> CreateResolvedVisibilityand inherit from new parent - Reparented entity has children -> Propagate visibility to all descendants of reparented entity
- Reparented under pass-through parent -> Walk up hierarchy to find propagating ancestor
- Parent's
PBVisibilityComponentremoved -> Children reset to visible
Screen.Recording.2025-12-18.at.1.48.02.AM.mp4
Key fields:
-
ShouldPropagate- When reparenting, check if new parent's resolved visibility should cascade -
LastKnownParent- Compare withTransformComponent.Parentto detect reparenting without modifying ParentingTransformSystem
Must run AFTER ParentingTransformSystem (so parent relationships are already updated)
Use of SDKTransform.IsDirty as a filter to avoid checking every frame, this is efficient because:
-
SDKTransform.IsDirtyfilters to only entities with transform changes - Quick
LastKnownParentcomparison filters out position/rotation/scale-only changes - Only actual reparenting triggers visibility recomputation
- Query to use
ResolvedVisibilityComponent(primary) - Keep fallback to direct
PBVisibilityComponentfor backwards compatibility
flowchart LR
A[ParentingTransformSystem] --> B[VisibilityPropagationSystem]
B --> C[ComponentInstantiationGroup]
C --> D[PrimitivesVisibilitySystem]
C --> E[GltfContainerVisibilitySystem]
C --> F[VisibilityTextShapeSystem]
D --> G[ResetDirtyFlagSystem]
E --> G
F --> G
Key ordering: VisibilityPropagationSystem must be [UpdateAfter(typeof(ParentingTransformSystem))] so parent relationships are established before we check for reparenting.