I keep getting the error Condition "!is_inside_tree()" is true. Returning: Transform3D()

1.8k views Asked by At

When the player clicks I am trying to pass the position and direction of the camera3D (which is in the player scene) to the world scene through a signal to spawn a bullet with that direction and position. The world scene is a parent of the player scene and is able to get the information but only the position actually works, and if I pass position and direction for some reason it won't spawn the bullet in the right place

I tried moving the bullet node around to try to get it to work

3

There are 3 answers

0
Theraot On

The error is telling you that the operation you are doing cannot be done on a Node that is not on the scene tree... Either:

  • The Node hasn't been added yet (i.e. you haven't called add_child yet).
  • The Node been removed (either because of remove_child or queue_free).

And since this is about a Transform3D I'm going to guess this is about reading or writing the global_transform of a Node3D.

Note: I'll continue talking about the global_transform, but this applies to global_position,. global_rotation and global_rotation_degrees since they are all shorthand to global_transform for convenience.


Now, setting the global_transform outside of the scene tree is not an error, but it sets transform instead (which would explain why you are getting the bullet spawned in the wrong position).

While you could address that by setting the global_transform after you added the Node3D to the scene tree, that might give colliders an opportunity to run before Godot sets the updated position.

So, instead I'm going to encourage to set the transform... Let us say:

  • You have a Node3D, which I'll call instance.
  • And you want instance placed at desired_global_transform.
  • And added as child of parent which is in the scene tree.

Then you do this:

instance.transform = parent.global_transform.affine_inverse() * desired_global_transform
parent.add_child(instance)

Contrived? Yes, but I'd expect it to work around the wrong position.

The idea is that when instance is added as a child of parent, then instance.global_transform will be parent.global_transform * instance.transform... Then the parent.global_transform cancels out with its inverse, leaving desired_global_transform.


But getting the global_transform of a Node3D that is not in the scene tree is an error.

In this case you say you read the global_transform of a Camera3D... Which makes be believe the Camera3D isn't in the scene tree.

Since you say the Camera3D is part of the player scene, I'm guessing the whole scene is outside the scene tree.

You, of course, can use is_inside_tree to check, and don't run the code if it returns false. If you also add a breakpoint there, it might help you debug the situation.

0
Anil Myne On

I had the same problem and here is how I solved it.

  1. Start by making a backup of the script that brings the error OR a copy of the entire project's script.
  2. Convert every print() statement in the code to a push_error(). This will push all printed out statements to the error output window allowing you to see which stage this error occurs at. For this step, you might want to reduce the print() statements so that the output isn't much.
  3. Run the project and see what point the !is_inside_tree occurs. At this point you could already have an idea of how to solve the issue. If no, move on to step 4.
  4. Put a breakpoint on the latest 1 or 2 lines before the !is_inside_tree error as seen in the error output window.
  5. Run the project and run and once the breakpoint is hit, use the step into feature repeatedly until the !is_inside_tree error is printed.

That'll surely help.

0
Huseyin Kaplan On

I had the same error when doing:

cube_object.global_position = last_valid_position get_parent().add_child(object)

fix was to change the global_position after calling .add_child()

get_parent().add_child(object) cube_object.global_position = last_valid_position