Wednesday, 17 May 2017

Gitting Gud At Godot - Part 8 - The AnimationPlayer

Watch the video version of this tutorial here: https://www.youtube.com/watch?v=7DzrL1P_7J4

In this tutorial, we're going to delve into the exciting world of the AnimationPlayer, the node which (unsurprisingly) handles animations.


A good first exercise is to create a spawning animation for our "mover" prefab from part 7.

In order to do anything to our mover, we need to open it. If you don't have it open, you can either use the FileSystem tab to double click on "mover.tscn" or you can navigate to "Scene"->"Open Scene" and select "mover.tscn" there.


Now, we can add a node of type AnimationPlayer as a child of the tree root. When you have this node selected, you might notice an odd menu opens at the bottom of your screen, titled "Animations".

This menu is where you will be working with your animations. It's pretty easy to use, so let's go ahead and create a new animation. There is an icon on the top left of this menu that looks like a page with a creased corner.


Click this, and enter the name "spawn". This has created the animation. In addition to creating the animation, it's given us a timeline view in the animation menu.

So how do we add elements to the timeline?

This is super easy. Almost every property in the Inspector tab can be keyframed. You might notice that since creating the AnimationPlayer node, a key has appeared next to almost all of the properties on every node.

Select your Sprite node and scroll down to "Scale". For the beginning of our spawning animation, set "Scale" to (1.2, 1.2) and press the key icon to the right of the field. When it prompts you to add a new track for this property, press "Create" and you should notice that a blue dot has appeared at 0 seconds in our timeline. This is our first keyframe.

Click along the numbers on the timeline to move the marker to about 0.2 seconds. You can zoom in on this timeline using the scroll wheel for some added accuracy, or you can edit the number in the top left of the animation menu to be sure that you are where you want to be.

When you've moved the marker to 0.2 seconds, set "Scale" to (1, 1) again and press the keyframe button to the right once more. You should see another blue dot appear at 0.2 seconds.



Now that we have two keyframes, let's press the play button with the vertical line preceding it in the top left of the animation menu. The difference between this play button and the play button immediately to the right is that this button will play the animation from the beginning, while the other button will only play the animation from the current position of the marker.

With any luck, our Sprite should start slightly larger than normal and quickly shrink to a normal size. Hooray!

However, we've not actually added any functionality for this to be played in-game. To the right of the drop-down menu which currently says "spawn" is a right-facing arrow button with an A in it. Click this button to ensure that your animation plays once as soon as the node is added to the scene.

Now, we can return to our "mainscene.tscn" and press play. With any luck, we can move over the Area2D and see that our movers have a lovely spawning animation.

So, we've covered a very basic overview of how the AnimationPlayer works. If you don't want to spend any more time with this boring tutorial, you can leave now and be content with a suitable (if rudimentary) understanding of how it works. If you want to leave now, experiment, and come back for some handy tips and tricks then I fully support that.

First of all, the AnimationPlayer can call functions for you. This is super useful for a lot of things, but let's just create a quick example. In our mover.tscn file, open the script attached to the tree root and create a new function named "speak_to_me(message)". This is what I'm going to put into the function.

func speak_to_me(message):
    print(message)

Since this is only a little example, this is all I'm going to do for now. Now, we can return to the animations menu.

At the bottom right, we can see a button with a + icon - like the one that we use to create new nodes in the Scene tab.

Click it and press "Add Call Func Track". At this point, it'll open a seemingly random dialogue with a list of the available nodes to link this track to. Since we want to access the script attached to our tree root, we must select the tree root in this dialogue and press "OK".


You might notice that a new track has been created with an effectively blank path and no keyframes on it. In order to create a keyframe, we must press the green + button all the way to the right of this track. Once we do this, a green dot should appear at our marker.

If it isn't already, click and drag the green dot to the beginning of the timeline for convenience. It isn't necessary, but it just makes it a bit more neat for the purposes of this tutorial.

In order to edit our new keyframe, we can click on the green dot that we just created and select the button on the bottom right with an icon of a dot and a pencil. This should open a small menu to the right.


The "Name" field is for the name of our function. In this field, I will type "speak_to_me".

The property "Arg Count" is for the number of arguments supplied to the function. Since speak_to_me takes in 1 argument named "message", we can set this property to 1. When we do this, some new properties appear below.

Set the "type" property to "String", and in the new field type "Hello, world!" or a message of your choosing.


Return to mainscene.tscn and press "play", move into the Area2D and hopefully a message will appear in the output window. To recap, this is because when our mover gets spawned we automatically start the animation, and this animation is designed to call our speak_to_me function. Fun!

There are still a few more things to mention. First of all, our animation is set to one second long. Since we only have 0.2 seconds of stuff happening, we can go to the "Length (s)" field and set it to "0.2". This cuts out a lot of unnecessary time, something which comes in handy if you were to use the "finished()" signal.

This signal is super useful, and it calls every time an animation is finished by this AnimationPlayer. I would personally recommend confining your function calls to the function call tracks, since this way you can re-use the same AnimationPlayer for multiple purposes. For instance, you could use the same AnimationPlayer for a shooting animation as well as a death animation that changes the scene to a "Game Over" screen when it's done.

However, the same AnimationPlayer cannot play multiple animations at the same time.

As usual, play around with it. You can never have too much practice. Either way, thanks for reading. Stay tuned for Part 9 on the topic of sound!

No comments :

Post a Comment