Choosing between three directions randomly during tween

Godot Version

4.2.1

Question

I have an autoload script that controls damage numbers, right now the tween just makes the numbers pop up and then fall down, scale down, and disappear after the tween. How can I make it randomly choose to pop up, up-left or up right, and then fall down and proceed as normal?

extends Node

func display_number(value: int, position: Vector2):
    var number: Label = Label.new()
    number.global_position = position
    number.text = str(value)
    number.z_index = 5
    number.label_settings = LabelSettings.new()
    
    var color: Color = "#FFF"
    if value in [2, 7, 12]:
        color = "#B22"
    if value == 0:
        color = "#FFF8"
    
    number.label_settings.font_color = color
    number.label_settings.font_size =  8
    number.label_settings.outline_color = "#000"
    number.label_settings.outline_size = 1
    number.label_settings.font = preload("res://Art/HUD/Font/NormalFont.ttf")
    call_deferred("add_child", number)
    
    await number.resized
    number.pivot_offset = Vector2(number.size / 2)
    
    var tween = get_tree().create_tween()
    tween.set_parallel(true)
    tween.tween_property(number, "position:y", number.position.y -24, 0.25).set_ease(Tween.EASE_OUT)
    tween.tween_property(number, "position:y", number.position.y, 0.5).set_ease(Tween.EASE_IN).set_delay(0.25)
    tween.tween_property(number, "scale", Vector2.ZERO, 0.25).set_ease(Tween.EASE_IN).set_delay(0.5)
    
    await tween.finished
    number.queue_free()

Please let me know if any additional information is needed.

Thanks!!

I’m not fully understanding your question but Tweens are code driven animations so you can do whatever you want with them in code.

If you just want to spawn the node to the left or to the right of your original position then something like this should work before creating the tween:

if randi() % 2 == 0:
	# to the left
	number.position.x -= 24
else:
	# to the right
	number.position.x += 24

or something like this if you want to have a different starting tween:

var tween = get_tree().create_tween()
match randi() % 3:
	0:
		# to the left
		tween.tween_property(...)
	1:
		# center
		tween.tween_property(...)
	2:
		# to the right
		tween.tween_property(...)
		
tween.tween_property(...)
1 Like

The current behavior is:.

  1. The number spawns above the player
  2. It rises up directly only moving y value
  3. It then falls down
  4. Shrinks
  5. Then is erased

What my desired behavor is for #2 to change from always rising directly up always to instead choose from 3 directions:

  1. Directly up
  2. Diagonal up-left
  3. Diagonal up-right

I hope this helps.

Something like this maybe :

var direction = [-40, 0, 40]
tween.tween_property(number, "position:x", number.position.x + direction[randi() % 3], 0.75).set_ease(Tween.EASE_OUT)

Or for something totally random :

tween.tween_property(number, "position:x", number.position.x + randf() * 40 - 20, 0.75).set_ease(Tween.EASE_OUT)

Just put it between you tween.set_parallel(true) and the first tween.tween_property

1 Like

I will try that out! Thanks

By the way if you want your popup to be really centered on the point it start of you can add this line

number.global_position -= Vector2(number.size / 2)

just after number.pivot_offset = Vector2(number.size / 2)
And add

number.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER

somewhere

You can also if you want to have a effect of curve add .set_trans(Tween.TRANS_QUAD) to each tween.tween_property modifying the y position.

One more think, you can use a callback to delete your number after the tween instead of using an await.

	tween.set_parallel(false)
	tween.tween_callback(delete_number.bind(number));

func delete_number(number):
	number.queue_free()

Here is the function with all the change if you want :

display_number
func display_number(value: int, position: Vector2):
	var number: Label = Label.new()
	number.global_position = position
	number.text = str(value)
	number.z_index = 5
	number.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
	number.label_settings = LabelSettings.new()
	
	var color: Color = "#FFF"
	if value in [2, 7, 12]:
		color = "#B22"
	if value == 0:
		color = "#FFF8"
	
	number.label_settings.font_color = color
	number.label_settings.font_size =  8
	number.label_settings.outline_color = "#000"
	number.label_settings.outline_size = 1
	call_deferred("add_child", number)
	
	await number.resized
	number.pivot_offset = Vector2(number.size / 2)
	number.global_position -= Vector2(number.size / 2)
	
	var tween = get_tree().create_tween()
	tween.set_parallel(true)
	tween.tween_property(number, "position:x", number.position.x + randi_range(-40, 40), 0.75).set_ease(Tween.EASE_OUT)
	tween.tween_property(number, "position:y", number.position.y -24, 0.25).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT)
	tween.tween_property(number, "position:y", number.position.y + 24, 0.5).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN).set_delay(0.25)
	tween.tween_property(number, "scale", Vector2.ZERO, 0.25).set_ease(Tween.EASE_IN).set_delay(0.5)
	tween.set_parallel(false)
	tween.tween_callback(delete_tween.bind(number));

func delete_tween(number):
	number.queue_free()
1 Like

This is amazing, thanks

your welcome.
by the way i forgot to put back this line :

number.label_settings.font = preload("res://Art/HUD/Font/NormalFont.ttf")
1 Like

That’s okay, I readded it :slight_smile:

Have a wonderful rest of your weekend!

Just an addition. You can also use Godots inbuilt function pick_random() for this since it’s an array.

var direction = [-40, 0, 40].pick_random()

1 Like

Good to know, thanks!!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.