-
-
Notifications
You must be signed in to change notification settings - Fork 21.1k
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
Listing directories in exported project returns only *.import
files
#25672
Comments
Ok, but i don't want to load any files. I need to do what i need to do i.e. get full list of files i have in my directory. Maybe there is another way, if yes then how? |
Another option: you can try to use this contraption to directly create PCKs from folder without any changes to files or to extract exported PCK, add files and repack it back. |
I simply can get why this does not works properly. If it works in editor it's intended to work everywhere, else this is either a huge issue or listing function is completely pointless to have in engine. I don't believe in workarounds cause they tend to fail everytime you add minor changes to anything :S |
Would like to say that this solution fixed the issue of importing for me, now I've got files which export properly without a *.import, however now I'm getting a "no loader" error when I run the program, and I can't use any of the files while running in the editor. |
Another option is to use the whole project folder and put the executable inside. |
But you can load it manually (process is different for various file type: for images you should use Image, for sound files load it as file and set AudioStream*.data). Won't work unless $TextureRect.texture = load("res://test.png") This will work with any var image = Image.new()
image.load("res://test.png")
var texture = ImageTexture.new()
texture.create_from_image(image)
$TextureRect.texture = texture |
Isn't it a kind of absurd to distribute to other users access to all the sources of your game. Yes, the engine is open-source, but let's say you have something related to micro-transactions in your game, or your saving data is encrypthed and the key is hidden within your code. You have to think ahead and outside the box of using your game on your machine only. |
@timCopwell I have the source code of my game on Github, so it doesn't matter for me. |
You won't be able to load any changed/added files (or any files at all it you do not distribute
Export is not much of protection. You can easily decompress PCK, you can convert scenes back to text versions and decompile gdscripts to the state almost identical to source. PCK does not store original files, but you still can restore it from |
Is there an *.ogg/streamplayer equivalent to the code mentioned above? |
Something like this: var ogg_file = File.new()
ogg_file.open("res://test.ogg", File.READ)
var ogg_stream = AudioStreamOGGVorbis.new()
ogg_stream.data = ogg_file.get_buffer(ogg_file.get_len())
ogg_file.close()
$StreamPlayer.stream = ogg_stream |
Workaroud for this Godot Engine bug :godotengine/godot#25672
Unfortunately bruvzg's workaround has been fixed and no longer works in 3.2 beta 2 Edit: My new workaround is to have a file with the directory list inside of it. You can then use File and get_line() |
*.import
files
If only |
The fix for this issue would be documenting in Then we could add a method named |
This seems unnecessarily confusing. I'm not sure why this has been a years long battle and yet no documentation under the load function mentions the fact that files will fail to load correctly after export if you don't jump through a bunch of extra hoops. |
@DaGamingWolf there's no problem with |
that is only true on the specific condition that |
What is the proposed way of making sure a specific resource file exists in an exported game? if FileAccess.file_exists(path:String):
var resource = load(path)
# other stuff
else:
printerr("File "+path+" couldn't be accessed.") This fails during export because file_exists() returns false. Do I manually have to check if .import, .remap have been added? The only general purpose solution I can see is using func is_valid_file(path:String) -> bool:
return FileAccess.file_exists(path) or FileAccess.file_exists(path+".remap") or FileAccess.file_exists(path+".import") Which idk. Seems pretty clunky for such a simple task. |
You can use ResourceLoader.exists() |
Perfect! Thanks a lot! |
I just stumbled over this when I ran into #66014, for now I manually have to remove the |
@ePirat Did you mean to link another issue? You linked this exact issue. |
@AThousandShips Yes indeed, fixed. |
If we have It seems to me that the problem is it's currently difficult to do filesystem-y stuff with resources because whether or not the files actually exist at the paths they claim to is completely dependent on esoteric project configuration. I want to do something similar to OP - I have a few hundred audio files and at runtime I just want to load them into Right now, the fixed version looks something like: func get_resources(path):
output = []
for fname in DirAccess.get_files_at(path):
if fname.ends_with(".import") and ResourceLoader.exists(fname.trim_suffix(".import")):
output.append(fname.trim_suffix(".import"))
return output This is neither intuitive nor convenient. I think it would be best to supply another set of directory operations for those who don't actually want to deal with the concrete filesystem, just the tree of imported resources. |
Hi everyone, I am currently struggling with this as well. I have mostly gotten things working, here is the code I'm using, maybe it will help you as well: static func get_files(dirpath : String, must_ending: String = "") -> Array[Filename]:
var dir_da = DirAccess.open(dirpath)
if dir_da == null:
return []
var files : Array[Filename] = []
for filename in dir_da.get_files():
if filename == ".hidden": continue
var p = dirpath + "/" + filename
if p.ends_with(".import"): p = p.replace(".import","")
elif p.ends_with(".r4") or p.ends_with(".json"): pass
else: continue
var fn = Filename.new(p)
if must_ending != "" and fn.extension != must_ending:
continue
files.append(fn)
files.sort_custom(func(a,b): return Helper._string_compare(a.base, b.base))
return files This uses the workaround from #14562 , notice how it is taking .import files instead of the normal ones (for example png files). Change the class_name Filename
var path
var base
var full
var extension
func _init(path : String):
self.path = path
var slash = path.rfind("/")
var filename = path.substr(slash + 1)
base = filename
full = filename
extension = ""
var dot = filename.rfind(".")
if dot != -1:
base = filename.substr(0, dot)
extension = filename.substr(dot + 1)
else:
base = filename
extension = "" Then you just use that static func (I have it as var spells_dir = DirAccess.open(spells_path)
for class_n in spells_dir.get_directories():
for namepair in Helper.get_files(spells_path + "/" + class_n):
var texture = namepair.full
var spell_id = "%s/%s" % [class_n, namepair.base]
spells[spell_id] = ResourceLoader.load("%s/%s/%s" % [spells_path, class_n, texture]) as Texture2D for m in DirAccess.get_directories_at(merchants_path):
for mood in Helper.get_files("%s/%s" % [merchants_path, m]):
merchants["%s/%s" % [m,mood.base]] = ResourceLoader.load("%s/%s/%s" % [merchants_path, m, mood.full]) as Texture2D Two things you should do as well: just change all calls for imported assets (textures, models, etc) from |
Just ran into this in my own game when I tried to export it and had a pile of errors when running. Surprised the issue has been around this long, and that there's such vehement arguments suggesting ResourceLoader and a hardcoded list of files is somehow a viable alternative. In my case I want to a folder to have X number of player car images which I randomize through dynamically. I had written it to easily drop a new PNG in without having to update a hardcoded list, so therefore I used Looks like I'll do the "change .import to desired .xyz extension" approach as a workaround |
Godot version:
Godot v3.0.6 Stable x64
OS/device including version:
Windows 8.1
Issue description:
Shortly I tried to scan my
res://audio/supersounds
directory for every.wav
file it had into array, and then play track by picking randomly with randi() % array.size(). But i've met problem where already exported project return empty array. So thinking about it might be problem with.wav
, i've added some.png
and.ogg
into the folder and even removed file type check and it did some progress, it returned only.import
type files. That's not what I wanted. In editor everything showed how expected.Some guy in godot questions topic did reproduction and met the same problem. But he somehow got some
.png
and other types in output. Being surprised I also went and created empty project with same function to scan, but added custom.png
intores://
and tried to list the thing. This is what've got:Apparently default files and main scene are somewhat defended against it!?
After... I went already here to search for answer I thought it might be #25347, but i checked it's reproduction and it works fine, so file_exists() isn't the case.
Im at dead end now.
Steps to reproduce:
Create new scene, add root node, add following script to it:
Export, launch. Executable debug console should print something similar to this:
Expected:
Minimal reproduction project:
exported.zip
project.zip
The text was updated successfully, but these errors were encountered: