Godot: Tween function for single axis position/translation

Created on 4 Apr 2017  路  13Comments  路  Source: godotengine/godot

Godot 3 got better property access, making possible to move a node with something as simple as translation.z += some_float.

But Tween still does not have access to a single axis, it can only interpolate full translations or positions limiting the use of interpolation to full translation; if Tween is able to interpolate a single axis, it will allow more complex animations.

I don't mind general vector item interpolation but only single axis position/translation for nodes, because these are the most used and may have their own complexity if involves transform.

ps: this could be a new method, like interpolate_axis, no need to alter the regular property access.

enhancement core

Most helpful comment

I want to provide a concrete example for why this would be a useful feature.

I'm creating a sort of bobbing bird enemy in my game. It moves at a fixed rate from right to left (x axis), but in the y axis it's bobbing up and down like a sine wave. Ideally, I'd use a Tween object for this, but in its current form I have to tween the entire position property. While I want the y property to vary using Tween.TRANS_SINE, the x property should not be using a sine curve. It should be linear, or even better, not affected by the tween at all. As a newbie user, I was expecting either transform/pos/y or transform/pos.y to work for interpolate_property's property argument.

The workaround documented here is to tween a custom field instead of the transform directly and then copy that custom field into the transform.

All 13 comments

Rather than interpolate_axis additional properties like transform/posX or transform/posY or transform/posZ

resulting

tween.interpolate_property(get_node("Node2D_to_move"), "transform/posX", 0, 100, 1, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)

Sounds doable if we change Object.set(property, value) (or Variant.set, if possible) to support dotted properties. E.g. (psuedo code):

Object::set(String property, Variant value) {
  if (property.find(".")) {
    [first, rest] = property.split_in_two(".");
    current_value = get(first);
    current_value.set(rest, value);
    set(first, current_value);
  }
}

Then, the code would become:

# 3.0
tween.interpolate_property(node, "position.x", 0, 100, 1, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)

Other new properties like modulate makes more difficult to do simple things like animating opacity because is not possible to access the modulate.a from Tween and AnimationPlayer.
If you modify the modulate colors and want separate opacity management, it gets complicated.

If what @bojidar-bg suggested can be done, that would solve many issues.

I can change the title asking for a generic properties of properties access if others are interested.

Actually, is this really needed?
We can do single axis translation using Tween.
You just need the start and end pos as Vector2 values.

Like this:
tween.interpolate_property(node, "transform/pos", node.get_pos(), node.get_pos() + Vector2(0,100), 1, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)

Or am I missing something?

EDIT: I think, the requirement is to do a single property change without modifying other sub-properties?

@vinod8990 to modify a single sub property without change the full property, currently you tween the whole thing (you can't control X if the tween is manipulating the position, same for opacity and colors on 3).

I want to provide a concrete example for why this would be a useful feature.

I'm creating a sort of bobbing bird enemy in my game. It moves at a fixed rate from right to left (x axis), but in the y axis it's bobbing up and down like a sine wave. Ideally, I'd use a Tween object for this, but in its current form I have to tween the entire position property. While I want the y property to vary using Tween.TRANS_SINE, the x property should not be using a sine curve. It should be linear, or even better, not affected by the tween at all. As a newbie user, I was expecting either transform/pos/y or transform/pos.y to work for interpolate_property's property argument.

The workaround documented here is to tween a custom field instead of the transform directly and then copy that custom field into the transform.

Just to mention it, you might get it simpler if you use interpolate_method instead of interpolate_property.

I got bit by the transform/pos/y not working, too.

interpolate_method should work as it just calls a method with the tween value. Inside the method, we can set any object property according to the tweened value.

I use this trick to tween a value from 0 to 1 to change multiple object properties simultaneously.

Interpolating method means call gdscript function from Tween I want to avoid. I also want to animate transform/pos.x and transform/pos.y separately in different tracks (from Tween or AnimationPlayer). So interpolate_method looks like working hack, but ability to modify property's property is important for me.

Does changing the tween object's target to the parent object?

Like

tween.interpolate_property(object.pos,"x"....

"pos" is the property, not a children of "object".

I've also run into this issue. In my example, I need to be able to tween just the x and z scale of a Spatial node, but modify the y scale elsewhere. I can't use the method of only adding a value to just the relevant axes of the Vector as outlined above by vinod8990, because the tween would still set the y scale to it's initial value every step, which makes sense.

This is how i expected it to work:

tween.interpolate_property(pulser, "scale/x", pulser.scale.x, max_scale, pulse_up_time, Tween.TRANS_CUBIC, Tween.EASE_IN_OUT)
tween.interpolate_property(pulser, "scale/z", pulser.scale.z, max_scale, pulse_up_time, Tween.TRANS_CUBIC, Tween.EASE_IN_OUT)
tween.start()

of course, this throws scene/animation/tween.cpp:1015 - Condition ' !prop_valid ' is true. returned: false errors when run. I also tried this:

tween.interpolate_property(pulser.scale, "x", pulser.scale.x, max_scale, pulse_up_time, Tween.TRANS_CUBIC, Tween.EASE_IN_OUT)
tween.interpolate_property(pulser.scale, "z", pulser.scale.z, max_scale, pulse_up_time, Tween.TRANS_CUBIC, Tween.EASE_IN_OUT)
tween.start()

But it appears that Vector3's are passed by value instead of by reference. Which also makes sense.

Ideally, my first example would just work. I think it would be more usable with dot notation; "scale.x" instead of "scale/x" for example. I think that this functionality would be extremely useful, and is actually quite important.

As it stands at the moment, I'm going to go and write an interpolate method and copy/paste it across a bunch of different scripts, which is never ideal.

Was this page helpful?
0 / 5 - 0 ratings