SetPresentableToPlayers inconsistent across multiple entities with the same component

Summary

SetPresentableToPlayers appears to silently fail on some entities when called across multiple entities with the same component attached, causing those entities to remain visible to all players regardless of the visibility list passed in.

Please select what you are reporting on:

Verse

What Type of Bug are you experiencing?

Verse

Steps to Reproduce

  1. Create a new empty UEFN project

  2. Create two simple static mesh assets (e.g. a Box and a Cone)

  3. Create a Verse component that on simulate spawns two child entities, attaches one mesh to each, hides both via SetPresentableToPlayers(option{array{}}) on init, then toggles their per-player visibility every 5 seconds using a player list tracked manually

  4. Place 8-10 empty entities in the level and add the component to each one

  5. Observe that some entities consistently show both meshes at the same time instead of only the correct one, the specific affected entities can vary between sessions or after pushing changes but there are always some that are broken


using { /Verse.org/SceneGraph }
using { /Verse.org/Simulation }
using { /Fortnite.com/Playspaces }
using { /Verse.org/SpatialMath }

Test component that spawns two meshes and toggles their per-player visibility

presentable_test := class<final_super>(component):

# Stored references to the two spawned entities
var MaybeMesh1Entity : ?entity = false
var MaybeMesh2Entity : ?entity = false

# Per-player visibility tracking lists for each mesh
var Mesh1Players : []player = array{}
var Mesh2Players : []player = array{}

OnSimulate<override>()<suspends> : void =
    (super:)OnSimulate()

    # Create two blank entities to attach meshes to
    EntityA := entity{}
    EntityB := entity{}

    # Attach a different mesh to each entity
    MeshA := Meshes.Box{Entity := EntityA}
    MeshB := Meshes.Cone{Entity := EntityB}
    EntityA.AddComponents(array{MeshA})
    EntityB.AddComponents(array{MeshB})

    # Add both entities to the scene at this component's position
    XForm := Entity.GetGlobalTransform()
    Entity.AddEntities(array{EntityA, EntityB})
    EntityA.SetGlobalTransform(XForm)
    EntityB.SetGlobalTransform(XForm)

    set MaybeMesh1Entity = option{EntityA}
    set MaybeMesh2Entity = option{EntityB}

    # Hide both meshes from everyone on init
    set Mesh1Players = array{}
    set Mesh2Players = array{}
    EntityA.SetPresentableToPlayers(option{Mesh1Players})
    EntityB.SetPresentableToPlayers(option{Mesh2Players})

    # Wait before starting the toggle loop so the hidden state is visible
    Sleep(10.0)

    # Toggle between State1 and State2 every 5 seconds for all players
    loop:
        # State2: Mesh1 hidden, Mesh2 visible
        if (Playspace := Entity.GetPlayspaceForEntity[]):
            for (Agent : Playspace.GetParticipants()):
                ShowState2(Agent)
        Print("presentable_test: State2 | Mesh1={Mesh1Players.Length} Mesh2={Mesh2Players.Length}")

        Sleep(5.0)

        # State1: Mesh1 visible, Mesh2 hidden
        if (Playspace := Entity.GetPlayspaceForEntity[]):
            for (Agent : Playspace.GetParticipants()):
                ShowState1(Agent)
        Print("presentable_test: State1 | Mesh1={Mesh1Players.Length} Mesh2={Mesh2Players.Length}")

        Sleep(5.0)

OnEndSimulation<override>() : void =
    (super:)OnEndSimulation()
    # Clean up entities from the scene on end
    if (Ent := MaybeMesh1Entity?) then Ent.RemoveFromParent()
    if (Ent := MaybeMesh2Entity?) then Ent.RemoveFromParent()

# Hides Mesh1 and shows Mesh2 for the given agent
ShowState2(Agent : agent) : void =
    if (Player := player[Agent]):
        if (Ent1 := MaybeMesh1Entity?):
            set Mesh1Players = for (P : Mesh1Players, P <> Player) do P
            Ent1.SetPresentableToPlayers(option{Mesh1Players})
        if (Ent2 := MaybeMesh2Entity?):
            var AlreadyIn : logic = false
            for (P : Mesh2Players, P = Player):
                set AlreadyIn = true
            if (AlreadyIn = false):
                set Mesh2Players += array{Player}
            Ent2.SetPresentableToPlayers(option{Mesh2Players})

# Shows Mesh1 and hides Mesh2 for the given agent
ShowState1(Agent : agent) : void =
    if (Player := player[Agent]):
        if (Ent1 := MaybeMesh1Entity?):
            var AlreadyIn : logic = false
            for (P : Mesh1Players, P = Player):
                set AlreadyIn = true
            if (AlreadyIn = false):
                set Mesh1Players += array{Player}
            Ent1.SetPresentableToPlayers(option{Mesh1Players})
        if (Ent2 := MaybeMesh2Entity?):
            set Mesh2Players = for (P : Mesh2Players, P <> Player) do P
            Ent2.SetPresentableToPlayers(option{Mesh2Players})

Expected Result

Each instance toggles correctly, only showing one mesh at a time per player.

Observed Result

Some entities show both meshes at the same time, the visibility calls appear to have no effect on them.

Platform(s)

PC

Video