Godot: Feature request; Slow parenting

Created on 11 Jun 2018  路  20Comments  路  Source: godotengine/godot

The reason I bring this up, I've been reading the other thread about Reduz's idea of pushing things out of the engine. However, getting rid of the _Interpolated Camera_ node could cause a number of problems for people because Godot does not yet have the concept of slow parenting.

What slow parenting would do is instead of a child object updating its position instantly based on where the transform of the parent object, it would update in a way that is delayed and on a smooth curve. The amount of delay and the length of this curve meanwhile would depend on a user-defined value (the higher the value, the more delayed and the more smooth the response).

This would be useful for more than just camera systems though, it could be used for any setup where a delayed response is needed (such as a companion object for a character). Another reason for this is because having a perfectly smooth and curved response otherwise can be difficult to do in GDscript unless you are well versed in math concepts such as trigonometry.

Thoughts?

archived feature proposal core

Most helpful comment

What about an interpolated option to remote transform nodes?

All 20 comments

There's no trig needed for what you're requesting (or what Camera2D currently does), it's just the one-liner
position += some_speed * (parent.position - position) * delta

Sure it could be made more complex (varying some_speed with a tween say), but I feel like it depends a lot on the specific application.

The slow parenting ability proposed here would apply for both the 2D and 3D modes for Godot.

It would also be the same for rotations and perhaps even scaling as well (and because it's still related to parenting, the end transform of the child object would always catch up to where it would be under regular parenting if given the chance).

Then you would have the option of slow-parenting at different extents throughout an entire hierarchy of objects (allowing for complex, flowing movements with little to no code). That is not to forget that the delay parameter would be controllable by code as well.

It's not difficult to do, it's more or less the basics of game programming.
As explained by @isaacremnant that's a one-liner in most situation. And for more complex cases, such as camera interpolation, it will stil be available via the asset store.

Also, you've got the tween node to do so, and the brand new capture animation feature.

That one-liner though (posted above) only covers positional movement in 2D games (I'm pretty sure the 'tween' node is 2D only as well).

It can get more complicated in 3D games (especially if you want to add rotation to it, following it up with variable control of the delay). Besides that, I don't recall people pushing back against making it easier for Godot users to do things like getting an object to look at another or switching to a new scene (we used to not have functions specific to those).

Even the BGE has slow-parenting (and that community is quite aggressive about 'build it yourself' ideology).

I'm pretty sure the 'tween' node is 2D only as well.

No, it's a generic purpose node.

It can get more complicated in 3D games (especially if you want to add rotation to it, following it up with variable control of the delay)

That's handled by the new animation editor. And i'm pretty sure this could be easily achieved with a simple script, there's no need for it to be added to the core. Maybe the tween node can be adpated though, if it's not already possible.

Looked at the 'tween' node, it would sound like you could use it to interpolate between two values defined in code, but nearly every function is a bool?

I also don't know if the new animation editor would be a solution, a slow parent effect would be something that is ongoing and dependent on object motion and not something prebaked into keyframes.

In all, I really don't get why this should be controversial. If the developers want to remove features on the ground of being a little too 'specific' (converted to assets or worse, taken out of the engine and then sold back to us for a price), then we need features to help recreate whatever effects they provided and more due to being more generic _(slow parent_, as mentioned, would eliminate the need for the Interpolated Camera node without requiring a lot of extra code or a lot of trial and error testing).

When we say moving to the "asset store", it's just moving stuff out of the core. Such plugin will still be completely free & MIT licensed (for things we remove). Most of them will stay "official" by keeping it in a godot organization's repository.

This is controversial since people exporting games on mobile platforms do not want to have a 40Mb executable size for a simple 2D game. That's why most "too specific" assets should be moved out of the core, and made optional. This does not mean they won't be maintained.

Well, I made a quick attempt to rewrite the camera system for my project through use of the 'tween' node rather than the 'interpolated camera' node. I have to say, I had no idea where I was supposed to go.

Not having the interpolated camera behavior nor the slow parenting in the engine would mean a lot of users would end up thinking the same. Considering that Godot is an engine that is said to be making game development easy and fun, doing such a thing would mean the engine doing a huge amount of backpedaling away from that. Is trimming the file-size a little (barring a strip system) really worth making many common game mechanics much harder to do (especially one in nearly every third-person game in existence)? Then there's the fact that slow-parenting would a generic parameter for all nodes (as it would affect the fundamental relationship between it and its parent), I'm not sure if assets can do that yet (and even if they did, having it built in would likely be faster anyway).

Well, I made a quick attempt to rewrite the camera system for my project through use of the 'tween' node rather than the 'interpolated camera' node. I have to say, I had no idea where I was supposed to go.

The tween node is for interpolating generic properties, it might not work as is for 3D.

Is trimming the file-size a little (barring a strip system) really worth making many common game mechanics much harder to do (especially one in nearly every third-person game in existence)?

Donwloading a plugin is not "much harder".

Honestly I have the feeling that's you're talking about a feature you saw elsewhere but did not bother understanding how things works in godot. As said before, interpolation can be done with tween nodes, scripts or animation (on the master branch). It might need some tweaks to work with 3D positioning though. Please read to documentation to understand what it does.

In any case, what you describe is a very specific behaviour that needs to be used only on specific kind of nodes, and can be easily workarounded with a single line of script (I'm pretty sure an interpolation function exists for 3D transforms). So, to be honest, there's very little chance that this gets added to the core.

Regarding the one liner, you probably can do something like this:
$mynode.transform = $mynode.transform.interpolate_with($target.transform, 0.1 * delta)

Edit: probably global_transform instead of transform

I'm already beginning to figure it out, thanks.

However, it's definitely more than 1 line of code. At least though, it doesn't appear to be near as complex as I thought (though I'm not using the tween node or the animation editor).

I still see myself as a proponent of built-in features and node types though (mainly for reasons of performance and the ease-of-use in just having them whenever I download a new build). On performance, try writing a particle system in GDscript compared to just using the node for instance.


EDIT: I have this code down now

func _physics_process(delta):
       time = delta
       tween(2.5,5,3.75)

func tween(delayXZ,delayY,rotDelayY):

    var interpXZ = 10.0/delayXZ
    var interpY = 10.0/delayY
    var interpRotY = 10.0/rotDelayY

    position[0] += interpXZ * (parent_position[0] - position[0]) * time
    position[2] += interpXZ * (parent_position[2] - position[2]) * time

    position[1] += interpY * (parent_position[1] - position[1]) * time

    orientation[1] += interpRotY * (parent_orientation[1] - orientation[1]) * time

    var basis = Basis(orientation)
    set_global_transform(Transform(basis,position))

I was pleasantly surprised to see it just work for the camera's orientation like it did for its position.

In all, it functions about the same as the Interpolated Camera node, but it's definitely more than 1 line of code.

I was faced with a similar issue when I decided to move away from InterpolatedCamera so I could have the movement occur during the physics step, eliminating jitter.

I ended up using Transform.interpolate_with. In fact, it's the same method used internally by InterpolatedCamera.

In all, it functions about the same as the Interpolated Camera node, but it's definitely more than 1 line of code.

It is one line of code.

I just tested that:

func _process(delta):
    global_transform = global_transform.interpolate_with($"../target".global_transform, 0.5 * delta)

And it works perfectly:

output

What about an interpolated option to remote transform nodes?

@eon-s that's a nice idea, as a user of remote transform I must say I sometimes needed to use it together with tween before starting the remote following (not such big hassle since we can yield tween completion and then start 'normal' remote following, but still I think it would ease workflow for users)

What about an interpolated option to remote transform nodes?

I'd say the problem is that there are several ways of interpolating between several values, as the animation editor suggests. I'm not sure if it's worth adding such behavior in the core.
But why not, the RemoteTransform node might benefit from that.

I've implemented this in my current project by applying a script ("FollowOther") to a Spatial node, such that it updates its own global_transform based on that of a target node (ie. the reverse of what RemoteTransform does), with optional interpolation as described in this thread.
This means that any Spatial-derived children of such a FollowOther node will also move with the target node. For example, adding a standard Camera as a child would allow it to function like an InterpolatedCamera, but with even more flexibility since you can give the Camera an offset from the FollowOther node (eg. for "zooming" in and out).

I can also see the potential benefits of having the FolllowOther node affect its parent, rather than itself, so that the functionality could effectively be added to any existing Spatial-derived node in a component-like manner, rather than having to rearrange your scenetree hierarchy to fit it in.

I do think Godot would benefit from a generic node like this being available out of the box, but I think RemoteTransform is doing it the wrong way round - I shouldn't have to look through the entire scene to find out if one particular node is following another, and which node (or nodes!) it's set to follow.

Why does this need to be an engine feature? Can't you accomplish this by just keeping track of the global position, and interpolating that value towards the parent's position?

I use this in my projects.

look_at_from_position(transform.origin.linear_interpolate(targetCamPos.get_global_transform().origin, delta * followSpeed),player.transform.origin,Vector3.UP)

where targetCamPos is a Spatial child of Player at a certain offset and is used as a position where the camera should finally reach after following. Rotation feels smooth too.

Closing due to lack of support (see the above comments).

Was this page helpful?
0 / 5 - 0 ratings