Hello, I am testing letting the player create sprites for an AnimatedSprite2D node during runtime.
I have managed to edit and “convert” an Image-resource to a sprite that is applied to the AnimatedSprite2D’s SpriteFrame resource.
But I think I will need to save this runtime-created image to the disc or else it will be lost on restart, correct? The sprite needs a filepath to its texture I’m thinking. I can save these created images as well currently.
Here is my issue: I want to recreate the AnimatedSprite2D from the image I saved to the disc. Or rather, I want to recreate the SpriteFrame but will apply it to the AnimatedSprite2D. But I only end up with nothing seemingly, the new AnimatedSprite2D has an empty SpriteFrame.
Here is my code that save the created sprite named “default”, and immediately loading it into a new SpriteFrame “updated_frame”:
func _recreate_spriteframe():
var image_to_save
var image_to_load
var texture_with_filepath
var updated_frames = SpriteFrames.new()
image_to_save = animated_sprite.sprite_frames.get_frame_texture("default", 0).get_image()
image_to_save.save_png("user://default.png")
image_to_load = Image.load_from_file("user://default.png")
texture_with_filepath = ImageTexture.create_from_image(image_to_load)
updated_frames.add_frame("default", texture_with_filepath, 1.0, 0)
animated_sprite.sprite_frames = updated_frames.duplicate()
Help is appreciated!
PS. I have a hard time viewing images in the editor I notice, even in nodes I know has images. They are presented as though they are nothing more than a resource, they don’t even have an image field. Very strange… But perhaps my issue could be when I call Image.load_from_file not working? Is there some special method to view images in the inspector?
If your intention is to substitute the first frame from the animation default then what you are doing is not correct as right now you are creating a new SpriteFramesResource that has nothing to do with the current assigned one. You’ll need to Resource.duplicate() it instead (var updated_frames = animated_sprite.sprite_frames.duplicate()) if you don’t want to share it with other nodes.
If that’s not the case then you are missing adding the default animation to the new SpriteFrames with SpriteFrames.add_animation()
Thanks for the reply. After having tested a bit more I think I know a bit better now what my issue is. The title is a bit confusing now in hindsight, but to focus on a particular issue:
What I really want to do is create a new SpriteFrame resource that can load frames from PNG:s in the filesystem during runtime. Let’s say I want to add an “attack” frame instead of the “default” example:
var sprite_frame : SpriteFrames = SpriteFrames.new()
sprite_frame.add_animation("attack")
sprite_frame.add_frame("attack", load("res://saves/characters/0/attack.png"))
But my SpriteFrames resource seems to be completely empty despite adding both animation and frame:
The image I provided show the sprite_frame resource after giving it the animations. I figured I should be be seeing the same interface as when I’d click on the same resource type in an AnimatedSprite2D. Here I only see an empty resource.
I also tried assigning it to an AnimatedSprite2D node to see what happens, but got the same result.
Which interface are we talking about? Runtime inspector is different than editor inspector. But even editor inspector doesn’t display any properties for SpriteFrames resource.
If you created an object and assigned the properties via code. Those properties are surely assigned. Print their values to check.
Printing helped a lot to see the changes instead of looking in the inspector!
The animations were created but I have some issue saving and loading png:s in a single runtime, I get the old image when trying to load. But that can make sense and I don’t need to reload the image during runtime regardless.