How To Make A Idle Animation In Game Maker Studio 2
Every game needs polished animations to immerse users in its world and characters, and GameMaker is here to help brand your game look as smooth as possible with its new "Sequences" feature: allowing y'all to bring your characters to life your own style!
In this tutorial web log we're going to pattern animations for our thespian character using Sequences. This technique makes use of multiple sprites to create a customized attack sequence, and also includes a hitbox (which tin exist animated too) then y'all can control its attack range and ability - basically allowing you to have everything in one place!
This mail service is divided into the following sections:
- Basic Attack Sequence (+ Hitbox)
- Playing the Sequence using GML
- Heavy Assail Sequence (+ Surface area of Consequence)
- Idle Slumber Sequence
- More than Attack Sequences (+ Combining Attacks!)
The base projection is a simple pinnacle-downwardly game where the character has idle and walking animations. We'll be adding attacks to this character completely using Sequences, without any blitheness code in the player itself!
During an attack blitheness, the player case volition be disabled so we can only run across the Sequence.
For an introduction to Sequences, check out the post-obit resource:
- Manual page for Sequences
- Official video tutorials for Sequences
Basic Attack Sequence (+ Hitbox)
For our kickoff Sequence, we'll but place the attack sprite into a new Sequence (we'll phone call it seqAttack1) and fix the length of the Sequence to lucifer the animation (in my case, 42 frames):
Note that we're placing the sprite directly into the Sequence, without using an object, since we don't need whatever object interaction for these set on animations (except for the hitbox, which we'll go to in a moment).
Make certain to set the initial position of the player to (0, 0) in the Sequence, so that nosotros get a seamless transition when we play the Sequence at the player instance's origin. Essentially, the origins of your sprite and Sequence demand to match so the transition from instance to Sequence looks skillful!
Hitbox
Nosotros're also going to place a hitbox in this Sequence, allowing the actor to set on enemies. For this I've created an object called oPlayerHitbox, and added a collision effect in my enemy object to reduce its health when information technology collides with a player hitbox:
/// oEnemy - Collision event with oPlayerHitbox if (!attackable) get out; hp --; instance_create_depth(x, y, depth, oAttackEffect); attackable = false; alarm[0] = 30; var _dir = point_direction(oPlayer.x, oPlayer.y, 10, y); moveX = lengthdir_x(knockSpeed, _dir); moveY = lengthdir_y(knockSpeed, _dir); if (hp <= 0) { sprite_index = sEnemyDie; } else { image_alpha = 0.6; }
This event is reducing the wellness of the enemy, and creating an "attack effect" case just equally a visual effect for the enemy existence striking. It then sets the attackable variable to false, which exits the event (at the top) as long equally information technology remains faux, and so the enemy tin can't exist hit. Then Alarm 0 is fix to xxx, which resets attackable to truthful so the enemy tin be attacked once again.
After that we take some basic code to assign knockback to the enemy'southward move variables, and ready the sprite information based on the hp. If the hp is <= 0 so the sprite switches to the dying blitheness. Later on that the instance is destroyed in the Animation Terminate event if the instance is on that dying animation. If the enemy hasn't died, its blastoff is lowered, which is as well reset to i in the Alarm 0 event.
Let's place the hitbox object in our Sequence now. Drag it in equally a new runway and make sure to starting time its Nugget Key simply when the blitheness gets to the attack frame:
You tin see in the Canvas how the hitbox only covers a certain portion of the sprite, as that is the surface area that is able to hit enemies. You tin adjust this to your eye's content and fifty-fifty animate information technology so it matches the motion in the animation!
Playing the Sequence using GML
Enabling/Disabling the Player
We're going to create some functions in our player object to handle the animation, and brand certain that the player itself is disabled while the Sequence is active. Let's handle that first, past creating the post-obit variables and functions in the Create issue:
enabled = true; Enable = function () { enabled = true; image_alpha = 1; } Disable = part () { enabled = false; alarm[0] = ane; moveX = 0; moveY = 0; }
enabled controls whether the player is enabled or not. Calling Enable() will set that variable to true and the case's blastoff to 1 (to make it visible again).
Calling Disable() volition set enabled to fake, set Warning 0 to run after 1 step and set the player's move variables to 0 and so it stops. Alarm 0 will set the image_alpha to 0 so the actor disappears. Nosotros're using an Alarm for this equally in that location is a 1-frame filibuster in the Sequence appearing, which is why we can't set the alpha to 0 immediately equally that will result in an empty frame where the player tin't be seen at all.
Let'due south open the Pace outcome and make sure the player tin can't be controlled if information technology's disabled. At the top of the event, I'll add the following code:
if (!enabled) exit;
This will exit the event if enabled is false, pregnant that the residuum of the event will not run. Of course, this simply works if your movement code is in the Footstep event. If at that place are any other events that you lot would like to disable as well, you can put this same line at the top of those events and they won't run for equally long as the role player is disabled.
Allow's at present create some new functions to handle the Sequence animation!
Playing & Managing the Blitheness
In the Create issue, I'll create the following variables and functions:
activeAnimation = -1; sequenceLayer = -1; activeSequence = -one; StartAnimation = function (_sequence) { activeAnimation = _sequence; sequenceLayer = layer_create(depth); activeSequence = layer_sequence_create(sequenceLayer, x, y, _sequence); layer_sequence_xscale(activeSequence, image_xscale); Disable(); } CheckAnimation = role () { if (activeSequence == undefined) return; if (layer_sequence_is_finished(activeSequence)) { layer_sequence_destroy(activeSequence); layer_destroy(sequenceLayer); activeAnimation = -1; activeSequence = -1; sequenceLayer = -i; Enable(); } }
Let'south await at the variables first. activeAnimation stores the Sequence nugget ID that is being played at the moment, sequenceLayer stores the ID of the layer that is playing the Sequence, and activeSequence stores the Sequence element ID that is playing on that layer.
Let'southward now expect at the rest of the code, line-by-line:
StartAnimation = office (_sequence) { activeAnimation = _sequence;
The StartAnimation() function is used to start a Sequence animation and takes the Sequence nugget every bit an argument. That Sequence asset is and then assigned to the activeAnimation variable.
sequenceLayer = layer_create(depth);
Then we create a new layer at the player'southward electric current depth and store that layer'due south ID in the sequenceLayer variable. I am just doing this considering my thespian instance does not belong to a layer and has a variable depth - this is due to the post-obit lawmaking in my manager object:
with (all) { depth = -bbox_bottom; }
This changes the depth of each instance based on the Y coordinate of its bottom bounding box edge, for easy depth-sorting between the instances. Because of this, those instances no longer vest to any certain layer because their depth keeps changing. This is why nosotros're creating a new layer to play the Sequence so that it appears at the correct depth, however if yous are not changing your instance's depth, then you don't need to create a new layer and can simply create the Sequence on the case's layer, using the layer variable.
Permit'south continue looking at our code:
activeSequence = layer_sequence_create(sequenceLayer, ten, y, _sequence); layer_sequence_xscale(activeSequence, image_xscale); Disable(); }
Here we're creating the Sequence on our new layer, at the example's x and y position. The ID of the created Sequence chemical element ("elements" exist on a layer) is stored in the activeSequence variable. We're then calling the layer_sequence_xscale() function to change the horizontal scale of the Sequence to friction match the example's scale (so that if the player is facing left, the Sequence as well faces left -- of course this only works if you are using the image_xscale variable to flip information technology). Finally we're calling Disable() to disable the histrion example.
Let's look at the second function at present:
CheckAnimation = function () { if (activeSequence == -1) render;
This function will be used in the Stride outcome, to check whether the agile Sequence has concluded. Before doing anything, it checks if the activeSequence variable is -1 (significant that no Sequence is active at the moment) and in that case, calls return to finish the office.
If there is an agile Sequence then the function will continue, and come up to the following lawmaking:
if (layer_sequence_is_finished(activeSequence)) { layer_sequence_destroy(activeSequence); layer_destroy(sequenceLayer); activeAnimation = -i; activeSequence = -1; sequenceLayer = -1; Enable(); } }
Here nosotros're checking if the Sequence has finished, and when it has, we destroy it and the layer that holds it. Then we reset all iii variables that hold information regarding the active Sequence, and enable the player once again.
Let'south open up the Step result now to call the CheckAnimation() function. Add a phone call to the role at the top of the outcome before the "leave" line, so information technology runs even when the player is disabled (equally that is when information technology'southward actually needed):
CheckAnimation(); // New line if (!enabled) exit; // Sometime line
Finally, let's add code in the aforementioned event to start the set on animation. Later on the "exit" line (and so it merely happens while the role player is active), nosotros'll add the following lawmaking:
// Attack 1 & ii if (keyboard_check_pressed(vk_space)) { if (keyboard_check(vk_shift)) { StartAnimation(seqAttack1_Heavy); } else { StartAnimation(seqAttack1); } }
This cake runs if the Space cardinal is hit. If the Shift cardinal is besides held down (creating the combination Shift+Space) it starts the seqAttack1_Heavy Sequence (which we'll create in the side by side section). If Shift is not held down (meaning only space is pressed) then it starts the seqAttack1 Sequence, which we have just created. So you lot can come across that nosotros'll also add together a heavy variant of our assault that runs when Shift is besides held down!
This should now play our animation when yous hit Space, and the hitbox should exist able to hitting enemies. You'll also notice that the Sequence flips based on the thespian'southward xscale, which is perfect:
You'll probably not desire the hitbox to be visible in the game, so brand certain to make information technology invisible by using the "Toggle Visibility" button in the Sequence'southward Track Panel:
Heavy Attack Sequence (+ Expanse of Effect)
Allow's create our heavy assail Sequence now (seqAttack1_Heavy). I'll simply indistinguishable seqAttack1 as it will use the same attack animation, simply will include some extra editing on our function and an additional hitbox!
For our assault blitheness in this Sequence, I've used the Image Index parameter runway so I could control the animation frames manually. I did this so I could add a longer "waiting menses" before the actual attack frame hitting. You can add the Image Index parameter from this menu:
Note that this will disable your sprite's animation completely, and y'all will have to use keyframes to accelerate each frame one-by-one. Earlier doing that, brand sure to disable interpolation for the Paradigm Index track by correct-clicking on it and turning off the "Interpolation" option. This makes the values modify instantly between keyframes without any tweening (so it would spring from 0 -> i instead of going through each decimal value in between, for example: 0 -> 0.2 -> 0.4 -> [...] -> 1).
In the paradigm beneath you can come across the keyframes I've used forth with their image alphabetize values. You lot can see how I've repeated the frames ii and 3 in the middle to increase the duration of the "hold" blitheness (as this is a heavier attack and should take more time to charge up):
I've too added keyframes to the position runway, to add additional move to the player every bit it charges its set on and unleashes information technology:
Since the histrion now moves in this Sequence, make certain that it moves dorsum to (0, 0) at the end of the animation so that the transition from Sequence to instance is seamless as well. Also make certain to adjust the hitbox and then it fits the new animation (y'all'll encounter in the GIF above that I've fabricated it larger for this set on).
Area of Outcome
To spice up this assail and go far stronger, nosotros'll add an surface area of effect circumvolve. I'll make it start small when the player attacks and grow gradually until the stop of the animation. I'll as well add the Colour Multiply parameter rail and add keyframes to brand it fade away at the terminate (you can set the alpha to 0 in the color picker to reach this effect).
Still, this is only a sprite and we need some other hitbox for this area of effect attack. Yous can add together the hitbox object again to create another attack, and make it fit the new circle:
I've inverse its colour using the Color Multiply track then I can hands differentiate between the two hitboxes. Also note that I am using the same hitbox object in all my Sequences, however you can create multiple hitbox objects and use different damage values and status effects for each, which you lot can and so utilize in different Sequences to add variation to your combat system. For example, yous can create a new hitbox object that does double the impairment and use that in the heavy assail Sequence.
You can at present hitting Shift+Space in the game to play the heavy assail animation, which has an awesome area of effect assail that easily inflicts impairment on multiple enemies!
Idle Slumber Sequence
You tin do a lot with Sequences, and so instead of focusing only on creating attack animations, we'll also create a "sleep" animation that plays 5 seconds after the histrion has been left idle.
I'll create a simple Sequence called seqIdle1 and brand it then the role player looks around so goes to sleep. For this I am using the Epitome Alphabetize parameter to manually control the frames, so I can brand the player sleep for longer. At the end of the Sequence, it wakes up and returns to its usual pose.
Of course, we'll also make information technology so that the player can wake it upwards by pressing an input button.
To implement this animation, we'll first create a variable in the player object chosen idleTime, and fix it to 0. This will tell how many frames it has been since the thespian has been left idle, and will be used to trigger the sleep animation.
idleTime = 0;
I'll add together some code in the Begin Step upshot to handle this blitheness, so it runs before the Step consequence and is as well able to run while the player is disabled (as I haven't put the "exit" code into this event -- if y'all have, make sure to add together this code before that line).
if (inputX == 0 && inputY == 0) { if (enabled) idleTime ++; if (idleTime > 300) { StartAnimation(seqIdle1); idleTime = 0; } } else { idleTime = 0; if (activeAnimation == seqIdle1) { var _seqLength = layer_sequence_get_length(activeSequence); var _newHeadPos = _seqLength - xx; if (layer_sequence_get_headpos(activeSequence) < _newHeadPos) { layer_sequence_headpos(activeSequence, _newHeadPos); } } }
First we check if inputX and inputY are zero, pregnant there is no input on either centrality. In that case, as long as the player is enabled, we increase its idleTime value. When that value exceeds 300 (which is five seconds as by default each second has 60 frames) we start the seqIdle1 animation and reset the idleTime to 0.
This will now start that animation, and enable the histrion again once it's over. Nevertheless, we also desire the actor to be able to end the animation manually past giving input on either axis, then they tin control the grapheme again. That is what the else block handles.
The else block runs if at that place is input on either centrality, and in that instance information technology resets idleTime to 0. Then it checks if the seqIdle1 animation is currently agile, and in that instance gets the length of that Sequence. We now want to end the Sequence, however we're non going to make it bound to the terminal frame immediately as that would look abrupt. Instead, we'll make the Sequence play its terminal 20 frames, then that we meet the character getting up.
The _newHeadPos local variable stores that frame number, by subtracting 20 from the Sequence's length. It then checks if the Sequence's current playhead position is less than that frame, in which instance it moves the playhead to that frame. So basically, once the player gives input, the Sequence jumps to that frame, which ways the character will be seen getting upwardly so the control will be returned to the player.
You lot tin can at present run the game, wait five seconds and see how the histrion goes to sleep. Pressing a motility button at any moment wakes it upwardly:
More than Assail Sequences (+ Combining Attacks!)
Using the same technique as we did for seqAttack1, I've created a new attack called seqAttack2 and assigned a new cardinal to it. This is only some other attack animation that was placed into the Sequence with a hitbox, without any changes to its frames:
We can at present create a heavy version of this set on: seqAttack2_Heavy. Like to the previous heavy attack Sequence, this also has additional concur frames and movement animation so we get a stronger-looking attack:
Y'all can run across that it also has an animative hitbox, which is pretty cool!
We'll brand this Sequence special by adding another assail to it. I'll but repeat the steps I followed for animative seqAttack1_Heavy and create the same animation in this Sequence, forth with a new hitbox. Notation that I've used the Prototype Index parameter for this besides and so I could start information technology on the 4th frame instead of the starting time one (to leave out the "charging" part of that animation):
Player too OP please nerf.
To create combined attacks hands, y'all tin can pull your older Sequences directly into a new one without having to recreate the attack animations. For example, the following Sequence combines three dissimilar attacks by including those three Sequences in it (yous tin can simply drag a Sequence from the Nugget Browser into the Sequence Editor to place it at that place):
Make sure the positions of your Sequences are (0, 0) in the combined Sequence to keep the transitions seamless.
Conclusion
Having Sequences in your Game Making armory ways yous don't always need to depend on sprite animations, equally yous can create custom animations within GMS2 to extend on the art you have and to improve your visuals without drawing new sprites. Of course, this post is only a small instance to demonstrate the power of Sequences, and when it comes to using Sequences in your game, the sky's the limit!
Let us know what you idea of this weblog on Twitter @YoYoGames, and remember to employ the #GameMakerStudio2 hashtag when sharing your creations with the world. Yous can also hit me upwards at @itsmatharoo if yous have any technical questions.
Happy GameMaking!
Sprites past Penusbmic on itch.io: https://penusbmic.itch.io/sci-fi-character-pack-11
Source: https://gamemaker.io/en/blog/busting-moves-sequences
Posted by: grimesmorningard.blogspot.com
0 Response to "How To Make A Idle Animation In Game Maker Studio 2"
Post a Comment