godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.13k stars 75 forks source link

Add a default offset support for Sprites directly #7844

Open RobotoSkunk opened 1 year ago

RobotoSkunk commented 1 year ago

Describe the project you are working on

I'm working on porting an existing 2D platformer game from Unity and more previously Game Maker Studio.

It contains a lot of sprite animations and non-centered sprites.

Describe the problem or limitation you are having in your project

The lack of sprites pivots highly affected me, especially for sprite animations. Without them, I've been forced to edit all of the sprites I already have to fit the annoying Godot's centered sprites.

Specifically, I've edited around 107 sprites in two days just to make them work in Godot Engine and use AnimatedSprite2D instead of the Animator itself just because, well, that's the purpose of AnimatedSprite2D, isn't it?

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

Add an option to set up a default offset for each sprite individually, and then set it automatically to Sprite2D and AnimatedSprite2D nodes when the sprite is added to the node.

Additionally, add a checkbox for Sprite nodes with something like Use Default Sprite Offset just to make a fallback to the default sprite offset previously stablished.

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

I don't know how exactly the Sprite2D and AnimatedSprite2D works, but it should be something like this:

// Sprite2D.cs

public Texture2D Texture {
  set {
    if (useDefaultOffset) {
      Offset = value.Offset;
    }

    _texture = value;
  }

  get {
    return _texture;
  }
}

With this, you could have some freedom to set up a custom offset or let the Sprite2D set up the offset for you based of the Sprite's default offset.

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

Yes, to work with the default Godot's behaviour, the developer just has to disable the Use Default Sprite Offset option and it would work normally just like this feature have never existed.

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

Because, it's a completely basic feature of every 2D game. A lot of engines work with this, even Game Maker 8.1 and Adobe Flash worked with this and Godot lacks this important feature.

I've seen a lot of solutions for this problem by just setting the offset manually for each sprite or using the regular Animator instead of AnimatedSprite2D, but it's harder and annoying for newcomers like me and using the regular Animator makes AnimatedSprite2D useless if it cannot set the offset automatically per sprite.

RobotoSkunk commented 1 year ago

Also, this would be ideal for bigger sprites to optimize disk space and GPU usage to prevent rendering empty sprites spaces by trimming them.

wareya commented 1 year ago

To clarify: This is about adding an "offset" value to the Texture resource, which the Sprite etc. nodes would read when assigning their texture reference, right?

RobotoSkunk commented 1 year ago

To clarify: This is about adding an "offset" value to the Texture resource, which the Sprite etc. nodes would read when assigning their texture reference, right?

Yes

Calinou commented 1 year ago

I'm a bit concerned about having this property be defined at a texture level, as this means you need to define it in the Import dock. It also doesn't feel like a local solution to me, as it means adding a property to Texture2D that will be ignored in a lot of scenarios (such as 3D rendering, outside of Sprite3D maybe).

RobotoSkunk commented 1 year ago

I'm a bit concerned about having this property be defined at a texture level, as this means you need to define it in the Import dock. It also doesn't feel like a local solution to me, as it means adding a property to Texture2D that will be ignored in a lot of scenarios (such as 3D rendering, outside of Sprite3D maybe).

I think it could even be useful for 3D rendering if the game needs a long sprite animation, and as I commented above, it could be useful to trim the sprites and reduce GPU and storage usage

RobotoSkunk commented 1 year ago

Also, imagine this scenario: I'm working with a sprite animation of 256x256 as a base size with 240 frames at 60 FPS, each sprite trimmed by the animator and I need to add it into a game.

To work faster, I often use Texture Packer to set all of the frame's pivots by bulk editing, but that feature is missing only with Godot exporting mode because Godot does not support this. And I've seen similar scenarios more than one time by just doing a search in Google

Mickeon commented 1 year ago

AtlasTexture has a padding property that would basically lift these issues on its own. The problem is that you cannot modify the individual frame textures that displayed and bundled within the SpriteFrames resource.

... Even though it would work just fine. I myself have added metadata on some of my frame textures, and I can check for them with get_frame_texture and get_meta combined.

So, comparing to the original proposal, the simpler solution in my eyes is to be able to easily open SpriteFrames' texture sub-resources in the Inspector dock. With some elbow and grease you may modify the padding to suit your needs. Keep in mind most users don't really need all of this complexity from the get-go, especially when alternatives or "Do it yourself" exist. Adding new features should be carefully considered so as not to bloat the engine.

RobotoSkunk commented 1 year ago

So, comparing to the original proposal, the simpler solution in my eyes is to be able to easily open SpriteFrames' texture sub-resources in the Inspector dock. With some elbow and grease you may modify the padding to suit your needs. Keep in mind most users don't really need all of this complexity from the get-go, especially when alternatives or "Do it yourself" exist. Adding new features should be carefully considered so as not to bloat the engine.

After thinking a little about this, I think the most obvious solution is just add the ability to actually change the offset per frame in AnimatedSprite2D from the editor. It would be really useful to actually fix all of the problems I've mentioned above... well, being honest, that's the only problem I have with Godot, the lack of offsets per sprite in AnimatedSprite2D but yeah, padding exists, even if it's still a waste of resources because of the unused part of the spritesheet

RobotoSkunk commented 1 year ago

Should I open another proposal to add offsets per sprite in AnimatedSprite2D or just close this one?

Calinou commented 1 year ago

Should I open another proposal to add offsets per sprite in AnimatedSprite2D or just close this one?

There are already proposals on the subject: https://github.com/godotengine/godot-proposals/issues/2060, https://github.com/godotengine/godot-proposals/issues/665

TinyMatt commented 12 months ago

I encountered a similar problem while exploring Godot for my next project. Let me explain what I wanted to achieve and how the pivot/offset attached to textures would fit right in.

I created a Scene that would be the base for each Unit shown in the game. When instantiating said Scene I would swap a texture to the one specified by the artist/designer. The Sprite2D would check for base offset set by the artist and adjust itself to match other elements of the Scene (like blob shadow, health bar etc).

Additionally, imho incorporating this into the Texture data could enable workflows that start outside of Godot (eg setting up pivot/offset in atlas creation tools) and feel quite polish.

abe33 commented 3 months ago

For those interested, I've started working on a PR that implements support for texture based offset and other improvements to sprites' pivots.