Godot version: v3.1.stable.mono.official
OS/device including version: Windows 10.0.17763 Build 17763
Issue description:
I created a Viewport node and had it draw some GUI. Then, on a MeshInstance (quad) I set its albedo texture to ViewportTexture and selected the viewport node (at Player/Viewport). It still came up with a preview.
When I ran the game I was met with two errors:
Node not found: Player/Viewport
ViewportTexture: Path to node is invalid
But I was still able to play the game and furthermore, the viewport still worked correctly. I took a look at the scene's .tscn
file and found that the ViewportTexture does indeed point correctly to the Viewport node I had created.
ViewportTexture, SpatialMaterial, and QuadMesh:
...
[sub_resource type="ViewportTexture" id=1]
flags = 1
viewport_path = NodePath("Player/Viewport")
[sub_resource type="SpatialMaterial" id=2]
resource_local_to_scene = true
flags_transparent = true
flags_unshaded = true
flags_albedo_tex_force_srgb = true
albedo_texture = SubResource( 1 )
[sub_resource type="QuadMesh" id=3]
resource_local_to_scene = true
material = SubResource( 2 )
size = Vector2( 0.3, 0.2 )
...
Scene tree:
â”–â•´Spatial
â” â•´Player
┃ ┠╴Camera
┃ ┠╴Cockpit
┃ ┠╴Right
┃ ┠╴Left
┃ ┠╴CockpitAudio
┃ ┠╴GunFireCockpitAudio
┃ ┠╴TargetingMesh
┃ ┖╴Viewport
┃ ┖╴GUI
┃ ┖╴Speed
â” â•´CSGBox
â”–â•´CSGBox2
This is very similar to #14790, #12781, and #19259.
Steps to reproduce:
Create a Viewport node, assign a ViewportTexture to a mesh, select the Viewport you made, and run the game.
Oh, my bad: the error occurs on save, too.
I'm having the same issue without using mono. The ViewportTexture
is used in a TextureRect
and works correctly, but an error message is thrown.
@asmoaesl @CptPotato, do you use the "tool" keyword in a script attached somewhere in the node hierarchy that includes the Viewport Node?
I don't. I'll see if I can create a small reproduction project later today.
Can confirm this is happening for me as well with 3.1 stable. A possibility is that for the first frame, the Viewport is invalid/initialized, since this only seems to happen when starting the game or the editor.
I do not.
On Mon, Apr 8, 2019 at 3:10 PM KaadmY notifications@github.com wrote:
Can confirm this is happening for me as well with 3.1 stable. A
possibility is that for the first frame, the Viewport is
invalid/initialized, since this only seems to happen when starting the game
or the editor.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/27790#issuecomment-480987869,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ANCVy-PQBnmj1e0YLMannkPKNl-0YrXCks5ve6IpgaJpZM4chGqk
.
Looks like @kaadmy is correct.
This works without errors:
The TectureRect
is using the Viewport as ViewportTexture.
This causes an error on the first frame (probably while the tree is being created):
Good temporary solution
Can confirm the bug
The workaround is working...but it may break a little the consistency of the node tree, ie: if my Viewport Node is generating a texture specificaly for a Sprite Node, I'm assume it's more logical to have it _under_ the Sprite Node and not _before_. Thus manipulating the Viewport Node is more straightforward through a script attached to my Sprite Node.
Is there any way to skip the first frame otherwise?
@Overblob I actually think it makes more sense to have the Viewport above the Node which is accessing it. Not only does it prevent the error, but it also doesn't introduce lag. Otherwise you'll get 1 frame of lag for each consecutive Viewport you're using.
@CptPotato Makes sense, I didn't think of it. But it still feels weird to have the 2 Nodes at the same hierarchy level since the former is a dependency of the later one (ie. if my Viewport Node is only meant to generate a texture for the other Node). And generally speaking, from a given Node I think it's good practice not to reference a non child Node.
Maybe an exception is inevitable in this particular case.
I have a very similar issue, but in my case I'm using a label under a viewport, and then rendered into a sprite3d that have a ViewportTexture, no matter the order of the nodes, I still get the same error.
I have to correct myself, changing order works also with Sprite3D, I just forgot to change reference to if from a script.
I'm using Godot 3.1.1
Welp! How you work around this?
EDIT:
Instead of setting the texture
directly from the Inspector, set it from script:
func _ready():
texture = $Viewport.get_texture()
This seems to be just an issue with the way the _ready
notification is passed, the connection is happening before the viewport node is instanced in the tree. Maybe in the other notification that is called after _ready
? ( I am forgetting its name right now and cannot find it in the docs )
This is listed as "similar" to #19259, but are they actually exact dupes?
I was going to file a separate issue, but I think it is close enough to this to post here.
I've got a repro of this even with the ViewPort ordered before the texture, and it seems to be blocking parts of the editor UI.
Godot version:
3.1.2.stable.custom_build
OS/device including version:
Linux 5.4.10-arch1-1
Issue description:
When I use a ViewportTexture referencing a ViewPort (A
), clicking the arrow on an exported PackedScene
field (B
) of a custom resource (C
) prints the error "ViewportTexture: Path to node is invalid"
(D
), and no dropdown is shown.
Steps to reproduce:
data
in the filesystem searchbarbolt/data.tres
projectile
fieldMinimal reproduction project:
Not completely minimal, but I tried to reduce my current project down as much as feasible.
example.zip
Digging further, the issue in mine seems to be that loadout.gd
preload
's a scene that has a ViewPort texture. If I remove the preload
, my errors go away. Haven't been able to minimize it though.
An easy solution would be to modify the error that gets printed, to suggest modifying the hierarchy to silence the error. i.e.
"ViewportTexture: Path to viewport is invalid or the texture was instantiated before the viewport. If the path seems valid, move the node using the texture underneath the viewport"
I did my own digging and here's what I found:
//path is the viewport path
//path is initialized as an empty path
void ViewportTexture::set_viewport_path_in_scene(const NodePath &p_path) {
if (path == p_path)
return;
path = p_path;
if (get_local_scene()) {
setup_local_to_scene(); //This line refreshes texture when path is changed
}
}
Our issue is that when our scene gets instantiated, path is set to whatever it is in the scene/resource file. This calls set_viewport_path_in_scene() which calls setup_local_to_scene() and since the node is most likely not done initializing, there's potential for a path to be invalid. set_viewport_path_in_scene() is called a second time, after initialization (I don't know from where) so the path will be valid.
I guess the two options would be to change the error message with #37014 or we could somehow check if the node returned from get_local_scene() is fully initialized. But I don't know if such a function exists.
I've had this same issue, and I modified the engine to remove ViewportTexture::setup_local_to_scene() and moved the logic to ViewportTexture::set_viewport_path_in_scene(). Seems setup_local_to_scene() is called too soon (before the scene is put into the tree). I'm not sure if there's a reason setup_local_to_scene() needs to be there, but for the two instances I'm using it (reflection on water and rendering something to a monitor), it seems to work properly.
@jitspoe Do you think you could share what ViewportTexture::set_viewport_path_in_scene() looks like after you add the functionality from ViewportTexture::setup_local_to_scene()?
Pretty much just a copy/paste, I think. I'm a bit hesitant to do a pull request, as I don't know why setup_local_to_scene() was used and what removing it would break.
void ViewportTexture::set_viewport_path_in_scene(const NodePath &p_path) {
if (path == p_path)
return;
path = p_path;
if (get_local_scene()) {
if (vp) {
vp->viewport_textures.erase(this);
}
vp = NULL;
Node *local_scene = get_local_scene();
if (!local_scene) {
return;
}
Node *vpn = local_scene->get_node(path);
ERR_FAIL_COND_MSG(!vpn, "ViewportTexture: Path to node is invalid.");
vp = Object::cast_to<Viewport>(vpn);
ERR_FAIL_COND_MSG(!vp, "ViewportTexture: Path to node does not point to a viewport.");
vp->viewport_textures.insert(this);
VS::get_singleton()->texture_set_proxy(proxy, vp->texture_rid);
vp->texture_flags = flags;
VS::get_singleton()->texture_set_flags(vp->texture_rid, flags);
}
}
Edit: Could stand to be cleaned up. The local scene check is redundant. I just copy/pasted it to see if it would fix the bug.
@jitspoe Feel free to open a pull request so it can get broader testing :slightly_smiling_face:
Using mono here. I also get the same error spam 6-7 times every time the scene loads regardless of the order, and even when programmatically set. Happens all at once, right after the scene's _Ready() method is called, after I lose control of the loop's cycle, and before the next cycle starts.
And, like clockwork, after a few weeks debugging this issue, as soon as I post about it, I discover the root of the issue.
So, I was avoiding building a minimum reproduction, because it's not simple to replicate, but I took the time and made one, but I couldn't get it to throw the slew of errors.
After doing a general string search the entire project for references to the node's name, I found that sometimes (I can't find a pattern) when you pass a ViewportTexture
as a parameter to a shader, it will sometimes hold on to the reference to the node in the tscn file even after you clear it. In my case, since I decided to programmatically set the ViewportTexture
, it doesn't need to be referenced in the scene, but it persisted in file though it was cleared, and I had to manually remove it from the tscn code. So, while the errors are annoying, they were valid, but only due to another unrelated editor bug. I'll open a separate issue once I've been able to consistently replicate the problem.
Did you, by chance, happen to have that as a child scene and have editable children enabled?
I'm guessing there's an open bug involved with that? Because totally.
I couldn't find documentation on this, but it seems like the little circular arrow next to a setting resets it to whatever the base scene's setting value is. If that is the case, it sometimes shows it update in the editor, but doesn't save it in the tscn.
Don't know if there's an open bug on it, but it's something I've noticed with other things. For example, I had a scene that had editable children enabled, then I updated a material on the child scene, but that material didn't update on the scene containing it (even though that material wasn't edited -- I just wanted to move some meshes around or something).
Most helpful comment
Looks like @kaadmy is correct.
This works without errors:
The
TectureRect
is using the Viewport as ViewportTexture.This causes an error on the first frame (probably while the tree is being created):