Scene Graph Feedback Thread

Simulate Play in the scene graph world (at least) would be huge. To be able to test simple movement like a lantern swaying without having to wait one minute for a server push every time would be a huge workflow improvement.

1 Like

I think it would make sense to have an onDestroy subscribable on the component base class.

There really are a couple of design flaws with spawn on components right now.

component_a := class(component):
    ComponentB: component_b
    OnSimulate<override>()<suspends>: void =
        ComponentB.DoSomething()

component_b := class(component):
    DoSomething<public>(): void =
        spawn{SomeLoop()}
    SomeLoop<private>()<suspends>: void =
        loop:
            Print("Tick")
            Sleep(0.0)

When will task for SomeLoop be cancelled?

  • never, it will keep running
  • when ComponentA is disposed or detached
  • when ComponentB is disposed or detached
  • something else

The answer is, that the task spawned in a method of component_b is being cancelled when component_a leaves the scene. I could easily mention several cases that show that this implicit component ownership is cursed.

Let’s say we have a player and a npc. The npc freezes the player (just an example task) and then dies/despawns in the meantime. That freeze would just cancel, even tho it is not supposed to be like that.

Or imagine a turret spawning a projectile and spawning a task that makes the bullet follow a specific object. If the turret is being destroyed, that task would be canceled and the bullet would stop moving (which doesn’t make any sense at all).

This basically makes very little sense from a design perspective. Tasks/spawn{} should not depend on a random component. IF you want to have tasks that are dependent on a component, do not make it this way. Make it explicit, like component.Spawn(Callback, Args), which then makes every programmer aware of what the resulting task is tied to.

Here is my convoluted workaround for reference because there is no way that i will ever use spawn{} again the way it currently is:

    component_task_base<public> := class<abstract><unique>:
        var Finished: logic = false

        Run()<suspends>: void
        Cancel<public>(): void
        Await<public>()<suspends>: ?any
            
    component_task(args_type: type, res_type: type) := class(component_task_base):
        Callback: type{__(:args_type)<suspends>: res_type}
        Args: args_type

        CancelEvent: event() = event(){}
        FinishedEvent: event(?res_type) = event(?res_type){}

        Run<override>()<suspends>: void =
            if (Finished?):
                false
            else:
                MaybeResult: ?res_type = race:
                    block:
                        Result := Callback(Args)
                        set Finished = true
                        option. Result
                    block:
                        CancelEvent.Await()
                        false
                FinishedEvent.Signal(MaybeResult)
        Cancel<override>(): void =
            CancelEvent.Signal()
            set Finished = true
        Await<override>()<suspends>: ?res_type =
            if (Finished?):
                false
            else:
                FinishedEvent.Await()

    advanced_component<public> := class(component):
        var TickHandle<private>: ?cancelable = false
        var QueuedTasks<private>: []component_task_base = array{}

        Spawn<public>(Callback(:args_type)<suspends>: res_type, Args: args_type where args_type: type, res_type: type): component_task_base =
            ComponentTask := component_task(args_type, res_type):
                Callback := Callback
                Args := Args

            set QueuedTasks += array. ComponentTask
            if (not TickHandle?):
                Handle := TickEvents.PostPhysics.Subscribe(SpawnTasksFromQueue)
                set TickHandle = option. Handle
            ComponentTask

        SpawnTasksFromQueue<private>(:any): void =
            for (TaskInfo: QueuedTasks, TaskInfo.Finished = false):
                spawn{TaskInfo.Run()}
            set QueuedTasks = array{}
            if (TickHandle?.Cancel()):
                set TickHandle = false

This is not a perfect solution and i wish there would be some official API for this instead, but here is some example usage:

component_a := class(advanced_component):
    ComponentB: component_b
    OnSimulate<override>()<suspends>: void =
        ComponentB.DoSomething()

component_b := class(advanced_component):
    DoSomething<public>(): void =
        Spawn(SomeLoop, ()) #This will not be randomly canceled when ComponentA is detached and is *properly* owned by ComponentB instead.
    SomeLoop<private>()<suspends>: void =
        loop:
            Print("Tick")
            Sleep(0.0)

Also for anyone that uses this code, feel free to enjoy a very nice feature, that task fails to provide called “Cancel”…

It would be nice if they changed the concept of “actor classes” or “Entities” for “DEVICE classes with events” to take advantage of the entire CREATIVE class system WITHIN UNREAL ENGINE, this has 2 benefits, unreal developers learn to use unreal devices and within unreal we have the entire class system of the devices, using the inheritance and event system of each type of class.




The system of events associated with the class type is very important in an engine. In this way, with a simple button like with BP, you can create an enter trigger or any event and think directly about what that class was made for.
If you use components regardless of the class type, you will break that and you will get rid of that way of thinking that for me is the best thing about Unreal and Godot.



So the device classes would have packaged functionalities, but above all the event system, which is very good and is very similar to the Godot signal system, for me 80% of the work is how the engine handles the game events, a trigger enter, a mouse enter, etc…

We could even have all of Fortnite in Unreal and we could use it within our game.

This would be like Godot’s reusable nodes with signals and script, but much more powerful, because creative devices have much more complex and practical functionalities…

So having that concept inside the engine would help to be able to create assets that would be DEVICE and could be reused with entities and would have a whole system of events associated with the class system, which is essential to improve and make the development of a complex game easier.

To summarize: A device that can inherit from Verse Script with an event system associated with the class system and within them they can have entities with components and those components can also be seen as a script… That would be having the best of Godot, Unity and Unreal in a single engine.

So:
a godot node is a type of class.
an unreal Device is a type of class
Captura de pantalla 2024-07-28 164048

This way you can reuse the entire unreal class system, use inheritance which is so important within unreal and make the object hierarchy within entities make much more sense and be easier to read.

But don’t just stick to the godot concept, also use the Unity concept, so that you can also add components and component scripts to those “entities” DEVICE.
Captura de pantalla 2024-07-28 164617

Above all, not losing the ability to think about inheritance when we create actors, the ability to understand what we are doing, and also, if necessary, extend those functionalities packaged in a concept of classes with event and components.




Another concept that they have to add within the graphs are animations.
Look how godot handles the animations, in the nodes, it is having references to the scene objects.
I would love to have a level sequencer, so I can create prefab-based animations that I can call whenever, wherever and however I want, without depending on what is in the scene.

In this video you can see that I have the same instance many times and each one has a reference to an animation node that refers to the objects of that scene, I change a parameter in each one independently. That’s what I mean.

As a user of Unreal Engine for more than 3 years and Godot for more than 5 years, I would not like to lose the possibility of using inheritance in actors, having the entire system of events associated with the class type and not losing that way of thinking about actors and how they relate to reusable logic using inheritance.

I was also testing it and for some reason I couldn’t add a verse script component, it was buggy.

That’s my feedback that I can give you for now, but later I will tell you more things.
Sorry, if you don’t understand, my English is very bad, my native language is Spanish.

1 Like

Thanks @Daigoro. You’re absolutely correct. This is just an implementation detail but the Verse tasks are mapped to a set of “Verse context” objects within the engine. Looking through the scene graph code I think these are set up with far too fine a granularity, which is what causes the issues you’re highlighting. I’ve logged an issue internally to rethink how we’re scoping out and cancelling tasks related to the scene graph. My initial thinking is that we should just have one context for the whole scene graph, scoped at the Simulation Entity level. That way the only time tasks are cancelled is when we’re resetting the map, not when objects within the map come and go.

2 Likes

That’s a great idea totally in my favour. If you want to add tasks that are tied to components back in at a later point, then i guess it might be the best to just wait until we get lambda support for Verse and add a component.Spawn or entity.Spawn function, that takes a suspending lambda as argument.

Thanks for sharing some insight and have a nice day.

Hey all,

EDIT: I think I identified the issue! If I name the root entity first in a prefab, the error in the video below happens when I choose a mesh. I have to connect the mesh first to the generated name and then rename the entity. Did I miss this as an error somewhere? I know there is a renaming bug, but didn’t think that cascaded down to a component mesh add…

Posted this issue on the forums, a.k.a. it won’t let me add my custom mesh as a component and reverts back to a cube:

It turns out starting a new project and trying the exact same thing with the same .fbxs and it suddenly works as intended. The original project was not complex at all, a few dozen objects and a camera at most. So I don’t think it’s me doing something wrong as before… Can post this in bugs but figured the feedback thread may be better given the experimental tag.

Sorry for double dipping so quickly, but I have a separate feedback / request.

The game we’re developing is almost all diagetic:

We’ll need our diagetic UI to be moving with the camera, which is easily done with traditional UEFN outliner stuff by having our geo attached as children to the camera as seen in that clip…

Prefabs don’t attach to actors of course… Is it planned to have a camera entity in the future and/or an entity to be attached to a camera at any point?

Not sure how I can detect collision after I added collision components. There is no documentation available: [DOCUMENTATION] Missing documentation for all scene graph components

Could you provide a basic example? Or at least let us know how it should work top-level / in theory.

Collision detection capabilities for creators are not provided yet. Those are work in progress and very likely to be opened up together with the announcement of physics.

Is there a way that we can change the collision preset on the collision component?

Are there plans for Fortnite’s props to become integrated into scene graph? If so, is there an approximate timeline?

There is no way this feature will not take advantage of Fortnite’s massive library of assets. Maybe exposing all props read only static mesh component in verse, or making it accessible via a new mesh_component subclass (like the BasicShapes module) for instance?

1 Like

The wording from the the scene graph documentation page makes it seem like it is planned to be implemented, although for now they recommend to export fortnite assets and then add them into your project Scene Graph | Unreal Editor for Fortnite Documentation | Epic Developer Community

1 Like

For my games, scene graph will be rather transformative - we really wanted to start playing around with it even in experimental mode…

BUT a central mechanic/requirement is that we have a great deal of geo follow a cinematic camera around for a diegetic UI; scene graph doesn’t seem to allow for this.

My question is, will it allow for entities to attach to a camera or a camera to become an entity?

Anyone has any insight, it would be greatly appreciated as any answer would effect our current coding and development of our gaming series even if it isn’t out of experimental yet.

Thanks in advance.

I am wondering about performance regarding the Scene Graph. Once an entity has been turned into a prefab, will it be packed properly to account for performance, somewhat similar to a packed level actor. Basically, will the assets become instanced to reduce draw calls?

I’m currently exploring the Scene Graph and wondering if the Control Rig Component will be supported once it moves into beta

Has anyone found a workaround for handling animations and rigging within the Scene Graph in its current state?

@Incredulous_Hulk
With the beta release planned for Q1, are there any plans to announce what features/components will be part of the beta release?

Things I’d love to know about what is in the Beta (or request for future updates):

  • Damagable Component?
    - Missing feature currently with creative props where we don’t know who is hitting a specific prop.
  • Player/Agent as an Entity?
    - Will they trigger the overlap events?
    - The ability to parent meshes to players
  • Replication Component/Function
    - Much needed to feature to be something similar to a more versatile Switch device or replace the hundreds of cinematic sequencers we need for per player instigation and visuals
    - Per Player Visuals?
    - Per Player Collidable?
    - Per Player Interactable?
  • Text Render Component
    • This was removed in a recent patch. Will it be returned?
2 Likes

Add WINDOWS notifications with UEFN whenever someone on the team makes a change, so that it is easier to identify when there are changes in the project repository controlled by your version control included in UEFN. If you add some kind of script with discord to notify people, to a server, better