Skip to content

Instantly share code, notes, and snippets.

@YuriSizov
Created August 16, 2025 14:16
Show Gist options
  • Save YuriSizov/e0b4ab06f4381745a6a2bac8d9c751a2 to your computer and use it in GitHub Desktop.
Save YuriSizov/e0b4ab06f4381745a6a2bac8d9c751a2 to your computer and use it in GitHub Desktop.
An interactive example of using tweens to interpolate vector components separately
@tool
extends Node2D
enum TweenMode {
TWEEN_TOGETHER,
TWEEN_INDEPENDENTLY,
}
const TWEENING_START_POSITION := Vector2(300.0, 200.0)
const TWEENING_END_POSITION := Vector2(600.0, 400.0)
const TWEENING_DURATION := 1.0
const TWEENING_REPEAT_DELAY := 0.2
@export var tween_mode: TweenMode = TweenMode.TWEEN_TOGETHER:
set = set_tween_mode
@export_group("Tweening (Both)", "tweening_both_")
@export var tweening_both_transition: Tween.TransitionType:
set = set_tweening_both_transition, get = get_tweening_both_transition
@export var tweening_both_easing: Tween.EaseType:
set = set_tweening_both_easing, get = get_tweening_both_easing
@export_group("Tweening (X)", "tweening_x_")
@export var tweening_x_transition: Tween.TransitionType:
set = set_tweening_x_transition, get = get_tweening_x_transition
@export var tweening_x_easing: Tween.EaseType:
set = set_tweening_x_easing, get = get_tweening_x_easing
@export_group("Tweening (Y)", "tweening_y_")
@export var tweening_y_transition: Tween.TransitionType:
set = set_tweening_y_transition, get = get_tweening_y_transition
@export var tweening_y_easing: Tween.EaseType:
set = set_tweening_y_easing, get = get_tweening_y_easing
var _left_trans: Tween.TransitionType = Tween.TRANS_LINEAR
var _left_ease: Tween.EaseType = Tween.EASE_IN
var _right_trans: Tween.TransitionType = Tween.TRANS_LINEAR
var _right_ease: Tween.EaseType = Tween.EASE_IN
var _tween: Tween = null
@onready var _sprite: Sprite2D = %Sprite
func _ready() -> void:
_restart_tween()
func _validate_property(property: Dictionary) -> void:
if property.name.begins_with("tweening_both_"):
property.usage = PROPERTY_USAGE_DEFAULT if tween_mode == TweenMode.TWEEN_TOGETHER else PROPERTY_USAGE_NONE
if property.name.begins_with("tweening_x_"):
property.usage = PROPERTY_USAGE_DEFAULT if tween_mode == TweenMode.TWEEN_INDEPENDENTLY else PROPERTY_USAGE_NONE
if property.name.begins_with("tweening_y_"):
property.usage = PROPERTY_USAGE_DEFAULT if tween_mode == TweenMode.TWEEN_INDEPENDENTLY else PROPERTY_USAGE_NONE
# Properties.
func set_tween_mode(value: TweenMode) -> void:
if tween_mode == value:
return
tween_mode = value
notify_property_list_changed()
_restart_tween()
func set_tweening_both_transition(value: Tween.TransitionType) -> void:
if _left_trans == value:
return
_left_trans = value
_right_trans = value
_restart_tween()
func get_tweening_both_transition() -> Tween.TransitionType:
return _left_trans
func set_tweening_both_easing(value: Tween.EaseType) -> void:
if _left_ease == value:
return
_left_ease = value
_right_ease = value
_restart_tween()
func get_tweening_both_easing() -> Tween.EaseType:
return _left_ease
func set_tweening_x_transition(value: Tween.TransitionType) -> void:
if _left_trans == value:
return
_left_trans = value
_restart_tween()
func get_tweening_x_transition() -> Tween.TransitionType:
return _left_trans
func set_tweening_x_easing(value: Tween.EaseType) -> void:
if _left_ease == value:
return
_left_ease = value
_restart_tween()
func get_tweening_x_easing() -> Tween.EaseType:
return _left_ease
func set_tweening_y_transition(value: Tween.TransitionType) -> void:
if _right_trans == value:
return
_right_trans = value
_restart_tween()
func get_tweening_y_transition() -> Tween.TransitionType:
return _right_trans
func set_tweening_y_easing(value: Tween.EaseType) -> void:
if _right_ease == value:
return
_right_ease = value
_restart_tween()
func get_tweening_y_easing() -> Tween.EaseType:
return _right_ease
# Tweening.
func _restart_tween() -> void:
if not is_node_ready():
return
if is_instance_valid(_tween):
_tween.kill()
_tween = null
_sprite.position = TWEENING_START_POSITION
_tween = create_tween()
_tween.set_parallel(true)
_tween.set_trans(Tween.TRANS_QUAD)
if tween_mode == TweenMode.TWEEN_TOGETHER:
_tween.tween_property(_sprite, "position", TWEENING_END_POSITION, TWEENING_DURATION)\
.set_trans(_left_trans)\
.set_ease(_left_ease)
else:
_tween.tween_property(_sprite, "position:x", TWEENING_END_POSITION.x, TWEENING_DURATION)\
.set_trans(_left_trans)\
.set_ease(_left_ease)
_tween.tween_property(_sprite, "position:y", TWEENING_END_POSITION.y, TWEENING_DURATION)\
.set_trans(_right_trans)\
.set_ease(_right_ease)
_tween.chain()
_tween.tween_callback(func() -> void:
_restart_tween.call_deferred()
).set_delay(TWEENING_REPEAT_DELAY)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment