godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.13k stars 20.2k forks source link

`NavigationMesh` does not complete when running on main thread #77801

Closed tavurth closed 1 year ago

tavurth commented 1 year ago

Godot version

v4.0.3.stable.official [5222a99f5]

System information

Mac

Issue description

The following code will not print any vertices, nor polygons. The NavigationMesh resource will not be saved correctly.

Even though we specify bake_navigation_mesh(false) (on the main thread)

func _ready() -> void:
    var navreg = $NavigationRegion3D
    navreg.bake_navigation_mesh(false)

    print(navreg.navmesh.get_vertices())
    print(navreg.navmesh.get_polygon_count())

    var to_save = preload("res://testresource.gd").new(navreg.navmesh)
    ResourceSaver.save(
        to_save,
        "output.tres",
        ResourceSaver.SaverFlags.FLAG_BUNDLE_RESOURCES
    )

Steps to reproduce

  1. Download minimal repo below
  2. Run the repo
  3. Check the console
  4. Check output.tres
Screenshot 2023-06-03 at 19 05 22 Screenshot 2023-06-03 at 19 05 34

Minimal reproduction project

test-navmesh.zip

tavurth commented 1 year ago

Modifying the code thusly:

    navreg.bake_navigation_mesh(false)
    await get_tree().process_frame

Or by using the connect callback

@tool
extends Node3D

func _ready() -> void:
    var navreg = $NavigationRegion3D
    navreg.bake_navigation_mesh(false)
    navreg.connect("bake_finished", self._on_navigation_region_3d_bake_finished)

func _on_navigation_region_3d_bake_finished():
    var navreg = $NavigationRegion3D
    print(navreg.navmesh.get_vertices())
    print(navreg.navmesh.get_polygon_count())

    var to_save = preload("res://testresource.gd").new(navreg.navmesh)
    ResourceSaver.save(
        to_save,
        "output.tres",
        ResourceSaver.SaverFlags.FLAG_BUNDLE_RESOURCES
    )

And I see the following output as expected:

[(0.5, 0.625, -1.25), (-0.25, 0.625, -1.5), (-0.5, 0.625, -1), (-0.5, 0.625, 0), (0.5, 0.625, 0.25)]
3
Screenshot 2023-06-03 at 19 08 18
smix8 commented 1 year ago

NavigationRegion3D.bake_navigation_mesh() makes a deferred call to always finish on the main thread no matter what.

With the new thread-guards added in Godot 4 dev3 this is now more important than ever.