[SCENE GRAPH VERSE] Mesh entered and exited event doesn't work with a var mesh_component unless looped

Summary

When a var mesh_comonent is used for EntityEnteredEvent and EntityExitedEvent, these events stop getting called when the var mesh_component is changed unless the events are looped however, when these are looped, the event gets called too much and logic is broken

Please select what you are reporting on:

Verse

What Type of Bug are you experiencing?

Verse

Steps to Reproduce

Create this setup:

if. var Mesh : mesh_component = E.GetComponent[mesh_component] then:
    Mesh.EntityEnteredEvent.Subscribe(Function1)
    Mesh.EntityExitedEvent.Subscribe(Function2)

    NewEntity := entity{}
    MeshComp := NEWMESH:
         Entity := NewEntity, Material := AMaterial
    set CompArray = array {MeshComp}

    ChildEntities : []component = E.GetComponents()
    for (Index := 0..ChildEntities.Length -1):
         if. Child := ChildEntities[Index]
         then. Child.RemoveFromEntity()

     E.AddComponents(CompArray)

    SpawnedMeshComp := E.FindDescendantComponents(mesh_component)
    for (MeshComponent : SpawnedMeshComp):
        set SpawnedMesh = MeshComponent

Expected Result

The subscribable EntityEnteredEvent and EntityExitedEvent events continue to fire even after the mesh is changed from its original

Observed Result

The events are not fired after the mesh is changed

Platform(s)

Any

Additional Notes

looping the events does get them to update but this can’t be used as the event ends up being fired too many times

Wouldn’t it then be a new mesh though ? i dnt understand your thinking in this.

I personally use Awaits() on the mesh_component so i dnt think i would have this issue

Forgot to include the part where i set the var, sorry

SpawnedMeshComp := E.FindDescendantComponents(mesh_component)
for (MeshComponent : SpawnedMeshComp):
    set SpawnedMesh = MeshComponent

Thank you for bringing this to our attention. After reviewing with the team, we believe this behavior is working as intended. Since a mesh_component is being removed and a new one added, you’ll need to re-subscribe to the Entity Entered event. Please let us know if that doesn’t resolve your issue, we’ll be happy to take another look. Thanks again

My issue is that if I resubscribe it, because its in a loop in the logic I’m actually using, when the event is fired, it fires multiple times and messes with logic, if there is a way to prevent this I would love to know. I would also argue that because it’s using a var, it should automatically resubscribe when the var changes as it just makes sense. I’ll send the whole function I’m using (I’m new to SG so it might not be the best code):

        if. SimEntity := Entity.GetSimulationEntity[] then:
            var SpawnedPrefab : entity = entity{}
            set PreivewEntity = SpawnedPrefab
            SimEntity.AddEntities(array{SpawnedPrefab})
            if (AttributeMap[Agent].BuildMode = false):
                spawn. OnTriggerEntered(Agent)
                if. set AttributeMap[Agent].BuildMode = true
                var CompArray : []component = array {}
                StartEntity := entity{}
                SMeshComp := Meshes.Building1:
                    Entity := StartEntity, Material := PreviewMaterial
                STransComp := transform_component:
                    Entity := StartEntity
                SKeyFrameComp := keyframed_movement_component:
                    Entity := StartEntity
                set CompArray = array {SMeshComp, STransComp, SKeyFrameComp}
                SChildEntities : []component = SpawnedPrefab.GetComponents()
                for (Index := 0..SChildEntities.Length -1):
                    Sleep(0.01)
                    if. Child := SChildEntities[Index]
                    then. Child.RemoveFromEntity()

                SpawnedPrefab.AddComponents(CompArray)
                

                if. var SpawnedMesh : mesh_component = PreivewEntity.GetComponent[mesh_component] then:
                    SpawnedMesh.EntityEnteredEvent.Subscribe(OverlapEnterHandler)
                    SpawnedMesh.EntityExitedEvent.Subscribe(OverlapExitHandler)
                    loop:
                        Sleep(0.0001)
                        NewEntity := entity{}
                        if. DeleteMode = true and SelectedBuild <> 0 then:
                            Print("DeleteMode")
                            set SelectedBuild = 0

                            MeshComp := Meshes.Cylinder:
                                Entity := NewEntity, Material := DeleteMaterial
                            TransComp := transform_component :
                                Entity := NewEntity
                            KeyFrameComp := keyframed_movement_component:
                                Entity := NewEntity
                            set CompArray = array {MeshComp, TransComp, KeyFrameComp}
                            ChildEntities : []component = SpawnedPrefab.GetComponents()
                            for (Index := 0..ChildEntities.Length -1):
                                Sleep(0.01)
                                if. Child := ChildEntities[Index]
                                then. Child.RemoveFromEntity()

                            SpawnedPrefab.AddComponents(CompArray)

                        else. if. DeleteMode = false and SelectedBuild <> 1 then:
                            Print("PlaceMode")
                            set SelectedBuild = 1



                            MeshComp := Meshes.Building1:
                                Entity := NewEntity, Material := PreviewMaterial
                            TransComp := transform_component:
                                Entity := NewEntity
                            KeyFrameComp := keyframed_movement_component:
                                Entity := NewEntity
                            set CompArray = array {MeshComp, TransComp, KeyFrameComp}
                            ChildEntities : []component = SpawnedPrefab.GetComponents()
                            for (Index := 0..ChildEntities.Length -1):
                                Sleep(0.01)
                                if. Child := ChildEntities[Index]
                                then. Child.RemoveFromEntity()

                            SpawnedPrefab.AddComponents(CompArray)

                        SimEntity.AddEntities(array{SpawnedPrefab})
                        set PreivewEntity = SpawnedPrefab


                        SpawnedMeshComp := PreivewEntity.FindDescendantComponents(mesh_component)
                        for (MeshComponent : SpawnedMeshComp):
                            set SpawnedMesh = MeshComponent
                        if. MovementComponent := SpawnedPrefab.GetComponent[keyframed_movement_component] then:
                            Transform := (/Verse.org/SpatialMath:)transform:
                                Translation := SpawnLocation.Translation - SpawnedPrefab.GetGlobalTransform().Translation
                                Scale := (/Verse.org/SpatialMath:)vector3{ Left := 0.0, Up := 0.0, Forward := 0.0 }
                                Rotation := CalculateRotationDelta(SpawnedPrefab.GetGlobalTransform().Rotation, SpawnLocation.Rotation)
                                
                            Keyframe := keyframed_movement_delta:
                                Transform := Transform
                                Duration := 0.1
                                Easing := linear_easing_function{}
                            MovementComponent.SetKeyframes(array{ Keyframe }, oneshot_keyframed_movement_playback_mode{})
                            MovementComponent.Play()
                            if. AttributeMap[Agent].BuildMode = false then:
                                SpawnedPrefab.RemoveFromParent()
                                PreivewEntity.RemoveFromParent()
                                set UnplaceableEntitiesInMesh = 0
                                set DestroyableEntitiesInMesh = 0
                                set ContactDestructionEntitiesInMesh = 0
                                set LandscapeEntitiesInMesh = 0
                                set DeletableEntitiesInMesh = 0
                                break

            else:
                if. set AttributeMap[Agent].BuildMode = false
                set DeleteMode = false
                SpawnedPrefab.RemoveFromParent()
                PreivewEntity.RemoveFromParent()
                ChildEntities : []component = SpawnedPrefab.GetComponents()
                        for (Index := 0..ChildEntities.Length -1):
                            Sleep(0.01)
                            if. Child := ChildEntities[Index]
                            then. Child.RemoveFromEntity()
                        return

FORT-953899 has been ‘Closed’. The issue reported is not caused by a bug in the tool.

Thanks for sharing the details of your setup. The behavior you’re seeing is expected given how the system works: when the underlying component is replaced, the old instance is destroyed and a brand-new one is instantiated. Because of this, any event subscriptions tied to the previous instance are no longer valid, which is why you need to resubscribe to the event on the new component.