godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.14k stars 93 forks source link

TileMap: allow placing any tile from an animation sequence other than the first tile #7461

Open inhalt120g opened 1 year ago

inhalt120g commented 1 year ago

Describe the project you are working on

A tile based pixel art game with lots of small animations and special effects

Describe the problem or limitation you are having in your project

In my project I'd like to use lots of simple special effects on menus, backgrounds and such. These effects are technologically very simple and lend themselves well to implementation as tiles, for example an animated menu background of small stars: godot tile animation example single star

The problem is that it looks quite mechanical and silly when there are lots of them and they're all blinking in sync (looks more like a stroboscopic seizure test than a fun background effect).

I'd like it to look like this (less mechanical): godot tile animation example 02

Or for example the animations of other elements, here is a sketch of water waves on the beach, compare the top (what it looks like out of the box) and below what I'd like it to look like: godot tile animation example 01

Currently, the only solution to eliminating this mechanical effect (when all tile animations are in sync) is to either use a shader (something like what is mentioned #57677), but this is impractical and I have no idea how to maintain it (I'm a designer) or prepare a special tile sheet with offset animations, but this looks quite wasteful to me: glitter

Other solutions are even less practical (for example I could make a mini-scene for each effect and then manually change the offset for each… nightmare to maintain).

Please note I'm not talking about the ability to randomize starting offset in a tile animation set (#6856). Randomization would not allow for synchronized effects like this for example: godot tile animation example 03

Describe the feature / enhancement and how it helps to overcome the problem or limitation

I'd like to be able to place any tile from the animation sequence on a TileMap. The placed tile would act as a starting point for the tile sequence animation.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

With the Tile Map component selected in the Scene Tree, using Tile Map / Paint tool the designer can select any tile from any animation sequence. Placing this tile in the game will set this tile as a starting tile once the animation starts playing.

There is no need for new interface.

If this enhancement will not be used often, can it be worked around with a few lines of script?

There are workarounds but they are all kind of impractical (and in my case maintaining a shader is not something I'll be able to do anytime soon). I believe it will be used often.

Is there a reason why this should be core and not an add-on in the asset library?

Selecting a tile from a tile sheet is such a basic and simple to use (not sure how easy it is to implement if any tile is accessible) action that is tightly integrated with the Godot's UI tile placing workflow, makes it hard to imagine how would an add-on be glued on top of it.

duncathan commented 1 year ago

My project would benefit greatly from this, so I'm interested in ensuring this proposal is as clear and useful as possible!

One question that isn't immediately answered in the proposal (as best as I can tell, anyway) is what the UX might look like. I have two ideas: 1) Permit alternative tiles to choose a frame to start on. This would slot nicely into the Rendering category for alternative tiles, I think. I'm not nearly familiar enough with the internals of the tile system to know if this would be easy to implement, but it does seem like the simplest addition to the existing UX. Disadvantage of this approach is that setting up alternative tiles can be cumbersome if this behavior would be used on very many tiles in the tileset. 2) Add a control for per-tile frame selection. Could be alongside the controls from https://github.com/godotengine/godot/pull/80144, if that's merged. A plain old integer box with arrows, maybe?

Another question is how to reconcile this with #6856, and its implementation in https://github.com/godotengine/godot/pull/77257. Should this behavior be a third enum entry? Restricted only to TILE_ANIMATION_MODE_DEFAULT? I'm not sure what would feel most natural.

rakkarage commented 1 year ago

2023-08-30

I am picturing it as modifying/selecting this highlighted tile within the animation. I guess a new mode (explicit?) would help to prevent it from highlighting frames other then zero when not intended and prevent interaction with random mode.

duncathan commented 1 year ago

Oh yeah, that's an option as well - would totally work. If that one were chosen then I agree, a new mode would be prudent. I imagine some users are used to the existing behavior of selecting the first frame regardless of where they click. A new mode would retain that behavior, add the new functionality, and avoid any confusion about random mode

inhalt120g commented 1 year ago

One question that isn't immediately answered in the proposal (as best as I can tell, anyway) is what the UX might look like. I have two ideas:

  1. Permit alternative tiles to choose a frame to start on.

I think allowing selection of any tile would work best if it were kept very simple, so yes, "Permit alternative tiles to choose a frame to start on" sounds like the most attractive option to me.

The reason I didn't go into details about this in the first post is because there's probably no need for any new interface or safeguards or any complications. The only thing that'd be different from designer's point of view is that the "selection rectangle" (the marker that shows which tile the designer is about to select for placing) can be moved to tiles other than the first tile in the animation.

For the benefit of people who are interested in the topic but don't know how it works in Godot: Right now if there's a tile animation defined like this (the 4 blinking stars in top row): image the only selectable tile is the first one. It's a bit hard to see because Godot is using some yellow frames without much contrast to mark the "selectable" and "connected" tiles but anyway, If I move the cursor over the second tile, the first tile is still marked as selected and we will see this on the screen: image At this moment, if I click on the second tile and then attempt to add it to the project, the first tile will be placed instead. No matter which tile I select, I will end up with this: Godot blinking stars

And here is how I imagine it, the "tile selection marker" would simply be able to do this: image

rakkarage commented 1 year ago

test

https://github.com/rakkarage/godot/commit/ac1afed0204293cb57e3d5df41fa66fa18588a47

Prototype with selection of frames working only in TileMap tab (even with animation columns)

todo:

rakkarage commented 1 year ago

I think I got it all working. Probably some issues but.... https://github.com/rakkarage/godot/commit/1d4a794021f460f67ef80c97adc27fedef6177af

Is it "cheating" to work on proposal instead of issue? :) This proposal seems like a must have... but i guess proposal is about how to implement not if implement. How long should i wait for "consensus" before open a pull request? Or I can...

Zireael07 commented 1 year ago

@rakkarage This issue has few reactions but they're all positive, I'd open a PR and see what the maintainers say