|
|
|
 |
Reply From: |
timothybrentwood |
There’s the propagate_call()
function which will call a function on a node and its children, otherwise you can add all of the nodes in a chunk to a group then use call_group()
. Note that both of those things are roughly the equivalent of looping over all of them. I’m not aware of anything analogous to disabling visibility on the physics side.
If you’re still experiencing stuttering issues you may want to consider spinning up a thread to do the work so you don’t block the main thread. I think your approach of disabling the processing should clear up your stuttering though.
Interacting directly with the PhysicsServer
object is useful for making highly optimized physics related changes at runtime. It’s a little more involved than just interacting with nodes but I’ve read that it’s significantly faster.
Thanks I may try and go the PhysicsServer route. There’s hardly any stutter now that I moved to hiding/showing chunks but on weaker devices there’s consistent lower frame rates. If I can cull the physics objects in a fast way, I hope to gain at least a few fps. The map is 36x580 so 20,880 children tiles 
Oh wow, yeah that is a lot of objects. I would recommend interacting with the PhysicsServer
in a new thread so you don’t get any stuttering. There’s also an analogous VisualServer
so you can show/hide faster as well (you might not get significant performance improvements there).
You could also break up how you you process the chunks over multiple frames too:
var nodes_to_process : Array
export var nodes_per_frame : int = 100
func initiate_process():
nodes_to_process = get_children()
process_node_chunk()
func process_node_chunk():
if nodes_to_process:
var nodes_this_frame : Array
var end_of_array = nodes_to_process.size() - 1
if nodes_per_frame < end_of_array:
nodes_this_frame = nodes_to_process.slice(0, nodes_per_frame - 1)
nodes_to_process = nodes_to_process.slice(nodes_per_frame, end_of_array)
else:
nodes_this_frame = nodes_to_process
nodes_to_process = []
process_nodes(nodes_this_frame)
call_deferred("process_node_chunk")
func process_nodes(nodes : Array):
var flag = not nodes[0].visible
for node in nodes:
node.visible = flag
node.set_physics_process(flag)
timothybrentwood | 2021-12-07 17:46
I think I’m just gonna let it be for now and see if the performance needs more optimization after adding other areas of the game since further than visibility culling is not very trivial. Without using PhysicsServer
, one thing I think I could do is make each chunk a StaticBody2D
and add all the tile collision shapes as children. At the moment each chunk is a Node2D
with StaticBody2D
tile children.
I see. I haven’t personally interacted with the PhysicsServer
directly but I have read about how it’s very fast from the contributors.
I’d suggest trying my code out. I think the stutter is happening because you’re trying to do too much in one frame. Dividing the work out over multiple frames should remove that stutter. Play around with increasing/decreasing nodes_per_frame
until you eliminate the stutter. If you can’t eliminate the stutter while maintaining the desired behavior of your game, you’ll likely need to create a new thread to handle the work.
https://docs.godotengine.org/en/stable/tutorials/threads/using_multiple_threads.html
timothybrentwood | 2021-12-08 01:45
I got rid of the stutter by just switching back to keeping the children instanced and toggling visibility. It results in a little bit worse constant performance but it’s definitely playable. But there’s a lot more to add to the game and those performance losses might add up in the end and I’ll need to look back into this. It’s for the OUYA game console lol so hardware limitations are a big deal.