I've been really curious, why does AnimatedTexture require multiple source textures? I've looked through the source code to see if that would give me any idea, but I didn't see any reason without developing a deeper understanding of the source than I have today (give me time, only been using Godot for a week or two).

Thanks for any insight you might have to offer!

  • c

I will postulate a theory and someone more in the "know" can correct me if I'm wrong... but the most common way to handle animation in game development is through a mechanism called key-framing [1]. The way that key-framing works... is you keep multiple static images... and the static images have enough differences between them that it fakes your eyes into believing that it "moves" when you flip between the different static images. Textures are, by and large, static images; the easiest way to animate a texture is to use the key-framing technique of flipping from one texture to another.

Another mechanism for providing animated textures exists if you create a plane... convert the plane into polygons... apply a texture to the polygons... then move the vertices of the polygons (and their associated) polygons... but that's a more advanced application from what 'AnimatedTexture' is trying to do.

Also... if all you're trying to do is take a single texture and perform a transformation like a translation or a rotation to achieve 'animation'; then perhaps 'AnimatedTexture' isn't the best way to try and achieve that?

[1] https://filmora.wondershare.com/video-editing-tips/what-is-keyframing.html

Appreciate the response, but that's not really what keyframing is - keyframing means you define the animation at key points, and your software interpolates automatically between them - so, you set what it's like at 0 seconds and, say, 1 second, and then your software would fill in all 30 or 60 frames between. AnimatedTexture does not do keyframing.

I have been a gamedev since the 8-bit days and understand the underlying concepts quite well, but don't understand why Godot made this very odd choice for AnimatedTexture - usually, you fit all of your frames into one texture and each frame is a sub-rectangle of that full size texture (sometimes called a spritesheet when it's sprites, etc). I come to Godot with a ton of assets and, unfortunately, can't use a lot of them without serious retooling.

I am certain, given the time to study the C++ code more, I can change the way it functions to fit my needs better... but before I do that, it might really help me to know why they chose to do it the way it's done. From what I can tell at the moment, it is primarily related to the way _update_proxy already worked, and rather than modify that, they just did what they could in the existing framework.

in traditional terms(think old school disney hand-drawn animation) key frames are the key poses drawn by the senior/lead animator with the juniors doing the tweens aka the in-between frames. Beyond that the term can be used rather loosely so it can be confusing.

"Appreciate the response, but that's not really what keyframing is - keyframing means you define the animation at key points, and your software interpolates automatically between them - so, you set what it's like at 0 seconds and, say, 1 second, and then your software would fill in all 30 or 60 frames between. "

So I learn something new. I'll call that a win. : ) I guess that I was describing the general idea of animation; I was completely missing the nuance that there were a set of dominant frames and that you can interpolate between them, and using that technique of creating dominant frames and interpolating between them is what is actually called key-framing. (Did I get this correct this time?)

I found an example of someone using AnimatedTexture (a 3 minute, 50 second video) -- it looks like this is a case where you define multiple textures and you set a time to elapse before you flip from frame "n" to frame "n+1", at least in this use-case:

@cliff There's a more interesting question that I am curious about, I don't have the context of years of game development experience that you do. How would you implement 'AnimatedTexture' in your context? Or... what behaviors and properties should 'AnimatedTexture' have?

@GreyWolf117 said: @cliff There's a more interesting question that I am curious about, I don't have the context of years of game development experience that you do. How would you implement 'AnimatedTexture' in your context? Or... what behaviors and properties should 'AnimatedTexture' have?

Well, when I've implemented such things from scratch, I write a shader and give it the UV coordinates of the bounds of the animation, and a rectangle that is the size of a single frame, and then update the frame index each time the frame should change, and then in the shader, I just calculate the UV for the particular frame and render that.

Or, in the old 8-bit days, each bit of the "texturemap" would actually be a character/font map, and you just update the character each frame (i.e. it may take the place of the characters A, B, and C... at least on say the Commodore 64 - on the NES, they're not actually replacing charsets, but they work the same way). You do that on the vertical refresh in a raster interrupt.

Part of why I love shaders so much is that they really feel like the new generation of copperlists.

Hmm... it looks like "AnimatedSprite" will interact with SpriteSheets the way you are describing: https://docs.godotengine.org/en/stable/tutorials/2d/2d_sprite_animation.html

I think I may comprehend the problem, now: https://godotengine.org/qa/39974/why-cant-we-use-animated-sprites-in-a-tile-map

I thought that I remembered reading that back in the 8 bit days... Sprites were pretty expensive in terms of the resources that were available at the time, so systems like the Amiga or the NES had a limited number of sprites that could be used on a screen at any given point of time; and background could be be rendered separately, and without consuming much additional resources. (Please feel free to correct me where I make a wrong statement)

If someone were to composite a "TileMap" of 'AnimatedSprite's... the resource consumption on rendering such a map might be greater than it would be if you were rendering a "TileMap" of 'AnimatedTextures'. And the current 'TileMap' does NOT take the 'AnimatedSprite' as a tile.

That's the reason I'm so confused, using multiple textures should consume MORE resources, not less. I knew that sprite sheets worked as expected, which is part of why I was confused when animated textures didn't.

I don't have the chops, yet, to add additional functionality to the Godot engine proper. I think that one could probably overload the class in c++ that represents 'AnimatedTexture' to read sprite-sheets and perform the uv-mapping, scaling and splitting so that it could either take multiple individual images, or one parameterized sprite-map. This might require some changes to other classes like 'TileMap' to get it to play well with the new 'AnimatedTexture' changes.

The other option that you already alluded to, would be to build your own tools to slice the sprite-sheets yourself, so that you could feed them into godot; which would require some up-front overhead from you.

Yeah, I have been thinking about a new class that extends AnimatedTexture when I get around to it... either that, or just modifying AnimatedTexture to work both ways and submitting a pull request.

Long term, I have some things I'd like to do with TileSet and TileMap, but those would work better as new classes - especially for the TileSet (I want to add good, fast support for RPGMaker-style tilesets)... would be nice if TileMap could work with both - optimally, the new TileSet extension would be completely transparent to TileMap.

Perhaps I should try starting with the current godot code and seeing what I can do with it. Cutting my teeth on a problem like this isn't a horrible way to spend an evening (or three). Naturally, if my output is crap, I don't have to waste the actual godot maintainers time with a pull request.

Honestly, when it comes to learning C++, I would suggest not starting with someone else's large codebase as they are doing some sophisticated things that will confuse the basics for you. I would instead suggest an actual free course on Udemy or Coursera or something like that. A good thick-as...cii book works too. If you go for a book, then of coz read reviews first to make sure the book is worth your time.

Was looking at newold's importer for RPGMaker tiles, where he has a very nice workaround for just the problem I'm posting here - attaching a script to the TileMap that runs on _process.

"Honestly, when it comes to learning C++, I would suggest not starting with someone else's large codebase as they are doing some sophisticated things that will confuse the basics for you. " -- I am familiar with the basics of c++ (I don't work with it professionally as I do with java). I'll occasionally have to look stuff up when it comes to pointers and pass-by-value versus pass-by-reference. I really like the multiple inheritance mechanism available to c++ (java only supports single-inheritance - which is fine for simple CRUD, you don't need advanced class models for that most of the time; but it makes designing advanced class models a bit goofy, sometimes). I am not familiar enough with c++ that I know how to handle advanced topics like templating and generics. The difficult part, for me, would be fully comprehending the high level model; then comprehending the mid-level implementation model.

"Was looking at newold's importer for RPGMaker tiles, where he has a very nice workaround for just the problem I'm posting here - attaching a script to the TileMap that runs on _process." -- That should help!

Java is definitely going to give you a leg up... getting used to the memory management stuff is probably the biggest hurdle, but thankfully, modern C++ has much better ways to handle it than the old fashioned manual way of handling it. std::unique_ptr and its siblings are your best friend.

In graduate school, most of the programming we did was in c or c++. It makes you a bit of a control freak with respect to memory management. It still drives me crazy that java wasn't really designed to let you do that... yeah java has a garbage collector, but sometimes the bloody thing makes stupid decisions.

I honestly am of the opinion that Garbage Collection is a failed experiment. Honestly, everything about Java was built from day one to require better hardware than most of us have/had.

So, I got Newold's animated tiles trick working, but it is stupendously slow on remotely large tilemaps (i.e. 64x64), so I may have to go back to using AnimatedTextures and just doing some manual work to prep the textures.

Ah, well, could be worse, I guess.

I've re-implemented the original AnimatedTextures way of doing it, and the framerate even on 256 layers of tilemaps that are 256x256 (with tiles drawn on the maps) is still managing to stick around 60fps, soooo... I guess this is how I'll be doing it for now.

The performance may well be why they are doing it the way they are doing it.

"So, I got Newold's animated tiles trick working, but it is stupendously slow on remotely large tilemaps (i.e. 64x64), so I may have to go back to using AnimatedTextures and just doing some manual work to prep the textures."

Stupendously slow? Which resource is being made scarce? CPU? RAM? Is this the kind of thing that can be made more efficient by pre-computing some values and shoving them into RAM before sending it to the render loop?

Also... did you end up submitting a pull request? I'm not seeing anything referring to Textures in the recent history of the "Master" or "3.2" branches. Or did you just make you needed changes locally?