0 votes

issue talking about relative paths

Ah, ok. It works if the path is not relative or it's relative, but
prefixed with res:// Preload works with relative paths either way.

var x = load("not/relative/item.gd") #=> success var x =
load("../relative/item.gd") #=> null var x =
load("res://../relative/item.gd") #=> success var x =
preload("../relative/item.gd") #=> success var x =
preload("res://../relative/item.gd") #=> success

excuse my ignorance but i am new
it seems like relative paths could be useful
is there a way to use relative paths in csharp?
i tried all these permutations but none seem to work...

Stream = ResourceLoader.Load<AudioStream>("res://Intro/PinDrop.wav")

then this folder with the script and wav in it would not break when moved or renamed right?

thanks

in Engine by (1,939 points)

2 Answers

+5 votes
Best answer

Relative paths don't work with load or ResourceLoader.Load because contrary to preload (which is specific to GDScript and deduced at compile time), the former does not have any info from where it runs, and so cannot do a relative path lookup. C# itself doesn't know this either. See https://github.com/godotengine/godot/issues/5999#issuecomment-249435940

I know in GDScript it's possible to still use the path of the script, which then you would append to a relative path to form an absolute path, which works like this:

load(get_script().resource_path.base_dir() + "/relative_path/resource.png")

Which in C# would maybe become:

ResourceLoader.Load<AudioStream>(((Resource)GetScript()).ResourcePath + "/relative_path/resource.png")

You could likely write an extension method to Godot.Object so that Load is always available anywhere with relative paths? But ResourceLoader is a separate class so it cannot do that automatically.

But otherwise you really have to input full paths. Note that it's actually recommended you export resource properties, rather than hardcoding them. If you do this, Godot will automatically reassign the path if you move the asset from the editor.

In GDScript it's more common to hardcode script paths because it is the only way to access other script classes (unless they use class_name), but C# classes are all named so it doesn't have this problem.

by (29,120 points)
selected by
0 votes

You'll have to roll your own load function that does compile-time-relative paths.

It's a touch tricky. I wrote up a sample Gist that you can tweak to fit your needs. It uses the CSharp attribute [CallerFilePath] to figure out paths. Read up on it, if you are unfamiliar, or you could shoot yourself in the foot.

Sample usage:
IO.Load<Texture>("./icon.png"); //< secret second param filled with this file's path

Anyway, here's the gist:
https://gist.github.com/cgbeutler/ac6f8d480c70f0ab697c245513a4c2a5

by (60 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.