How can send a signal when my animation reaches a certain point?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By greencloversguy

I have a character in my game who moves on a grid, and I am handling their movement through animations. I would like to set it up so, when they are halfway through moving, their current tile changes. So for example, if my player moves out of a tile after an enemy attacks the tile, the enemy will miss.

I currently have this code:

func move_to_tile(vec):
    var temp = currenttile + vec
    if !(temp.x < tl.x or temp.y < tl.y or temp.x > br.x or temp.y > br.y):
	    for anim in anims:
	    	if (vec == anim["pos"]):
		    	$AnimationPlayer.play(anim["name"])
	    yield($AnimationPlayer,"animation_finished")
        currenttile = temp
	    position = $Sprite.position + position
	    $Sprite.position = Vector2.ZERO
	    emit_signal("player_moved", currenttile)

So currently, my code starts playing the animation, waits for it to finish and then resolves the position of the character. What I would like for it to do is the same, but do it when the animation is halfway completed. Is there a way I can do this somewhat easily within the code? Can I add some code to the Animation Player and create a new signal easily? Or would I be better off splitting my move animations into seperate animations? For example, make 2 seperate “Move a tile right” animations.

Thanks for any help!

:bust_in_silhouette: Reply From: kidscancode

You can add a “Call Method” track. Insert a key at the desired point and set it to call emit_signal().

More information here:
https://docs.godotengine.org/en/latest/tutorials/animation/introduction_2d.html#advanced-call-func-tracks

This is very useful, thank you!

My current setup has me creating the animations in the code before the game starts. I’m struggling to find a good reference to use to help me add in a method track. I have the following in my code:

		tempanim.track_set_path(trackindex, 'AnimationPlayer')
	    tempanim.track_insert_key(trackindex, 0.25, "test_method")

This is causing this error:

E 0:00:02:0772   Condition ' p_key.get_type() != Variant::DICTIONARY ' is true.

I assume that this is because the key I’m trying to add needs to be a dictionary, but I can’t find what the dictionary I need to make looks like,what values it needs. Any help?

greencloversguy | 2019-08-01 08:05

Found it in the source code. For future coders, dictionary needs to look like the following:

{"method": method_name, "args": [arg1, arg2, ...]}

greencloversguy | 2019-08-01 08:14

When I try this syntax for the format in my own script like this:

animation_player.get_animation("S_Pistol_Holster").track_insert_key(0,0.2, {"test_method()" : "test_method", "args" : []})

I get the error:

E 0:00:00:0349 Condition ' !d.has("method") || d["method"].get_type() != Variant::STRING ' is true. <C Source> scene/resources/animation.cpp:1064 @ track_insert_key() <Stack Trace> Player.gd:390 @ animation_tracks() Player.gd:122 @ _ready()

Sir_Skurpsalot | 2019-10-15 21:13