0 votes

The challenge is to create a damage animation that sputter out of his monsters head.

With the following syntax I can achieve a straight line between two points.

effect.interpolate_property(node, "rect/pos", node.get_pos(), Vector2(47, -45), 0.5, Tween.TRANS_QUAD, Tween.EASE_OUT)

Damage label pos as parable

But I have no idea how to calculate a parable to the pos value?
Have anyone a clue to how can I achieve this?

in Engine by (17 points)
edited by

2 Answers

+4 votes

Here's one way:

    effect.interpolate_property(node, "x", start_x, end_x, 1, Tween.TRANS_LINEAR, Tween.EASE_IN)
    effect.interpolate_property(node, "y", start_y, end_y, 0.5, Tween.TRANS_QUAD, Tween.EASE_OUT)
    effect.interpolate_property(node, "y", end_y, start_y, 0.5, Tween.TRANS_QUAD, Tween.EASE_IN, 0.5)

x and y are member variables in the node you want to move. You also have to manually update the position of the node with set_pos(Vector2(x, y)).

by (1,554 points)

You can update the position (set_pos) on tween_step signal.

Yes this work really great. I have a similar solution in mind but I'am not sure this is the right way. Thank you so much.

@eons
Thank you for the tween_step tip, really interesting. I have try it with tween_step but x and y be two function requests. I found it convenient to set the pos in the node itself.

Thanks folks -- I ended up using both @mollusca's and @eons' suggestions. Here it is.

Here's my implementation. :)

extends Node2D

onready var container = get_node("container") # Node2D
onready var label = get_node("label") # Label
onready var effect = get_node("effect") # Tween

var x = 0
var y = 0

func _ready():
    label.hide()

func set_damage(dmg):
    var d = label.duplicate()
    container.add_child(d)
    d.set_text(str(dmg))
    d.show()

    var x = 0
    if (randi() % 2 == 1):
        x = d.get_pos().x - 50
    else:
        x = d.get_pos().x + 50
    var start_x = d.get_pos().x
    var end_x = x
    var start_y = d.get_pos().y
    var end_y = d.get_pos().y - 50
    effect.interpolate_property(d, "x", start_x, end_x, 1, Tween.TRANS_LINEAR, Tween.EASE_IN)
    effect.interpolate_property(d, "y", start_y, end_y, 0.5, Tween.TRANS_QUAD, Tween.EASE_OUT)
    effect.interpolate_property(d, "y", end_y, start_y + 30, 0.5, Tween.TRANS_QUAD, Tween.EASE_IN, 0.5)

    effect.interpolate_property(d, 'visibility/opacity',
                                1, 0, 1,
                                Tween.TRANS_EXPO, Tween.EASE_IN)
    effect.start()

func _on_effect_tween_complete( object, key ):
    if (key == "visibility/opacity"):
        object.queue_free()
+2 votes

This is an old question, but people are still looking at this, so...

Now (3.2.3) you can tween node positions directly with "position:x" and "position:y".

So you can have:

effect.interpolate_property(node, "position:x", start_x, end_x, 1, Tween.TRANS_LINEAR, Tween.EASE_IN)
effect.interpolate_property(node, "position:y", start_y, end_y, 0.5, Tween.TRANS_QUAD, Tween.EASE_OUT)
effect.interpolate_property(node, "position:y", end_y, start_y, 0.5, Tween.TRANS_QUAD, Tween.EASE_IN, 0.5)

Also, this is for animations where you want the ending y-position to be the same as the starting y-position only. Someone on Discord was trying to use it with a dynamic dropping system like in Enter the Gungeon and it didn't work. If you want to dynamically set the ending y-position, use this code:

const JUMP_HEIGHT = 96
const ANIM_LENGTH = 0.5

effect.interpolate_property(node, "position:x", node.position.x, ending_pos.position.x, ANIM_LENGTH)
effect.interpolate_property(node, "position:y", node.position.y, ending_pos.position.y-JUMP_HEIGHT, ANIM_LENGTH/2, Tween.TRANS_QUAD, Tween.EASE_OUT)
effect.interpolate_property(node, "position:y", ending_pos.position.y-JUMP_HEIGHT, ending_pos.position.y, ANIM_LENGTH/2, Tween.TRANS_QUAD, Tween.EASE_IN, ANIM_LENGTH/2)
effect.start()

Note that ending_pos is a Position2D node here. You can change it to a Vector2 or whatever you want, though.

by (7,541 points)

Very usefull, thank you.

How can I achieve the same this on a 3D scene?

I have th following aproach, but the result is a mess.

tween.interpolate_property(newBullet, "translation:x", origin.x, target.x, 1, Tween.TRANS_LINEAR, Tween.EASE_IN)
tween.interpolate_property(newBullet, "translation:z", origin.z, target.z, 1, Tween.TRANS_LINEAR, Tween.EASE_IN)
tween.interpolate_property(newBullet, "translation:y", origin.y, target.y, 0.5, Tween.TRANS_QUAD, Tween.EASE_OUT)
tween.interpolate_property(newBullet, "translation:y", target.y, origin.y, 0.5, Tween.TRANS_QUAD, Tween.EASE_IN, 0.5)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.