godotengine / godot

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

Getting Resource UID Returns Invalid (-1) at Runtime on Exported Projects #75617

Open TheoJao opened 1 year ago

TheoJao commented 1 year ago

Godot version

4.0.1

System information

Windows 11

Issue description

I'm building a character customization system in my game, and I use custom resources that contain information like the textures and thumbnails of parts of the face and stuff. When the character creator is loaded, I create the thumbnails and connect a signal that passes the resource UID as an argument so once clicked, it loads and applies the changes to the mesh, this also allows me to save the UID in a variable, which I later use to set the correct textures when the game is loaded.

When I use the editor everything works fine, using print(ResourceLoader.get_resource_uid(iris_style)) returns 6360883855146557548 which means it's working as it should. However when I export the project and execute it, every single time I print these IDs (for debugging purposes) it returns -1 which also means no textures are applied when the thumbnail is selected.

I already tried adding ".remap" to the resource path, but it still returns -1. Is this a bug? Or is it supposed to work like that? I can try to find a workaround, but what confuses me is that it works fine in the editor, and it seems like I can't expect the same behavior when I export my project. Isn't this the way I am supposed to handle resource ids? I already tried using get_rid() but it also returns 0 or invalid.

Steps to reproduce

  1. Create a few custom resources.
  2. Load them into the game and print their IDs using print(ResourceLoader.get_resource_uid(the_resource)).
  3. Now export the project and check the logs/console outputs (which should be invalid IDs). Make sure it is executed out of the project folder, or it will return the correct IDs.

Minimal reproduction project

Very small project with 3 custom resources, it returns -1 as expected.

id_project.zip

KoBeWi commented 1 year ago

Looks like export bug (or maybe not?). The resources are converted to res and no longer have UID. You can still load them using uid:// because it's cached, but you can't get UID from the resource.

TheoJao commented 1 year ago

Oooh I didn't know that, I get it now. So right now there is no way to get a resource UID when the project is exported, right? I guess I'll have to change my code. Thanks! At least I know what works and what doesn't.

It's also weird because when I placed the executable inside the project folder and ran the game it worked perfectly, which made me believe everything was good until I copied it to my laptop and found out everything was bugged, same result if I placed the executable in another folder on my main PC.

AThousandShips commented 1 year ago

The UIDs are not carried over in the code, for resources it is done here: https://github.com/godotengine/godot/blob/ef025711a694071a1407b5035a6fe3e67c2a5b07/editor/export/editor_export_platform.cpp#L795-L803

Could be an oversight, but UIDs mainly make sense in the editor for handling files being moved etc., but still might be good to have it fixed

leonardoraele commented 3 months ago

Keeping track of resources' UIDs in exported builds would be useful for multiplayer games. You could send a RPC from one peer to another referencing a resource by its UID instead of its path. (e.g. to instantiate a scene) Since UID is usually shorter than the path, it would be more network efficient than sending the path in the RPC.

poohcom1 commented 2 months ago

UIDs mainly make sense in the editor for handling files being moved etc., but still might be good to have it fixed

If this isn't planned to be implemented soon, I think it should be documented clearly in all places referencing resource UIDs, as well as have UID related functions like get_resource_uid fail loudly in exported runtime. Many people (like me xD) might end up coding large part of their game with the expectation that UIDs work in runtime because they don't regularly test in exported versions.

Summersay415 commented 1 week ago

Can confirm. This can be fixed by looking for .remap-like file and fetching path from them, or something like that. I will try to fix this.

KoBeWi commented 1 week ago

Yeah there is uid_cache.bin file that you can use for lookup. Other UID sources (like the new .uid files) don't/might not exist after export.