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
-
Create a new empty UEFN project
-
Create two simple static mesh assets (e.g. a Box and a Cone)
-
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
-
Place 8-10 empty entities in the level and add the component to each one
-
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