I am very new to Godot and I have been semi-following a youtube tutorial to create a candycrush-like game. However, I ran into some issues when trying to animate the moving pieces using tweens. The pieces are added as child nodes in the grid and when I drag the selected_piece into the area of another piece, the other piece will emit a signal that is received by grid to execute the swap_pieces function. However, when the swap_pieces function executes and calls the move function on the piece, the tween simply did not play. I have been looking at this for hours and am really stumped, hoping it is a simple mistake that i couldn't notice. Any help is appreciated. I am using Godot4.3 if that is any useful information.

Grid.gd

func swap_pieces(piece):
	var tmpgridpos = selected_piece.grid_position
	selected_piece.grid_position = piece.grid_position
	piece.grid_position = tmpgridpos
	# piece.position = tmpgridpos * 64
	print("moving from " + str(piece.position) + " to " + str(tmpgridpos*64))
	piece.move(tmpgridpos * 64)
	board[selected_piece.grid_position.y][selected_piece.grid_position.x] = selected_piece
	board[piece.grid_position.y][piece.grid_position.x] = piece

Piece.gd

extends Node2D

@export var color: String
@export var grid_position: Vector2i

var is_dragging

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	SignalBus.dragging_start.connect(_on_dragging_start)

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
	pass
	
func pickup() -> void:
	$Sprite2D.set_scale(Vector2(1.2,1.2))
	
func place() -> void:
	$Sprite2D.set_scale(Vector2(1,1))

func _on_area_2d_mouse_entered() -> void:
	SignalBus.mouse_in_my_area.emit(self)

func _on_dragging_start() -> void:
	is_dragging = true
	
func move(target):
	print("trying to move to " + str(target))
	var tween: Tween = create_tween()
	tween.tween_property(self,"position",target, 1)
	tween.set_trans(Tween.TRANS_ELASTIC)
	tween.set_ease(Tween.EASE_OUT)
  • Toxe and xyz replied to this.
  • liontantan Is the engine reporting a type mismatch error in the output console? The target value you're sending is Vector2i while position property is Vector2.

    additional information: the terminal output shows no errors and that the move function is executed and the values for target is on point as well, but the tween animation still didn't play

    liontantan Probably won't help but try giving your Tween a "from" value, like:

    tween.tween_property(self,"position",target, 1).from(position)

    Also, did you try removing the transition and ease? And can you watch your node in the debugger to check if its position changes? And how does your node tree look like?

      liontantan Is the engine reporting a type mismatch error in the output console? The target value you're sending is Vector2i while position property is Vector2.

        • Edited

        DaveTheCoder Why would tween_property() call that constructor? If the expected argument type was an explicit vector, the implicit conversion might happen. The type is Variant though, and there is no cast happening at the time of argument passing as anything is valid to pass. So the function likely just checks internally for type equality before creating a tweener. Since Vector2i and Vector2 have different variant type id, it reports the mismatch error and ignores that tweener.

        It could be argued should the "implicit cast" be made by the tween (and in which cases) but that casting would kinda go against static typing principles. Better to just be strict and issue an error when source and target types do not match.

        The only real problem here is OP not looking at the engine's error reporting.

        • Edited

        DaveTheCoder My vote is for the missing await.

        The need for await in such cases would make tweens really awkward to use. Once you issue your tween_*() calls, the Tween object is no longer needed for tweening to proceed. The engine does the bookkeeping internally. That object is only just an interface for script code to communicate with the engine about what/how to tween.

        It takes 1 minute to test this out.

        A simple test.

        Case 1: The tweener will play regardless of the Tween object being local to function:

        func _ready():
        	create_tween().tween_property(self, "position", Vector2(100, 100), 1)

        Case 2: Type mismatch error, the tweener is ignored:

        func _ready():
        	create_tween().tween_property(self, "position", Vector2i(100, 100), 1)
        E 0:00:00:0765   scene.gd:2 @ _ready(): Type mismatch between initial and final value: Vector2 and Vector2i

        In view of your superior information, I will delete my ignorant posts.

        Toxe Tried adding "from", now it outputs an error saying "Cannot call method 'from' on a null value."

        And i did try removing the trans and ease, it did not help

        xyz Oh my god, you just saved me from another 3 hours of figuring (or maybe not figuring) this out. Thanks a lot, it did have an error in the debugger regarding a type mismatch. I thought the errors would be shown on the output tab or the game would stop. I will pay more attention to the debugger tab next time I am debugging...

        Now realizing how stupid I am not to look at the literal debugger tab during debugging.

        • xyz replied to this.
          • Edited

          liontantan Also note that set_trans() and set_ease() need to be called before calling tween_*() if they are called on the Tween object. They only affect subsequent tweeners. The examples that appear to be calling them "afterwards" are in fact calling those function on Tweener objects returned by tween_*() not the Tween object itself.

          So it's either:

          tween.set_ease(...)
          tween.set_trans(...)
          tween.tween_property(...)

          Or:

          var tweener = tween.tween_property(...)
          tweener.set_ease(...)
          tweener.set_trans(...)

          Or shortened:

          tween.tween_property(...).set_ease(...).set_trans(...)