Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Needs documentation: NavigationServer will only update after 1 physics frame #57022

Closed
Xyotic opened this issue Jan 21, 2022 · 7 comments · Fixed by #61593
Closed

Needs documentation: NavigationServer will only update after 1 physics frame #57022

Xyotic opened this issue Jan 21, 2022 · 7 comments · Fixed by #61593

Comments

@Xyotic
Copy link

Xyotic commented Jan 21, 2022

Godot version

Godot 3.5-beta1_mono

System information

Windows 10, GLES3, RTX2080

Issue description

Edit: @smix8 noticed the issue was me not waiting for the physics frame to end.
See the solution in the comments. Changing the subject to "Needs documentation".

Setting a NavigationServer map to active via .MapSetActive() does not have any effect.
.MapIsActive() will always return false.

I used a pretty simple setup using C#:

    NavigationMesh navmesh;
    public override void _Ready()
    {
        navmesh = new NavigationMesh();
        navmesh.Vertices = new Vector3[]
        {
            new Vector3(0,0,0),
            new Vector3(9,0,0),
            new Vector3(0,0,9),
        };
        navmesh.AddPolygon(new int[] { 0, 1, 2 });

        NavigationServer.SetActive(true);
        var map = NavigationServer.MapCreate();
        var region1 = NavigationServer.RegionCreate();
        NavigationServer.MapSetUp(map, Vector3.Up);
        NavigationServer.RegionSetTransform(region1, Transform.Identity);
        NavigationServer.RegionSetNavmesh(region1, navmesh);
        NavigationServer.RegionSetMap(region1, map);
        NavigationServer.MapSetActive(map, true);

        GD.Print("Is active: " + NavigationServer.MapIsActive(map)); //Will return false

        var result = NavigationServer.MapGetPath(map, new Vector3(0.1f, 0, 0.1f), new Vector3(1f, 0, 1f), true);

        GD.Print("Found waypoints: " + result.Length);
    }

Steps to reproduce

Run the MRP in Godot 3.5 beta mono build.

Minimal reproduction project

NavigationServerTest.zip

@Calinou Calinou added this to the 3.5 milestone Jan 21, 2022
@smix8
Copy link
Contributor

smix8 commented May 13, 2022

@Xyotic

Can't run and test mono builds but here are a few things.

The NavigationServer is active by default as soon as it is created by Godot, no need to set it active again.

If a Map is created through NavigationServer API alone it needs to be created / registered and set activated afterward.

Any change like registering a map, a region or an agent, changing their transform ... takes time to sync as the NavigationServer runs on a different thread. Don't expect changes to be in effect immediately or a path to return on the same frame you setup all the regions and maps. You need to wait at least 1 physics tick for the NavigationServer sync and queue flush before changes can take place.

If possible please test again and verify. I think it is not a bug but a setup, documentation and expectation issue.

@Xyotic
Copy link
Author

Xyotic commented May 13, 2022

Thx for the reply!
Do you have a example how to set this up in gdscript?

@smix8
Copy link
Contributor

smix8 commented May 13, 2022

@Xyotic

var navmesh : NavigationMesh
func _ready():
	# use call deferred to make sure the entire SceneTree Nodes are setup
	# else if yield on 'physics_frame' in a _ready() sceneload might get stuck
	call_deferred("setup")


func setup():
	
	navmesh = NavigationMesh.new()
	var vertices : PoolVector3Array = PoolVector3Array([Vector3(0,0,0), Vector3(9.0,0,0), Vector3(0,0,9.0)])
	navmesh.set_vertices(vertices)
	var polygon : PoolIntArray = PoolIntArray([0, 1, 2])
	navmesh.add_polygon(polygon)
	
	var map : RID = NavigationServer.map_create()
	var region : RID = NavigationServer.region_create()
	
	NavigationServer.map_set_up(map, Vector3.UP)
	NavigationServer.map_set_active(map, true)
	
	NavigationServer.region_set_transform(region, Transform())
	NavigationServer.region_set_navmesh(region, navmesh)
	NavigationServer.region_set_map(region, map)
	
	# wait for NavigationServer sync to adapt to changes made
	yield(get_tree(),"physics_frame")
	
	var is_active : bool = NavigationServer.map_is_active(map)
	print("Is active: %s" % is_active)
	
	var path : PoolVector3Array = NavigationServer.map_get_path(map, Vector3(0.1, 0.0, 0.1), Vector3(1.0, 0.0, 1.0), true)
	
	print("Found waypoints:")
	print(path)

@smix8
Copy link
Contributor

smix8 commented May 19, 2022

@Xyotic
Could that solve the issue?

@Xyotic
Copy link
Author

Xyotic commented May 19, 2022

Will try it this weekend

@Xyotic
Copy link
Author

Xyotic commented May 23, 2022

@smix8 waiting for the physics frame to end did the trick!

For anyone curious, this it how it would look in C#

    NavigationMesh navmesh;
    public override void _Ready()
    {
        CallDeferred(nameof(Setup));
    }

    private async void Setup() 
    {
        navmesh = new NavigationMesh();
        navmesh.Vertices = new Vector3[]
        {
            new Vector3(0,0,0),
            new Vector3(9,0,0),
            new Vector3(0,0,9),
        };
        navmesh.AddPolygon(new int[] { 0, 1, 2 });

        var map = NavigationServer.MapCreate();
        var region1 = NavigationServer.RegionCreate();

        NavigationServer.MapSetUp(map, Vector3.Up);
        NavigationServer.MapSetActive(map, true);

        NavigationServer.RegionSetTransform(region1, Transform.Identity);
        NavigationServer.RegionSetNavmesh(region1, navmesh);
        NavigationServer.RegionSetMap(region1, map);

        await ToSignal(GetTree(), "physics_frame");

        var result = NavigationServer.MapGetPath(map, new Vector3(0.1f, 0, 0.1f), new Vector3(1f, 0, 1f), true);

        GD.Print("Found waypoints: " + result.Length);
        foreach (var r in result) GD.Print(r);
    }

@Xyotic Xyotic changed the title NavigationServer.MapSetActive() does not seem to work ~~NavigationServer.MapSetActive() does not seem to work~~ May 23, 2022
@Xyotic Xyotic changed the title ~~NavigationServer.MapSetActive() does not seem to work~~ N̶a̶v̶i̶g̶a̶t̶i̶o̶n̶S̶e̶r̶v̶e̶r̶.̶M̶a̶p̶S̶e̶t̶A̶c̶t̶i̶v̶e̶(̶)̶ ̶d̶o̶e̶s̶ ̶n̶o̶t̶ ̶s̶e̶e̶m̶ ̶t̶o̶ ̶w̶o̶r̶k̶ May 23, 2022
@Xyotic Xyotic changed the title N̶a̶v̶i̶g̶a̶t̶i̶o̶n̶S̶e̶r̶v̶e̶r̶.̶M̶a̶p̶S̶e̶t̶A̶c̶t̶i̶v̶e̶(̶)̶ ̶d̶o̶e̶s̶ ̶n̶o̶t̶ ̶s̶e̶e̶m̶ ̶t̶o̶ ̶w̶o̶r̶k̶ NavigationServer.MapSetActive() does not seem to work May 23, 2022
@Xyotic Xyotic changed the title NavigationServer.MapSetActive() does not seem to work ~NavigationServer.MapSetActive() does not seem to work~ May 23, 2022
@Xyotic Xyotic changed the title ~NavigationServer.MapSetActive() does not seem to work~ ̷N̷a̷v̷i̷g̷a̷t̷i̷o̷n̷S̷e̷r̷v̷e̷r̷.̷M̷a̷p̷S̷e̷t̷A̷c̷t̷i̷v̷e̷(̷)̷ ̷d̷o̷e̷s̷ ̷n̷o̷t̷ ̷s̷e̷e̷m̷ ̷t̷o̷ ̷w̷o̷r̷k̷ May 23, 2022
@Xyotic Xyotic changed the title ̷N̷a̷v̷i̷g̷a̷t̷i̷o̷n̷S̷e̷r̷v̷e̷r̷.̷M̷a̷p̷S̷e̷t̷A̷c̷t̷i̷v̷e̷(̷)̷ ̷d̷o̷e̷s̷ ̷n̷o̷t̷ ̷s̷e̷e̷m̷ ̷t̷o̷ ̷w̷o̷r̷k̷ Needs documentation: NavigationServer will only update after 1 physics frame ̷N̷a̷v̷i̷g̷a̷t̷i̷o̷n̷S̷e̷r̷v̷e̷r̷.̷M̷a̷p̷S̷e̷t̷A̷c̷t̷i̷v̷e̷(̷)̷ ̷d̷o̷e̷s̷ ̷n̷o̷t̷ ̷s̷e̷e̷m̷ ̷t̷o̷ ̷w̷o̷r̷k̷ May 23, 2022
@Xyotic Xyotic changed the title Needs documentation: NavigationServer will only update after 1 physics frame ̷N̷a̷v̷i̷g̷a̷t̷i̷o̷n̷S̷e̷r̷v̷e̷r̷.̷M̷a̷p̷S̷e̷t̷A̷c̷t̷i̷v̷e̷(̷)̷ ̷d̷o̷e̷s̷ ̷n̷o̷t̷ ̷s̷e̷e̷m̷ ̷t̷o̷ ̷w̷o̷r̷k̷ Needs documentation: NavigationServer will only update after 1 physics frame ̷N̷a̷v̷i̷g̷a̷t̷i̷o̷n̷S̷e̷r̷v̷e̷r̷.̷M̷a̷p̷S̷e̷t̷A̷c̷t̷i̷v̷e̷(̷)̷ ̷d̷o̷e̷s̷ ̷n̷o̷t̷ ̷s̷e̷e̷m̷ ̷t̷o̷ ̷w̷o̷r̷k̷ May 23, 2022
@Xyotic Xyotic closed this as completed May 23, 2022
@akien-mga akien-mga changed the title Needs documentation: NavigationServer will only update after 1 physics frame ̷N̷a̷v̷i̷g̷a̷t̷i̷o̷n̷S̷e̷r̷v̷e̷r̷.̷M̷a̷p̷S̷e̷t̷A̷c̷t̷i̷v̷e̷(̷)̷ ̷d̷o̷e̷s̷ ̷n̷o̷t̷ ̷s̷e̷e̷m̷ ̷t̷o̷ ̷w̷o̷r̷k̷ Needs documentation: NavigationServer will only update after 1 physics frame May 23, 2022
@Zireael07
Copy link
Contributor

If this is a documentation issue, it shouldn't be closed before documentation is updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants