-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add render transform to Control nodes #87081
base: master
Are you sure you want to change the base?
Add render transform to Control nodes #87081
Conversation
I remember Node2D has properties. Vector2 | position | Vector2(0, 0) How are these different? Edit: Will review the proposal. |
One could argue that both |
I've gotten so used to the bug it may as well be a feature to me. 5 years ever since it has been reported, too. This "bug" does have its advantages in the same exact way as |
@Mickeon yeah, that's why I added render_rotation. So if the bug with rotation gets fixed eventually, people who used it for animation can switch to render_rotation and people who want rotated controls to actually use more space can finally do that. Same for scale and render_scale. |
How this would affect children of the animated node, if at all? In our games we're usually animating whole control-based scenes or Containers, like a playing card or something, frequently containing both Controls and Node2D, so the whole thing needs to be animated as a unit. I currently achieve that by applying an animation transform to the node but only after any parent Container does its layout. |
@djrain the current implementation sets the CanvasItem transform of the Control node, so it affects all children as well. |
c5123f0
to
ff160eb
Compare
@AThousandShips thanks for the review 🙌 applied everything and fixed code style issues |
ff160eb
to
f7ce79c
Compare
@AThousandShips now it should have everything except the px suffix |
7b26c72
to
5eed27e
Compare
5eed27e
to
891f968
Compare
d068334
to
d8bdea9
Compare
d8bdea9
to
7e3e661
Compare
dcadbb1
to
1383ae0
Compare
950d99d
to
e7a7125
Compare
Two things:
|
71bbe62
to
ca88cf2
Compare
0d77a96
to
ebffead
Compare
ebffead
to
45ad111
Compare
45ad111
to
db92f85
Compare
db92f85
to
e6b33da
Compare
The general conversation from godotengine/godot-proposals#7053 seems to be the maintainers are divided on adding this. When there's a clear agreement pull requests get merged quickly, but with disagreement enhancements get stuck. |
I do really appreciate that @timoschwarzer has been keeping this PR rebased and up-to-date as much as possible. I'm not part of the team of interest, but I am one of many Godot users.My worry is the same as it used to be from the start. That is, nodes in general are not exactly light in memory and the additional overhead may prove problematic, given that most Control nodes do not need this. So the question to me always remains: is the trade-off worth it? Regardless, the feature is obviously very, very desired. |
@Mickeon would it help to benchmark the actual impact this change would have, especially in UI heavy projects such as the Godot editor itself? I think I could do that. |
I can't say benchmarking would do a lot for the people of interest, because there's still the question of whether Control nodes should be capable of this in the first place. |
I will be busy for two weeks now but will try to get some meaningful data then.
I would of course like to see more sophisticated ways to accomplish animations for Control nodes but so far the other solutions I have seen came with limitations and aren't as flexible while I do see and have had use cases to animate both Control and Container nodes. When you say "more satisfactory", do you tie that directly to "not having render transform properties on all Control nodes"? |
@Mickeon I finally did some benchmarks: BenchmarkSample 1: Master branch at 1fc8208 For each sample, I launched the editor into an empty project, let everything load and then closed the editor again. Then I launch the same editor executable with a profiler, let it open and close it again. Each sample was profiled three times, the results per sample were roughly the same. System:
Compiled with scons platform=linuxbsd target=editor production=yes linker=mold lto=none debug_symbols=yes Profiled with: valgrind --tool=massif ./godot.linuxbsd.editor.x86_64 -e --path /path/to/empty/godot/project ResultsSample 1 (master branch): Sample 2 (this PR): Difference: |
e6b33da
to
48bcad0
Compare
I think this is the only way to reliably animate Control nodes inside Container with AnimationPlayer when their size is undetermined. Which is nice, but I think such strict requirement is not that common. There are multiple workarounds and if all fails, you can use Tweens. That said, I think there is a way to have this feature without much overhead (currently, aside from memory, it also makes transforming more complex). The Other than that, since this is purely visual, should these properties be serialized in the scene? Especially with the input problem you mentioned? The new properties should have their purpose documented in Control's class description (i.e. that they are meant only for animation). If the usage is optional like I described above, and it's properly documented, I think it might be fine to have this feature. EDIT: EDIT2: |
Warning: personal opinion and experiences. 🙂
I must completely disagree with your statement about this not being a common requirement. In every project so far that involves UI, a feature to apply a render transform to Control nodes of different kinds would have made things much easier to create. And it already helped a lot since I use a fork with this PR applied. Yes, I could have used Tweens for many of the things that I animated, but next to not being able to react to transform changes in parent nodes, Tweens just cannot hold up to the iteration speed and quality that AnimationPlayer gives. Being able to change animation easing curves and previewing them with one click - or even using Bezier curves - is a huge reduction in effort that I need to spend to get the same results in comparison to using Tweens. Looking at the reactions to this PR and the proposal, I don't seem to be alone with this opinion.
0.18% more memory usage in the most UI heavy Godot project that I know of (the Editor) still does not sound like much overhead to me, but a solution like you pointed out sounds like a good compromise, if it's really a concern.
I would agree immediately if Godot had some kind of slot mechanism that lets you define where children should be inserted for instanced scenes. Too often have I been at a point where I got screwed by this to be able to agree here right now. I have had dozens of such cases where this deep nesting of controls prevented modularization of logical Control "components" into separate scenes. I cannot tell immediately if this would be a problem if render transformation is achieved using Containers. |
Soon: #84018 |
Just to give my two cents: I think this feature is invaluable, to the point that I had already implemented this myself locally (though just for offset, not rotation). I've been using this PR for several weeks and have found no issues with it. My only feedback is about making the "relative to size" toggles default disabled, to keep them in-line with how transforms work everywhere else (that being in absolute pixels), and because positioning in absolute units is much more common in my experience. I agree that rotating around the center is the most common case for the rotation pivot, but at the very least I don't think that decision should effect the transform offset (and should probably also include similar changes to the basic pivot offset unit for consistency). |
48bcad0
to
be24431
Compare
For the ones interested in this feature, see and give feedback to the following alternative as well: |
be24431
to
7c5e2ec
Compare
I'd like to keep pushing for this PR a bit, so for anyone reading/catching up, here's my thoughts to try and pull together the current state of things:
Another major thing standing in the way of this PR is adjusting how the properties are shown in the inspector to make them a bit cleaner. In my opinion, the nicest way to do this would be to format the options to have parity with the existing Transform category for Control:
And to the extent of supporting parity, I'm tempted to favor removing "offset_relative_to_size" and "transform_pivot_relative_to_size" as well -- primarily because "offset_relative_to_size" can already be false in most cases, and we already expect developers to manually set the Control's pivot offset to |
@dog-on-moon I agree that the inspector properties should be more intuitive to use, like with transform properties.
I'm not so sure about this one. I feel like rotating and scaling around the center is a very common use case for animations (which this PR mainly targets), if not even the most common use case. Having to manually update the pivot every time the control size changes sounds like a lot of boilerplate that I'd rather not want to be needing to do for every single control. Dynamically sized controls are quite common, e.g. for Labels or Buttons with translated strings. It wouldn't be an issue though if there was something that could keep the pivot at a certain relative position of the control. |
Yea.. I do completely agree with this being the most common use case. I think I have nitpicky concerns either way:
To try and make point 2 more intuitive, I tried exporting a After some thinking I believe I am in favor for breaking parity here and keeping the pivot offset as relative to scale. But I could still go either way, I would like for a maintainer to make the call here. |
Another thing where we have relative values similar to these here are anchors, but there we don't present the value as percentages in the inspector. |
Regarding the percentage, we should stick to using values between |
This is an implementation of my proposal outlined in this discussion: godotengine/godot-proposals#7053 (comment)
tl;dr: Currently it's hard and complicated to animate Control nodes without breaking the layout, especially if the Control nodes are in deeply nested layout structures which is often the case. This PR adds new properties to Control nodes that specify a render transform that does not affect and is not affected by layouting (similar to CSS'
transform
). These make UI animations much less pain to work withrender_offset
: translationrender_scale
: scalerender_rotation
, rotationrender_transform_pivot
, pivot for scaling and rotatingrender_offset
andrender_transform_pivot
are relative to the size of the Control node by default (I think it's a very common usecase to rotate around and scale from the center) but it can be toggled to use absolute pixel values instead.Screencast.from.2024-01-11.17-10-13.webm
Considerations
Input is currently not affected by the render transform. That means if you e.g. apply a render offset to a button, the button is still clickable at its original position but drawn somewhere else. This might need some discussion whether that's desirable or not.