godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.08k stars 69 forks source link

Allow users to set the origin of Control Nodes #129

Open golddotasksquestions opened 4 years ago

golddotasksquestions commented 4 years ago

Describe the project you are working on: Card game, Action game with items, menus.

Describe the problem or limitation you are having in your project: When working on menus, anything with drag'n'drop functionality, items, cards, or even a simple debug text label, I find myself in dire need to have control over the Control nodes origin every single time. I work with a Control nodes as well as those inheriting from Control, but Godot currently does not seem to offer a way to adjust the origin. rect_pivot_offset is not an option since it is an absolute value (pixels I assume), not a percentage. The default origin for all Control nodes is the top right corner. This makes centering and scaling and positioning incredibly tedious and unintuitive.

Describe how this feature / enhancement will help you overcome this problem or limitation: Controling scale, positioning and grow direction is currently a nightmare from UX perspective. It forces you to use multiple nested nodes and properties of those nodes and absolut pixel values. This proposal would reduce all that to just one single setting.

Personally I would think having the origin of Control nodes and Node2Ds work the same way would be the solution, even if they have different defaults (top left vs centered) and Control nodes having additional parameters like padding/margins.

Show a mock up screenshots/video or a flow diagram explaining how your proposal will work: control_origin

Describe implementation detail for your proposal (in code), if possible: I don't know any C++ Edit: Something similar has apparently been proposed and requested here: https://github.com/godotengine/godot/issues/19529 PR: https://github.com/godotengine/godot/pull/30305

If this enhancement will not be used often, can it be worked around with a few lines of script?: It's the first thing I would want to adjust every single time I work with any kind Node that inherits from Control, so yes, it would be used often.

Is there a reason why this should be core and not an add-on in the asset library?: It's mainly a (massive) UI/UX improvement of existing features.

hammeron-art commented 4 years ago

That's what Pivot Offset is for. The main issue is that it doesn't update automatically. It should work like size and margin which update when related properties change.

Predefined origins like the screenshot will add another limitation. It must be values. I do agree it could be percentages like the anchors but there is a way of implementing it without breaking compatibility. Keep Pivot Offset as it is and add Pivot Modes such as Keep Position (current behavior) and Proportional Scale (update pivot when related properties change).

golddotasksquestions commented 4 years ago

@hammeron-art No, my main issue is the user experience and this backwards design principle. Making Pivot Offset change automatically might help with the negative symptoms short term, but the inherently bad design of the user experience still prevails. No halve way decent software with layout capabilities has such an incredibly hard to grasp and seemingly pointless backwards workflow. And at the core of this all is the fixed origin position.

If the user does not want the origin to be in the top left corner, the user should be able to set it somewhere else.

If having it set to the top left corner is so important for inert engine reasons, then why for the love of transistors have it not this way throughout the engine, including all Nodes inheriting from the Node2D? This mixed system is really the worst of all options.

hammeron-art commented 4 years ago

If the user does not want the origin to be in the top left corner, the user should be able to set it somewhere else.

I'm not understanding your reasoning. The origin isn't the left corner but the pivot offset. If you want the origin at the center, set the pivot offset to the rect size*0.5. You would have to set the pivot once and the automatic update would keep it at the center when the rect size changes. It's the same effect as using percentage.

golddotasksquestions commented 4 years ago

Imagine a centered or right aligned Label you cast some text to. Every time the text length changes, the Pivot Offset value will have to automatically change as well. Do you think this is good design?

hammeron-art commented 4 years ago

I agreed from the start that percentage for UI is better. My suggestion of auto-update is just a way of keeping compatibility or if they are not interested in changing the current design. The size and margin already work like this so it makes sense to make the pivot works like this as well.

lentsius-bark commented 4 years ago

I'd like to chip in to say that even if the proposed solution is not the best approach, I do hope the pivot editing options gets an update for UI. I for one remember playing with horizontal and vertical growth and pivot position to achieve desired UI functionality which took me a lot of testing and fiddling, which done with percentages would have been a single click away.

vitorbalbio commented 4 years ago

I'm also having problems with that since there's no way to set the Control origin for translation other than the left superior corner. So i need to parent it to another control with size 0 that will work as a pivot point.

HybridEidolon commented 3 years ago

I am working on some controls for a game UI using the Control hierarchy. While the container system works great for conventional desktop UIs, the lack of an "origin" makes it difficult to use for Controls that are free-standing in screen space. For example, I want to be able to programmatically place a speech dialog at a specific location on-screen, with its origin being a point between two PanelContainers in a VBoxContainer. This is surprisingly hard to accomplish with the current system, especially if the Control changes size at all (e.g. the text shown resizes its sub-container).

kilojool commented 3 years ago

I also would like some way to change the origin of control nodes. If the pivot offset affected position also, then that would be enough for me. Not sure if that would cause other problems though.

hawkerm commented 1 year ago

I started playing with Godot a bit and wanted to animate some text rotating about its center-point. This was the first issue I encountered, was hard to find this thread too as I saw a way to easily set the anchor point in the UI, but no way to do something similar for the origin of the control. Finally after like 20 minutes stumbled upon the pivot_offset properties in the inspector.

kilojool commented 1 year ago

After a couple of years with Godot, I honestly think this is what still gives me the most headaches. ;) There are workarounds, like using a dummy parent node with size zero, or some containers also can do the trick, but I would prefer not to clog up the scene tree too much. For cards, arrows, and similar objects where the rotation and origin is generally supposed to be the same point, this would be a huge timesaver. Also simple things like resizing a control node while keeping it centered is really unintuitive if not using CenterContainer. A relative origin offset would likely make that so much easier too.

YuriSizov commented 1 year ago

For rotation and scaling we have a PR in works that adds an offset ratio on top of the pixel offset for the pivot center: https://github.com/godotengine/godot/pull/70646

gpergrossi commented 8 months ago

Hey I see this is really old, but I'm using Godot 4.1.1 and I'm trying to rotate/scale/center a label on a point. I just got a massive dose of "oh wow what in the **** is going on right now?" and I don't think I'm alone.

I set the label's pivot_offset to (width/2, height/2) so that it would rotate and scale around the label's center. And it did, but I still needed to set the position to (-width/2, -height/2) to get it centered. But...

What if the position was automatically offset by pivot_offset? It would act like a local origin for the sprite (I.E. offsetting the position before all scaling and rotation happen around the "origin", which intuitively is the position of the node). Now if I set my pivot_offset to (width/2, height/2), I am very briefly distracted by how doing so has just moved my label halfway up and to the left on my canvas. This might be slightly confusing in the wrong situation too, but I think less surprising and perhaps some people even expect it.

The way it works now is just not very intuitive. The position is at allegedly (0, 0) but no part of the label is even touching (0, 0) anymore. To pretend the label is at (0, 0) requires you to imagine the "original" bounding box. There's a better way that allows you to just mentally discard that "original", and it's still easy to configure the changes you expect.

That solution is to make the pivot offset affect the position of the label automatically. If I put the pivot smack in the middle, and the position is (0, 0), the label is going to be drawn with its center at (0, 0), nice!

I can argue more about how this is the least confusing option: Relative Pivots!

A number of other Godot fans here have expressed the desire for pivot offset to be defined on a scale from 0 to 1, so that changes to the label's size do not require an update to the label's pivot (I think this is so important!). But if you just go and implement relative_pivot_offset, then in order to center the node, you still need to subtract relative_pivot_offset * size from the position. This is cumbersome, right? But not if we already expect the pivot to apply an offset to position. Then we don't need to even think about centering, or right/left middle aligning, or top/bottom center aligning! The pivot becomes so useful!

So I really think the case for nodes being positioned such that the pivot_offset position always lands right on top of the node's position position is pretty solid. It's a +2 for intuitiveness in what I feel is a pretty common scenario.

EDIT: I now realize that changing the position of an element relative to it's position will break the layout code for all the container controls. I can understand why that would be too big of a hurdle, but I still think it would be nice to have relative offsets and automatic positioning relative to the pivot without needing a zero-size parent.

bitbendergames commented 4 months ago

I too vote for a relative pivot position in the inspector. This seems like very very basic UI functionality that many people (me included) need, judging from the amount of upvotes in the OP.

TGRRRR commented 1 month ago

I would love to have this feature too!

AThousandShips commented 1 month ago

@TGRRRR Please don't bump without contributing significant new information. Use the :+1: reaction button on the first post instead.

Meorge commented 3 weeks ago

Not being able to specify the origin/pivot point for controls (easily?) is one of the big frustrations I've continued to have while attempting to make game UI in Godot. I was directed to issue https://github.com/godotengine/godot/pull/70646 independently of this thread for the concept of pivot offset ratio and have been hoping to contribute to that or, at least, show interest in it and make it a higher-priority item.

gpergossi's explanation of the difficulties with the current system really echo my own thoughts. In Unity, I remember I was able to define any point on a UI item as its origin and pivot point, and then easily position (and animate etc) it based on that custom-set point. I've struggled to do the same in Godot.

Might these issues might be worth trying to combine into more of a general overhaul of Control node positioning? I recall Unity's UI tools in these areas being much more flexible than Godot's, so perhaps we could take some cues from it. I imagine this would have to be a change for a more major release, though, and with tools for translating old Control node setups to whatever new system is devised.

If there are any more concrete ways I could help with getting these improvements to Godot through, I'd love to try! My experience with the engine code itself, as well as layout algorithms like this, is... limited, to say the least, but I suppose that's true for anyone before they start getting experience.