Logo 3.5Cats_AndHalfAFish


Animations in 3d.

April 08, 2019 Bethee, Godot
A simple 3d animation using the AnimationPlayer.

Disclaimer : I don't claim to know what I'm doing ; I'm discovering things as I go.

I've updated to Godot 3.1.
The purpose is to create a simple 3d animation using the AnimationPlayer node (no skeleton).

In a previous post I used a little bit of code to set up a 3d animation for my voxel model. Turns out you can also use the AnimationPlayer node for that ! An advantage of using the AnimationPlayer, is that you can blend animations. I won't be doing that here, but you could if you needed to.

Importing MagicaVoxel models.

Before I go any further, I thought I'd mention my new workflow to import MagicaVoxel models into Blender, and from there into Godot 3.1.

When I export from MagicaVoxel, I actually prefer to export to .py, even though this results in a larger number of vertices as compared to .obj. The reason is that .py preserves the 'voxel character' of the model, whereas .obj doesn't. It's just a personal preference, so .obj is just as good.

Next, I import the .py file into Blender, remove double verts and set a convenient model origin. I also align all models at (0,0,0).

Exporting the Blender models.
Exporting the Blender models.

With all models selected, I export to .dae (so, all models at once, inside 1 file). The only options I need checked, are : 'selection only' and 'use object instances'.

After copying the .dae file into the resource folder of Godot, I reimport :

Reimporting the .dae file in Godot (1).
Reimporting the .dae file in Godot.

This creates an ArrayMesh for each of the models, in the Godot resource folder.

Reimporting the .dae file in Godot (2).

Next, I double click each ArrayMesh in turn, set the correct material, and save the ArrayMesh resource again.
We are now ready to create the animations.

Setting the material.
Setting the material for each ArrayMesh.

The AnimationPlayer node.

First thing to do, is add an AnimationPlayer node ; I'm going to add it as a child of the KinematicBody node (Bethee). This way, I can easily change the MeshInstance as well as the CollisionShape (if that would be necessary).
Adding an AnimationPlayer node to the scene creates an extra tab at the bottom of the editor : 'Animation'.

The animation window is quite empty, and a bit unintuitively, you have to click the text 'Animation' (1) and then 'new' to get started.

AnimationPlayer node.
The AnimationPlayer node.
Creating the first animation.
Creating the first animation.

Any animation name ending in '-loop' (1) will loop in-game. If you need to rename your animation, click the 'Animation' text again. Not very logical, but ... =)

To change the total length of the animation, type a new number at location (2).

Here (3) you can type the frame you want to set (eg. 0.0 sec ; the blue vertical line next to 'add track'). Next, select the MeshInstance and load the first mesh (bethee_idle.mesh)

Creating the first track.
Creating the first track.

Click the key button next to 'Mesh' in the inspector tab. If you can't see it, just select the AnimationPlayer node again, and then return to the MeshInstance.
A popup will ask if you want to create a new track for the property 'mesh' ; click 'create'.
Congratulations. You have just added the first mesh of the idle cycle (1). Move the player head (2) to the next frame and repeat until all meshes have been added to the cycle.

The first frame of the cycle has been created.
The first frame of the cycle has been created.

To add the walking animation, press the 'Animation' text btn and repeat.

You can preview the animation in the editor : 1) make sure the animation name ends with '-loop', 2) click the 'looping' btn in the animation panel, and 3) change the 'current animation' property to eg. 'walking-loop'.

Animation preview.
Animation preview.

The result (you can still tweak it) :

To select the animation that is to play when your game starts up, click the arrow btn next to the name of the animation ('Autoplay on load').

The animation code.

The code is largely the same as before. The only thing that needs to be changed is how we're playing the animations :

The animation code.
The animation code.

Notice how you can still tweak the speed of the animations (third param of the play() method).