Drawing animated models

Beginner Getting started

In tutorial Drawing your first 3D model we used a posed character model to show you how to draw 3D models in GameMaker using BBMOD. This time we are going to expand on that code and make the character move using an animation player.

Contents

Animated materials

In Drawing your first 3D model we have created our own material by creating a copy of BBMOD_MATERIAL_DEFAULT. While this works for static models, animated models contain extra data that the shader used in this material does not account for. To fix this, we simply replace it with BBMOD_MATERIAL_DEFAULT_ANIMATED:

var _matCharacter = BBMOD_MATERIAL_DEFAULT_ANIMATED.clone(); // <- Instead of BBMOD_MATERIAL_DEFAULT
_matCharacter.BaseOpacity = sprite_get_texture(SprCharacter, 0);
global.resources.Materials.Character = _matCharacter;

Loading animations

When we convert a model that has animations, they are stored as separate *.bbanim files. Same as with *.bbmod, we have to put them first into the Included Files to be able to load them. Loading animations is straight forward just like loading models, we only have to use struct BBMOD_Animation instead of BBMOD_Model:

global.resources = {
    Animations: {}, // <- Add Animations struct here
    Materials: {},
    Models: {},
};

// Load animations:
global.resources.Animations.Idle = new BBMOD_Animation("Data/Idle.bbanim");
global.resources.Animations.Walking = new BBMOD_Animation("Data/Walking.bbanim");
global.resources.Animations.Jumping = new BBMOD_Animation("Data/Jumping.bbanim");

Adding an animation player

BBMOD offers multiple ways of playing animations, the simplest one being using the BBMOD_AnimationPlayer struct. We will want to create one for every instance that plays animations, which we can do in the Create event of our character object:

model = global.resources.Models.Character;
// Create an animation player for the model:
animationPlayer = new BBMOD_AnimationPlayer(model);

An animation player needs to be updated every frame. This is done using the update method, so we will put it into the Step event of our character object:

animationPlayer.update(delta_time);

Since animation player has a destroy method, we should not forget to call it when it is no longer needed, otherwise we would get memory leaks. We can do this in the character's Clean up event:

animationPlayer.destroy();

In the Draw event we want to use the submit method of the animation player instead of the model's submit:

bbmod_material_reset();
new BBMOD_Matrix().Scale(100, 100, 100).Translate(x, y, 0).ApplyWorld();
animationPlayer.submit(); // <- Change model to animationPlayer here
new BBMOD_Matrix().ApplyWorld();
bbmod_material_reset();

Playing animations

Our character object is now fully prepared for playing animations. This can be done using the animation player's method change in the Step event:

// This is just to shorted the code a bit:
var _animations = global.resources.Animations;
// This will be the animation we want to change to if it is not the current one
// (or none is being played). We will make it default to the Idle animation:
var _animationNew = _animations.Idle;
// Play Walking animation when we hold the W key:
if (keyboard_check(ord("W")))
{
    _animationNew = _animations.Walking;
}
// Change to the new animation:
animationPlayer.change(_animationNew);
// Update the animation player:
animationPlayer.update(delta_time);

Animation events

You may have noticed that we have not used our jumping animation yet. That is because we need to handle its playback a bit differently - we want to press a key only once and keep playing the animation until it finishes. For this we can use the animation player's method on_event to add a listener that is executed when an animation event BBMOD_EV_ANIMATION_END is triggered, which happens at the end of every animation we play. Lets begin by adding following code to the Create event of our character:

animationPlayer.on_event(BBMOD_EV_ANIMATION_END, method(self, function (_animation) {
    // When the Jumping animation ends, change back to Idle animation:
    if (_animation == global.resources.Animations.Jumping)
    {
        animationPlayer.change(global.resources.Animations.Idle);
    }
}));

Now we can slightly modify the Step event to play the jumping animation when we press space and then not call the change method while we are playing it, which we can tell from the read-only Animation property of the animation player:

var _animations = global.resources.Animations;
if (animationPlayer.Animation != _animations.Jumping)
{
    var _animationNew = _animations.Idle;
    if (keyboard_check(ord("W")))
    {
        _animationNew = _animations.Walking;
    }
    if (keyboard_check_pressed(vk_space))
    {
        _animationNew = _animations.Jumping;
    }
    animationPlayer.change(_animationNew);
}
animationPlayer.update(delta_time);

Animations

Congratulations, you have rendered you first 3D animated character in GameMaker using BBMOD!

Support the development

Support us in developing BBMOD, get priority assistance and more of our amazing tools as a reward!

Become Patron

Don't miss out on a thing!

Create an account, subscribe to newsletter and get notified on new releases, tutorials and special offers.

Register Log in