Animation Tips and Tricks

From The Official Visionaire Studio: Adventure Game Engine Wiki
Revision as of 17:11, 24 July 2022 by AFRLme (talk | contribs)

On this page you will find a bunch of different tips & tricks that you can apply to animations that you have imported into the animation frame sequencer; some of these tips & tricks might be applicable to Spine sprite part animation models & 3D character models.

The whole point in this page is give you ideas on how you can optimize your animations & your game overall by reducing the amount of animation frames needed to create smooth looking animations.

Anyway, let's crack on...


What is the Animation Frame Sequencer?

I'm just going to assume that most of you already know what it is, but just in case you don't, it's the animation form you can find around various sections of the Visionaire Studio editor that let's you import or batch import animation frame images into the engine. By default you can control the global duration of the frames, the duration of individual frames, the playback mode of the frames, & the amount of loops the animation should perform - however, we can get a lot more creative with what's possible via action parts, scripting, & some clever edits to the duration of individual frames.

Vs anim frame sequencer.png


Getting Started

Now before I go over the various animation tips & tricks, we need to setup a few things first that we will need further down the road for some of the methods listed below. This involves a bit of scripting, but don't worry it's nothing complicated. I just need you to navigate to the script section of the Visionaire Studio editor, create a new definition type script, rename it to workflow_functions, & then paste the code below into it.

math.randomseed( os.time() ) -- init math.random (make sure math.random is actually random each session)
math.random(); math.random(); math.random() -- shake things up a bit & make sure it is actually random

-- * function used to force animation frame range; i.e: frame 2 to 4 or frame 1 to 1, etc. * --
function setAnimFrames(anim, f, t) -- syntax: setAnimFrames(animation name, from, to)
  t = t or f -- fallback in case t equals nil
  if f > t then f = t end -- fallback in case f is greater than t
  ActiveAnimations[anim].FirstFrame = f -- update from animation frame range
  ActiveAnimations[anim].LastFrame =  t -- update to animation frame range
end


Individual Frame Duration

By default animations will automatically use the global pause (duration) value specified in the Anim propertiesv2.png properties section for the animation, however you can enable the option set pause for each frame, which will allow you to specify a unique duration value for each animation frame. Only frames that have a value other than -1 will be affected by this option. All frames that contain a value of -1 will use the global pause (duration) value.

Using this option lets you create dynamic looking animations where you can give your animations the appearance that they have some weight behind them. It's also a useful method for reducing the amount of animation frames you need to use for an animation, for example... let's say that you want a specific frame to play 3 times in a row, well in other programs you might need to import the same image 3 times to do that, but in Visionaire you can just adjust the duration of that specific animation to last 3x the global pause (duration) value.


Dynamic Frame Duration

This next tip is a bit of a tricky one, but it's one of my favorite methods for turn borning repetitive animations into animations that feel & look more natural by applying a dynamically generated duration value between specific animation frames - it also works a treat for adding a dynamic delay between animation loops.

1. Select the animation frame you want to apply a dynamic duration to. Edit the animation frame via Anim editframev2.png & open up the action modal box via Aktionenv2.png.

2. Inside of the action modal box create a new action via Addv2.png & then create a new execute a script action part & add something along the lines of this into it...

Animations["example"].Pause = math.random(1000, 3000) -- set dynamic duration of frame between 1 & 3 seconds

3. Close the action modal box & the animation frame editor modal box & then select the animation to the right of the one you have just edited & repeat the same steps, except in the execute a script action part you want to reset the pause value back to whatever the global pause (duration) value is that you specified inside of the Anim propertiesv2.png properties for the animation, which should look like something along the lines of this...

Animations["example"].Pause = 40 -- change frame duration back to global pause (duration) value

& that's it. You can use this method on multiple animation frames or even specific ranges of animation frames. Have fun experimenting with dynamic frame durations & don't be afraid to get creative.


Animation Frame Range

With a little bit of scripting magic we can force the engine to loop the animation between a specific range of animation frames or even loop a single frame. This can be useful for controling states, such as: door closed vs door open, etc. though you can alternatively do this via multiple scene objects & linking a condition or value to them to determine which object should be active/visible.

Quick note #1: This method will only work on animations that are set to loop infinitely, because non-looping & limited-loop animations are hidden after they have finished their specified loop amount.
Quick note #2: We will be using the setAnimFrames() function that I shared with you earlier in Getting Started.
Quick note #3: Animations have to be already playing/active for this method to work.

To loop a single frame you can do something along the lines of this...

setAnimFrames("example", 1) -- loop the 1st frame in the animation "example"

Or to loop a specific range of animation frames you can do something along the lines of this...

setAnimFrames("example", 2, 4) -- loop between the 2nd & 4th animation frame in the animation "example"

& just to show you how it can be done without the setAnimFrames() workflow function...

-- loop the 1st frame belonging to the animation "example"
ActiveAnimations["example"].FirstFrame = 1
ActiveAnimations["example"].LastFrame = 1


Animation Playback Order

Animations can be played forwards, backwards, or the animation frames can be played in a random order. Taking that into consideration it's possible to create pendulum animations that play in one direction then reverse back in the other direction, however we will be saving that for the next section of this tips & tricks guide.

You can specify the default playback direction/order inside of the animation Anim propertiesv2.png properties. Forwards will play the animation in the order it was created in. Backwards will play the animation from the last frame back to the first frame. Random will play the animation frames in a random order, which can be really useful for creating dynamic looking animations or for mixing up talk animations so they are less boring to look at if you aren't planning on adding lip sync to your game.

You can change the playback direction of any active/playing animation during runtime with a line of code that looks like something along the lines of this...

ActiveAnimations["example"].PlayOppositeDirection = true -- true = inverse direction; false = default direction


Pendulum Loop

What is a pendulum loop? A pendulum loop is when you play an animation in one direction & then play it back in the opposite direction.

There are multiple ways you could achieve this.

1. You could animate the entire thing, but this is bad in terms of optimization.

2. You could call a called by other action action via the execute action when animation ends option that's found inside of the Anim propertiesv2.png animation properties.

3. You could do this with the play animation action part, by setting it to play in one direction & wait, then same again but in the opposite direction & wait, & then you would jump back to the initial action part via the jump to action part #? action part to create a loop; providing you want it to loop, of course.

4a. You could insert a line of code into the first frame of the animation, which would be something along the lines of this...

ActiveAnimations["example"].PlayOppositeDirection = false -- play default direction

4b. & then the same again with the final frame of the animation with a line of code that is something along the lines of this...

ActiveAnimations["example"].PlayOppositeDirection = true -- play inverse direction


Move Animation

How can you make your animations move across the screen? Well besides the obvious answer of animating the movement inside of the animation itself, there's actually a few other options you can use for making your animations dance across the across the screen.

The Move Object Action Part

There's technically 2 move object action parts, but we are going to ignore move object as that one is based on relative offset from the default position, & we are instead going to be using move object to as that one uses absolute positioning, which makes things a lot simpler.

The Tweening Function

blah blah blah

The Curve System

blah blah blah


Rotation

Ideally rotation works best when the image/animation is flat to the screen as opposed skewed. Anyway, you can rotate objects with a line of code that looks something like this...

-- syntax: to(duration, {arguments}, easing, loop, pendulum)
game.CurrentScene.Objects["example"]:to(5000, {Rotation = math.rad(360)}, easeLinearInOut, true) -- rotate 360º over 5 seconds & loop


ScaleXYZ

Actually it's just X & Y, but I felt like completing the alphabet. Anyway, you can use scaleX & scaleY to flip any image or animation that's linked to a scene object or interface button.

Here's a quick scripting example of how to horizontally flip the image/animation belonging to a scene object...

game.CurrentScene.Objects["example"].ScaleX = -1 -- default = 1

& here's how to vertically flip an image/animation belonging to a scene object...

game.CurrentScene.Objects["example"].ScaleY = -1 -- default = 1


Final Notes

I know I haven't covered all methods as there are other features you can use such as the action part plugin system, or components, or behaviours that you can create via the visual scripting system, but I've never used the visual scripting system before & wouldn't know where to start. Anyway, if anyone has any other tips & tricks they want to include then please let me (AFRLme) know on our discord server.


Resources

Name Description
sceneception.zip A working .ved file, complete with resources. Check out the readme.txt file for instructions.