-
-
Notifications
You must be signed in to change notification settings - Fork 97
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
Bring Tween Node back and Merge it with current Tween #7892
Comments
By the way...maybe just port this to core? |
I don't think we should have two ways to achieve the same thing in core. This is what add-ons are suited for 🙂 |
Isn't that what we have with I mean, there are plenty of situations where you can achieve the same thing in multiple, not just two, different ways. I could cite at least five out of my head:
And we can keep going, but the thing is: we used to rather use Nodes than functions. This was the whole Godot Engine design. But the thing is: in this case specifically we can just merge the two into a Node, we don´t need to keep the current Tween RefCount after porting it as a Node |
Ok, I am only using tween using create_tween(). but the idea of this proposal I think is valid, due to how Timer Node works. and I think this will satisfy both who use create_tween() and Node approach. |
@henriiquecampos Your first code sample almost certainly fails because the variable declaration is missing a @onready. And your code with the proposed node will not work, because it is also missing a @onready. So there is literally no difference between these two versions. Edit: I hope there is no user on GitHub with the name onready |
I tried to using |
There is one, otherwise the bold clickable link wouldn't appear 🙂 |
@henriiquecampos That is odd. But it makes no difference. You can still use the original version. Declare the variable globally but don't initialise it (or initialise it to null). Then assign the tween to it in the function like in your second version. Still doesn't justify adding another node type IMO. onready must be really annoyed with Godot by now. Sorry! |
Ohh man...I definitely wouldn't be wasting my time if things were working as they used to, look: Note the tween is an object in the reference as seen in the debugger. It just don't process, so the Tweener that it should return from the Please understand, if it was working nice and smoothly as the Tween node used too, I wouldn't be as frustrated to the point of opening this issue. |
I remember that the new Terrains system was considered a bit of a Godot anti-pattern just because it having the layers as inspector variables instead of nodes. I don't understand why we should ignore the nodes system this time. |
this is what i've been doing succesfully on my project (keeping references to tweens once they're started, and then stopping them if they're valid and running), and it works fine. It's a little weird indeed compared to the old behavior, but you get accustomed to it (not all tweened animations require to be stopped). So i'm voting against this proposal. |
@francoisdlt would the implementation of this proposal prevent you from keep doing this approach? |
I think having "TweenPlayer" node could be beneficial. A node for managing multiple tween refs for nodes to interact. With this way, both current refcounted Tween and node version of Tween manager can have reason to exist with eachother. |
Something I just thought about is that to prevent "breaking compatibility" the So.. I think the whole interface of the current class could be ported to a Node. I mean, I'm struggling to understand the resistance to make this switch(not only here but the twitter's threads as well) |
Having multiple ways to do the same thing leads to bloat. It increases the code size and thus maintenance costs. It increases the binary size. It increases the documentation size. It increases the cognitive load on developers who have to choose between multiple APIs. Ideally there should be one way to do it and only one way. |
As shown in this reply: I don't think this is a valid reason to not have this proposal implemented, but on top of that, I'm not proposing to have two ways to do the same thing, the title is clear: merge the current Tween into a Tween node. The proposal suggests to have only the Tween node. But if this is not possible, supporting the two approaches shouldn't be such a hardache because, again as shown in the reply, "having two ways to do the same thing" is just the default Godot approach, especially turning one of these ways into a Node-based approach, as suggested in this proposal. |
While I do agree that we need a more reusable way for Tweens, and that the TweenNode accomplished that very well, it's not impossible to replicate it's behavior with the current system. The docs clearly say that tweens start working as soon as you create them, so doing What I do to replicate the TweenNode behavior is also in the docs, keeping the tween variable and checking if it's empty, then if I want it to reset I use stop, if not, just kill. But you have to always kill the Tween before doing a new one:
This has more or less always worked for me and it's basically the same as keeping a reference to a TweenNode, I don't get the need to do for loops on the tree to search for all the processed Tweens. |
I do understand that there are "work arounds" for this issue. But take a moment and assess: that: is this intuitive? Is this as intuitive as having a node(remember the Godot's design of using nodes as building blocks to create games with Godot). But on top of that, look at this logic: "I need to interpolate a property and at some point I can receive a new target value, so I need to stop the current interpolation and update it to aim towards the new target value. For that I need to: create a null reference for a variable type of tween, create a custom function that will stop the tween, even if it didn't even start to begin with, just to maintain a reference to it so I can use it later on, then I can actually play the interpolation but I have to ensure that it NEVER ends, because if it does, I will lose reference to the tween I was using to interpolate the previous value, and if at any point I need to interpolate another property I have to ensure that I stop the tween, even tho I may want to have the previous interpolation going" Previously the line of thought was: I need to interpolate something, there's this node that is specialized in interpolations, I'll add one as a child and use it, when I receive a new value to interpolate to, I can stop the current track and interpolate to it instead. Please correct me if I'm wrong, but just because we have workarounds to achieve the same outcome, it doesn't mean we can't improve things, right? I mean, we can create games with assembly, but we use an engine because it provides easier and higher level approaches to create these games without us having to re-invent the wheel. Besides this code you've shown works, and it probably has been working for you, imagine if instead of having a Sprite node you had to do something like: extends CanvasItem
@export var texture
@export var position
@export var rotation
@export var scale
func _draw():
draw_texture(texture, position) Imagine not having the Sprite node, or any of the nodes mentioned in #7892 (comment) Imagine not having the SceneTree and having to implement an engine processing loop by hand. Imagine not having a user interface like the Godot Editor and having to do everything via code without visual feedback. Imagine not having a user interface and having to create animations via code. Do you understand this proposal is not a cry saying "it's impossible to do tweens in Godot Engine 4.0"? But instead it's a proposal to improve the way we do it because as it is it's not as intuitive as it was or as it can potentially be? |
@henriiquecampos It's not a "work around". It's the intended use. It's in the official documentation: If you want to interrupt and restart an animation, consider assigning the Tween to a variable:
This is how it would look with your functions:
It's not much different from what we did with the TweenNode. You also had to store a reference and check if it was running or active and stop it or pause it. I don't see this argument as a need for adding a TweenNode. You use the Sprite node as an example that doesn't require code to work, and that makes it practical and in line with Godot, but the Godot 3 Tween node is kinda opposite to that, it does need a script to be used, just like the current Tween |
@henriiquecampos I would like to have a TweenNode for having more ways of doing the same, as you said here: #7892 (comment) But the new tweens can still accomplish the same as the old ones. I have many scripts making use of the new tween just like the old ones, and they all work as intended. I just want to make that clear. The documentation has a pretty decent tutorial/explanation on how to use them, with common use cases addressed, it's in the tween class page I also see how they are a bit more confusing if you're coming from Godot 3 (I was also confused when I first transitioned), but they are more intuitive if you think of them as only one animation each, and more in line with other engines. They are also designed for working quicker, since in Godot 3 they needed to have both a Node and a script, now they only need a script. |
Another argument could be allowing TweenNode to work without the need of a script, which is the purpose of the Timer node when I use it or the other nodes alternatives. This also allows for them to be reused when saving scenes instead of copy pasting code Something like a simplified animation player for only one thing? Or maybe you would need to write an expression? Then you can add that TweenNode to any scene and make the parent do the animation when a signal fires... Not really sure how it would work but that could be a very good reason to have Tween nodes |
@henriiquecampos |
@CarpenterBlue That's not really a solution. You would have to do TweenNode.tween to access it, and it still behaves the same. You would still need to kill it and re create it each time in your script. The original Tween node was made to support multiple animations, what you propose only supports one so you would need to make a new node for each. To make a proper Godot 3 tween node, it would need to store each created tween operation in some kind of dictionary, and properly manage them. Then you would access them by the object and/or property name to stop them. Like #7892 (comment) said, a Tween node should serve the purpose of managing a group of tween animations in one place |
Just to give you guys a starting point as to why this change was made I think it's worth linking to the original proposal: #514 It explains the new features, but it also explains why the node has been removed (short answer: it doesn't serve any practical purpose because nothing is exposed on it and there is no dedicated editor for it, you still need to write code — now more than ever with the advanced sequencing features). |
I think then the solution would be to exposed some properties like the Timer: process mode, easing, transition type, duration, autostart(maybe implement it?), etc... Would be way easier than revamp the whole thing and break compatibility, no? Maybe creating a cool UI like MultiplayerSynchronizer, AnimationPlayer, etc... |
I'm not sure why you're drawing a comparison like that. The rework was done to add new functionality to the class, none of which can be exposed as properties. And the properties that you are listing — nobody asked for them, so why would anyone consider exposing them? Besides, exposing them is not an alternative to the features added...
The first 3 are unique for each tweener, the last one is not how you normally use tweens. They just have different use cases compared to timers, even if sometimes you can use them similarly. |
I'm comparing the two because this is the whole point of this proposal. So you're saying the new functionalities couldn't be implemented in a Node? If nobody asked for the functionalities I pointed why they are in the new approach? If nobody uses nodes in autostart mode why the new class literally autostarts and the whole issue is caused precisely because it starts without anyone deliberately saying so, triggering its removal and losing reference to it? I really didn't get the whole point of your reply. Please help me see your point. On top of all that, the new approach makes a pseudo Node already. As mentioned in the documentation, the Tween is added to the scene tree, it has process and physics processing like only nodes have in Godot, and supposedely(as mentioned in the replies above) you should create it in the Why making it so similar to a node yet not making it a node if making it a node wod keep compatibility and prevent the current issues? |
The new Tweens don't "autostart" nor "start without anyone saying so", and you do not have to create them with the onready keyword. They are not meant to be just a code replacement for the old Tweens, please properly read how the new Tweens work before criticism them. The documentation is quite clear, and the original proposal is also there. What you're complaining about in the quote and other parts of this proposal comes from not understanding how they work and forcibly using them as the old ones. I already explained how to get the same result in my other comments, and it's pretty much the same amount of lines and usability as the old ones. Think of them as a single animation that can have multiple tracks each, meant to be discarded as soon as it finishes. They are only meant to be created in a function, so you always have the code that made them. They only start when you finish creating them, so you just call the function when you want them to start. You store a reference in a variable if you want to check their progress or cancel, pause, reset them, etc. To compare the old way vs the new, you have to understand how both work. Do you want to keep working the old way or to have a new Tween node? Those are two different things |
note that most of the functions are the more low level and simplified version of the same functionality without some overhead. which both alternatives needed in different use cases. The Tween Node removed because there were no additional usability nor interesting inspector properties as stated in #514. And you still need to write code to set it up anyway.
cmiiw this is the norm for tween behavior in other engines. DoTween in Unity is also auto freed when tween finished. Otherwise it will gives memory leak. I think what you want from the old Tween Node is its reusability by not set the tween to be autokilled. And as a node, it will be freed when the node or its parent is freed. So we need both.. But for the purpose of reusability of Tween, i think add ability to set off autokill would be better solution just like DoTween has Tween.SetAutoKill(false) |
As a side note, for those who want the exact same API as Godot 3's Tween, I have a GDExtension that implements this via the Threen node. I just updated it to make sure it works with Godot 4.1+: https://github.com/akien-mga/threen/releases/tag/1.0-stable The purpose was to help people migrating from Godot 3 to Godot 4 to reuse their existing Godot 3 Tweens, but if some really want to keep using that API going further, this extension should help. That doesn't mean we can't improve the current Godot 4 Tween API and bring back some of what people liked about Godot 3, I just mention this as a usable workaround for people who want it now. |
I did read that and understand that which doesn't mean I think this is better than having a Node. This is what is been missing in this whole thread all along: Just because you use and understand the new system doesn't mean it can't be improved. |
Continuing to misuse it in examples doesn't really help your argument. The impression it gives is that you do not understand the current API which is why many of the responses have been to correct your mistakes and show the proper way to do it with the current API. To better make your argument, you should present 3 sets of code.
Then you need to express how your proposed changes are an improvement. |
I sort of did this here #7892 (comment) and in the original proposal(where I showcase how I managed to achieve the desired behavior with the new API) |
Here is your last code snippet from that post. It uses the API incorrectly. You prefaced this by saying extends Node2D
var tween
func _ready():
tween = create_tween()
tween.stop()
func _unhandled_input(event):
if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
var tweener = tween.tween_property($Sprite2D, "modulate", Color.BLUE, 3.0)
tweener.from(Color.RED)
tween.play()
func _on_timer_timeout():
queue_free() There are two mistakes:
The correct way to do this in 4.0 is below. extends Node2D
var tween
func _unhandled_input(event):
if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
tween = create_tween()
var tweener = tween.tween_property($Sprite2D, "modulate", Color.BLUE, 3.0)
tweener.from(Color.RED)
func _on_timer_timeout():
queue_free() |
New Tween API is overfitted for making sequential, non interuptable tweens that execute once. Unfortunetly this use case never manifests in our games because "uninteruptable" promotes a user experience that does not live up to my quality standards of reliable instantaneous feedback to user input. ie: Closing a dialog while it is playing it's Open animation. Now again, but this time the Open animation is several tweens, with several layers of paralellism. Old tween API allowed this easily as it naturally allowed 'grouping of tweens', new Tween API simply falls over when challenged with 'interruptibility'. Yes, it is doable, but the resulting code is full of boilerplate and esotericism.
Godot is praised for keeping a consistent design on 'everything is a Node'. But now, there is a small secret, a leak, a flaw, where there is now a third type of object: the Tween. Now we have Node, Resource and Tweens. Tweens are a new, third thing, something that has it's own lifetime semantics, there label as a 'Reference' is not be trusted, for they can be a valid reference yet an 'invalid tween'. Explaining what an 'invalid tween' is is so obtuse that it leaks it's internal design. One cannot simply use a SceneTreeTween, one must know that it is a handle to some other system and invalidates itself at the end. This core piece of knowledge must be remembered at every usage of the API. New tween's lifetime semantics are so foreign to the rest of the engine that it must introduce a new word: "kill()". Keep in mind that even HTTPRequests are a Node in godot, and it becomes crystal clear that Tween was a mistake. I truly wonder where Juan's vision was on the design of this new thing, for he seemed to have such a strong vision for Godot, yet Tween is so incongruent to it. I have learnt to bend the new tween API to my will, but it's obtuse, esoteric and repeated in many files: Group some tweens:
Repeated everywhere boilerplate:
Little known hack that prevents tweens from invalidating themselves:
imo basically every tween that you create, must allow itself to be instantly stopped. ie: Opening/Closing a dialog. If a user presses the close button while the dialog is opening, the open tween must stop, and the close tween must instantly start. How would the designers of the new tween API implement this simple, core use case? The concept 'fire and forget' never manifests because you can never forgot, every frame of animation lives under the game designers control during it's entire duration, because we must allow user input to have instantaneous feedback. One cannot simply 'forget' about a Tween that has been started, and because of this, because the new Tween api overfits itself to an inferiour user experience, I must maintain far more boilerplate bookkeeping throughout our projects in order to use the new tween api. Listen, I dont want to hurt anyones feelings. Some people have clearly worked hard on the new Tween api, and I respect those people and their efforts. Dont take this personally: new Tween api was deeply mistaken. I know there's probably no going back, but I fear this will cause a fracture in Godot, where libraries like Threen become semi-dominant. |
Why do people keep repeating the "everything is node" mantra? I don't think it was ever true and it's slowly being phased out of the engine anyway. In fact the docs have a whole article about how to avoid using Nodes for everything. |
var anim_tween: Tween
func open():
if anim_tween:
anim_tween.kill()
anim_tween = create_tween()
anim_tween.tween_property(dialog, "size:y", 100, 0.5)
func close():
if anim_tween:
anim_tween.kill()
anim_tween = create_tween()
anim_tween.tween_property(dialog, "size:y", 0, 0.5) What is the equivalent in Threen? |
Thanks for the writeup.
|
Right, so for this simple use case they are pretty much the same. I am the person who designed and implemented the new Tweens. The new system is heavily based on DOTween, which is a popular tweening addon for Unity. As much as I hated working in Unity, DOTween was one thing I really liked and it was so much better than what was in Godot. Before rewriting Tweens, I made a GDScript addon which I was using instead of the old system; it had pretty much the same API as we have now in core and it proved really useful. From my experience, almost every animation you want to do with a Tween is sequential, which in the old system was hell to write. Refer to the old proposal, which explains the problems with old Tweens and how new system solves them: #514 There was a great deal of community feedback involved when the new system was made. The reception was overwhelmingly positive (implementation PR for reference: godotengine/godot#41794), while the reactions under this proposal are not really in its favor... Going back to the old system is out of consideration for that reason (and many others), and personally I'm staying out of this discussion (well, except this comment). The little known hack you mentioned was actually documented in the past as a way to reuse Tweens, but since people were abusing it, the Tweens are officially not reusable now. I actually have an idea how to make them reusable, but I have yet to see a case where it's more convenient and/or fixes a performance bottleneck. Also I don't recall anyone opened a proposal for that. Custom editor for Tweens is still very much doable and I actually have an idea for an addon that would add it. For now there are no plans to have it in core, because there is no demand. |
I want to reuse them so I dont have to re-run the setup code that creates tweens.
This is huge. Let me explain: We have performance problems with basically every single line of GDScript that runs on a per frame basis in our lowest end target platform: Mobile Web. We have 30% of our web users using mobile devices. We're talking tens of thousands of devices every single day. The web is a massive new burgeoning market for indies, and 30% of the users there are on mobile. It's a bigger market in terms of raw player #s then mobile, console and PC combined. Godot has an advantage here over Unity, and it would be Godot's error to not see and foster that capability. To develop further into this world, Godot must strive for optimal performance. Memory allocation has a large cost in WASM. I have sought out and eliminated even String(), even StringName() allocations in the per frame tick of our products. I have spent literal weeks finding and hunting down basically all GDScript that runs at runtime. Basically every single line of GDScript that runs in a per frame, per object basis is not capable of meeting our standards for performance in the WASM runtime. If I can re-use tweens, then I can set them up in GDScript. If I can't, then I simply cant write the code for them in GDScript, because its too slow to run on a per frame basis for our use case. Even the construction of the string to reference the property by name is too slow for our target platform. Not only does creating a String() allocate memory, but it iterates each character, converting it from a raw char to a wchar, one character at a time. Even writing "hello_world" in a per frame basis on a player's renderer is a deal breaker for mobile web, let alone using the scripting system to turn that string into a property reference. I love GDScript, but for certain projects on certain platforms, namely the web platform, GDScript is way too slow. To summarize: If I can't reuse the tween setup code, I can't write it in GDScript. If I can re-use the setup code, I can write it in GDScript. |
You are right about this, and this temptation has led me to use the new Tween api. I think the new Tween API had a good intention. It has a good raw tweening interface, but everything around that tweening api is a step backwards. It should have stayed within the constraints set out by the existing archetypes in Godot, namely Node or even Reference. If you really wanted it to not be a Node, it should not invalidate itself while there still lives a Reference. In my opinion, it should have stayed rooted in a Node. There are so many benefits, which I outlined before. Namely, the removal of 'invalidating itself' and the implict 'grouping of tweens'. I forgot one in my previous post: process_priority. In Godot 3's SceneTreeTweens, they always happen first, before other code, and I have no clue what order they happen in between each other. For things like player and camera movement, you need to be able to control what happens in what order. Tween as a Node allowed this implicitly, the new Tween api has no concept of intra-frame ordering. These issues of what was lost in the redesign pile up over and over and it becomes clear to me that the redesign was too liberal and too experimental. I haven't even bothered to figure out what order Tweens happen in in the new Tween api, because the 'gain' of using the new abstraction is out weighed by the cost of me having to figure all this stuff out. EDIT: Just so were clear KobeWi, I respect and value your work. I wish I had commented on the Tween proposal when it was announced, but Godot 4 was not something I could invest my time into until the web platform exceeded Godot 3's capabilities. |
The invalidation is needed to automatically remove Tweens from processing. Basically you start a Tween and when it's start processing, SceneTree will clean it up. The invalidation happens at the end of animation, it's all documented.
You can make the Tween process in either physics frame or process frame. But yeah, the processing happens at the end of the frame and there is no way to control that (btw this is the same behavior as SceneTreeTimer). However tween processing is an enum, so adding values for something like EARLY_PROCESS and EARLY_PHYSICS would be easy. Would that solve your problem? Also I don't get the argument about "per frame" allocations. Are you creating Tweens per frame? Why? |
I often get away with ignoring the kill part since the tween gets invalidated anyway and tweens added later that are tweening same value have priority, This should be enough for something this simple no? var anim_tween: Tween
func open():
anim_tween = create_tween()
anim_tween.tween_property(dialog, "size:y", 100, 0.5)
func close():
anim_tween = create_tween()
anim_tween.tween_property(dialog, "size:y", 0, 0.5) In regards to the get_tree().remove_all_tweens(node) Though, I don't really understand why do people seem to need it. People, you can just have classic |
Not necessarily every frame, but what I'm saying is that running the tween setup code is expensive and being forced to re-run the setup code is a significant problem to us. A huge factor in that cost is the memory allocations that occur when running the Tween setup code via GDScript. |
It would be a good idea to get a few examples and profile/benchmark them. To demonstrate the issue more vividly, if nothing else. |
It's weird how much attrition we need to request to bring back a feature THAT ALREADY EXISTED while nobody saw any issue completely rewriting the Tween system breaking compatibility and breaking the Godot's design philosophy. See: godotengine/godot#41794 People just thought "yeah nice, we have new features? Parallel execution(something 100% possible with the previous system) JUST DO IT!!" Meanwhile, here we are debating to bring back a 6 years old feature that had thousands of projects reinforcing its effectiveness. Did anyone request a profile/benchmark to overhaul the system as well? Honestly would make way more sense. IT WAS AN OVERHAUL AFTERALL |
Why being "compliant" with a Unity addon would make anything better? I mean, I'm on Godot, I like using Nodes, it's the engine's design philosophy. I'd much rather set up a node through the inspector than have to ensure every time I interpolate something it will use the physics process. It wasn't a hell to write sequential animations, you just needed to use How do I make specialized Tweens in this new system? Ohh I'll have to make a Node that instantiates these Tweens, even tho these Tweens behave EXACTLY as if they were nodes, with the drawback of being refcounted so I can't simply wait for the time I would actually use them, I have to somehow keep them in memory with weird workarounds instead of having them visible on the SceneTree, both remotely and in the editor. |
...Honestly, look how much effort you are making to get something that we had effortless before. Bound a Tween to a node(even tho this Tween already have its own life cycle, that works exactly like a node, with the downside of being removed if we don't manually keep it in memory due to being a refcount) makes the Tween effectively IDENTICAL to the Tween node we had in 3.0. Literally everything you guys are pointing out just justifies making this approach a node, effectively bringing back the Tween node and merging it with whatever advantage this new system has over it. I mean, for real, no butthurt, what are the actual advantages of this new system? Anything a custom method wouldn't solve? Like, for sequential animations, maybe have a Tween.interpolate_sequence()? |
Let's keep it professional and on-topic and not get mad over a software. These arguments feel like they are made in bad faith, you misconstrued much of what you responded to.
The proposal was unanimously liked. Part of the governance philosophy is that if we can't get near-universal agreement on a big feature, we won't implement it. The tween rework had it, this proposal doesn't. So we're bargaining, maybe you have a valid use case, you need performance of Tween nodes or something? We want to see you justify yourself so maybe we can get to a universal agreement about at least some kind of problem needing to be solved.
People are making thousands of projects with the new tween too. People use tweens when they do what they want, regardless of whether the implementation is good.
Nodes tend to have a lot of baggage around them, they are a far more heavyweight object than RefCounted, so in all likelihood the new system is faster in most cases. But anyway, as discussed above, the proposal was focused on usability, so people did not focus on profiling or benchmarking. Performance did become a focus of this discussion, so we're focusing on that. There's no bias, just context.
It's a cherrypicked example. When moving my project to 4.0, all of my tweens became way less code than they used to be. I do miss the ability to keep tweens around, but that's not much of a problem either. |
For a claim that there are performance issues? Yeah, we absolutely need an exhaustive set of data. We need to look into what's going on, if there are suboptimal hotpaths, if there are bugs in the implementation, if there is a wrong assumption by user which can be clear or directed with better API. |
@MewPurPur right, sorry if this was the tone I went to in the previous messages.
Correct me if I'm wrong, but the proposed workarounds(making a Node to hold Tween code and bounding it to a node effectively increase the resources load since now there will be a RefCount and a Node instead of just a Node, no?
Why did it suddenly become a focus of discussion? I mean, nobody mentioned it in the overhaul and nobody mentioned issues with Tween performance when it was a Node. It seems to me that it is just a way to put a wall and deny the proposal. Bringing the Tween Node back, for instance as an independent class, wouldn't prevent anyone from using this approach. So...people could choose the approach that better fit their projects, including if performance is an issue. We can have TweenNode and the Tween[RefCount], I can't see why not.
Through the discussion, the sum of "cherry-picked" examples build a lot. There are many examples where we need to come out with weird workarounds. The very implementation of the new system presumes it should "work like a node". I mean, I already pointed out: its life cycle, bounding to a Node, etc...it was made like a Node and even has methods to become part of a Node, so we can get the advantages of it being a Node. So why not have a Node already? Fundamentally, what would change in anyone's life if we had a TweenNode to keep up with the original design and the new Tween system to support those who would like to use Unity but are now on Godot and miss Unity's approach to stuff? I pretty much think we can have both, as we do have in many other instances, mainly the Timer node. |
For reference, there were debates about Tween chaining, and back then, people agreed the current tools we had were enough. |
So, look at this: https://github.com/godotengine/godot/issues?page=3&q=tween+performance Tween node's performance was never an issue. So why should it block bringing it back? |
Where did you get the idea that performance is blocking this suggestion? A performance issue was brought up before as a downside of the current approach. I asked for a demonstration of the issue so it can be investigated. PS. Also, please use the edit button. |
You have to understand, I made these suggestions only to help you alleviate your pains with using the new system and at least partially bring back your workflow. I treat the tweens as fire and forget thing and I personally don't use any of these suggestions as they are simply not needed. |
I think a big part of this debate is about when a feature should be implemented as a Node in Godot. There seems to be no clear rules, so I opened a thread here to discuss about it: |
For people who want Tween Nodes: would Capture in AnimationPlayer be a good alternative for you? #8513 / godotengine/godot#86715 |
Yes and no. IMHO they have different use cases |
Describe the project you are working on
I'm working on a Multiplayer Online Adventure game implementing interpolation techniques for lag compensation.
Describe the problem or limitation you are having in your project
The current Tween is way more intricate compared to the previous approach and brings up unnecessary steps to achieve things previously trivial, such as accessing and stopping the Tween. For instance, this doesn't work as it doesn't create a tweener for some reason:
But this works:
And since the tween reference "only exists" while the function runs, I can't do this:
Instead I need to do this:
Which stops other tweens not related to this behavior, so I need to add some filtering to find the actual reference to the tween I want.
On top of that, this new approach breaks the engine's design of providing NODES as building blocks for creating games with Godot Engine, so a Tween node would keep the design consistent, as it was in 3.x.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
With a Tween node I could just do this instead:
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
The idea is to turn the current Tween into a node that would expose some properties in the Inspector, making it easier for us to configure some settings, such as the process mode, duration, ease, transition, etc...
If this enhancement will not be used often, can it be worked around with a few lines of script?
Tweens are fundamental for game development, so this would be used often. Especially because now we have access to
Tweener
s these two classes would make things very versatile and would be used often.The workaround for the current approach is to create a whole Node that performs exactly what the previous Tween node did in version 3.x, but is now implemented manually which can cause lots of issues since not every user, me included, knows the proper approach to implement this manually. You guys are the best folks to implement a feature...that you guys already implemented previously.
Is there a reason why this should be core and not an add-on in the asset library?
Yeah, it's part of the engine's core design to use Nodes, not intricate functions as if we were developing in FP. On top of that this feature was in the previous versions of Godot Engine, so technically this is a regression of the core engine's code.
Edit by the production team: added syntax highlighting to code samples and changed tabs to spaces
The text was updated successfully, but these errors were encountered: