Pages

Welcome to my blog

My name is Gilles Charbonneau

I am a long time 2d animator and I would like to share with you some of the tips and tricks I have learned over the years by posting tutorials and articles on this blog.

Gilles

Scripting in Anime Studio - The basics

I tried, I really tried to stay away from scripting in Anime Studio, but I knew that I would eventually cave in, and I did, big time!

Scripting, for allot of peoples is a scary thing as most peoples put it in the same jar as programming, well, they are not quite the same, and scripting, especially in Moho/Anime Studio, will put much less strain on your brain!

Why is scripting a good and a bad thing for Anime Studio users?

Well, for one, it allows for the creation of tools that can ease your work flow tremendously by automating repetitive tasks.

With scripting, you can also extend the capabilities of Anime Studio by scripting tools that can do things that the basic software cannot do, like adding rig controls to your characters, for example.

The only bad thing is that scripting will obviously take away animation time from Anime Studio, but it is well worth the time and effort to learn, as the possibilities are almost endless.

Anime Studio scripting is done in Lua, a lightweight scripting language that has been around since 1993.

Now, there are two reasons why I am making this tutorial, the first one is that I like to make tutorials!

The second is that scripting in Anime Studio is by far the most technical thing you can do with the software, and there is very little documentation specific to scripting in Anime Studio.

Also, the little documentation available is often too hard to grasp for those who never did any programming or scripting before.

So, I will do my best to lay it down simply, in the hope that this will be useful to some of you!

Okay, enough chit-chat and let's dig into the good stuff.

You can find the finished script here.

gc_createcircle.zip 1kb

Before we actually get into scripting, we need to look at some of the basic concepts for scripting in general.

I will try to make it as painless as possibles.

THE TOOLS

To be able to script, you only need a basic text editor, one that can export plain text files.

Notepad is a good choice under windows, but a very good and free alternative is Developer Notepad, which add code highlighting, auto-complete, line numbering etc, and it is very easy to use.

BASIC CONCEPTS

Functions: Functions are scripts within a scrip. They are little scripts that run inside the main script.

They are usually used to do small tasks, like printing information to the screen or gathering information to be used by the main script, functions can be called at any time from within the main script.

A function is defined, or created with the function() class and you put the arguments you want to pass to the function between the parentheses.

Variable: Variables are basically containers, variable can hold almost any type of information that can be used by the script.

Variables can be local, meaning that they exist only for a certain task, usually from inside a function, or they can be global, meaning that the information they old can be used throughout the entire script, including functions.

Conditional statement: A conditional statement is a bit of code asking a question, like, if something happens, what do I do, and funny enough, the most used conditional statement is the IF/THEN pair.

if (SOMETHING_HAPPENS) then
DO_SOMETHING
end

Loops: Loops, as the name implies, loop through data and uses the FOR/DO pair.

Every time the count is incremented, some code is run.

An example could count from 1 to 10 and print something to the screen each time the counter gets incremented.

for i = COUNTSOMETHING do
SOME CODE
end

LUA

Levels of Lua: As I mentioned before, scripting in Anime Studio is done through the Lua scripting language and there are 3 levels or modules for Lua scripting.

LM Level: This is the most basic module for scripting inside of Anime Studio. This level holds the basic information like vector, colors, point motion etc.

LM.GUI: This module deals with the interface, this is where we build our custom menus, where we display warning or create the tools needed to interact with the software.

MOHO: This is where the action happens, this is the module where we create the content inside of Anime Studio, like points, curves, shapes etc. This is the most used module.

To script in Anime Studio, we need to reference these modules with build in constants, functions and classes.

There are 3 main types of scripts in Anime Studio.

Menu Scripts: Menu scripts are the simplest of the 3 types, you can find those on the top menu/Scripts drop down menu.

These are one time scripts, meaning that you run them, they do their magic, then they return you to Anime Studio Interface. If you want the magic to happen again, you need to run the script again.

Tool Scripts: You can find the tool scripts on the tool palettes at the left of your work area, these are comprised of the draw, fill, bone, layer, camera and workspace tools, plus you can add as many tool scripts as you like, and they will be displayed at the bottom of the tools palette.

The tools scripts are tools that get activated when you click their icons, and they stay activated until another tool is clicked.

These scripts are more advanced, as they allow for the creation and use of custom menus and much more, and they usually reside in the Script/Tool folder in your Anime Studio install folder.

Note: You can modify the layout of the tool palettes by editing the _tool_list.txt file in the Scripts/Tool directory by re-arranging groups and shortcuts to accommodate your workflow if you need or want to

Embedded Scripts:

You can add an embedded script by opening the layer property window then by checking the Embedded Script File box. Then a browsing widow appear, asking you to navigate to the location of the embedded script and selecting it.

Embedded scripts are evaluated on every frame of the animation, and make changes depending on their code.

Embedded scripts can be put in any folder you like on your system.

THANK GOODNESS THAT IS OVER!

OK, now let's have a look at an actual script.

This is a simple menu script that does only one thing, it creates a circle in the middle of the work area then assign the current style properties to it.

Let's have a look at it, then we will take it apart!

-- **************************************************
-- Provide Moho with the name of this script object
-- **************************************************

ScriptName = "gc_drawcircle"

-- **************************************************
-- General information about this script
-- **************************************************

gc_drawcircle = {}

function gc_drawcircle:Name()
     return "Draw Circle"
end

function gc_drawcircle:Version()
     return "6.0"
end

function gc_drawcircle:Description()
     return "Draws a circle on the workspace"
end

function gc_drawcircle:Creator()
     return "Gilles Charbonneau."
end

function gc_drawcircle:UILabel()
     return("Draw Circle")
end

-- **************************************************
-- The guts of this script
-- **************************************************

function gc_drawcircle:Run(moho)
     local mesh = moho:Mesh()

     if (mesh == nil) then
     LM.GUI.Alert(LM.GUI.ALERT_INFO, "This script only works on vector layers!")
          return
     end

     local v = LM.Vector2:new_local()
     mesh:SelectNone()

     v.x = -.25
     v.y = 0
     mesh:AddLonePoint(v, moho.layerFrame)
     v.x = 0
     v.y = 0.25
     mesh:AppendPoint(v, moho.layerFrame)
     v.x = 0.25
     v.y = 0
     mesh:AppendPoint(v, moho.layerFrame)
     v.x = 0
     v.y = -0.25
     mesh:AppendPoint(v, moho.layerFrame)
     v.x = -.25
     v.y = 0
     mesh:AppendPoint(v, moho.layerFrame)

     numpoints = mesh:CountPoints()
     
     mesh:WeldPoints(numpoints-1, numpoints-5, 0)
     
     mesh:Point(numpoints-5):SetCurvature(.4, 0)
     mesh:Point(numpoints-4):SetCurvature(.4, 0)
     mesh:Point(numpoints-3):SetCurvature(.4, 0)
     mesh:Point(numpoints-2):SetCurvature(.4, 0)
     
     mesh:SelectConnected()
     
     moho:CreateShape(true)

end

First of, every lines that starts with -- is a comment, these are not taken in consideration by the script. The ***** are just to make things look pretty!

The actual first line of code is

ScriptName = "gc_drawcircle"

This is where we tell the name of our script, The name of the script can be anything you like.

Usually the name of a script starts with the initials of the person who wrote it, in this case I started the name with gc, for Gilles Charbonneau, as this also help differentiate the script and prevent it from conflicting with another script.

-- **************************************************
-- General information about this script
-- **************************************************

This comment tells us that we are in the general section of the script. In this section, we have several functions that holds the general values of the script.

Most of this information is necessary for all scripts, you need to have these in all the script you will make.

gc_drawcircle = {}

On this line we create an array that we will use to handle all of our functions. In Lua this is called a table.

We will not get into the table object in this tutorial but you can look it up in the online manual listed at the bottom of this tutorial as it is an important concept for scripting with Lua.

function gc_drawcircle:Name()
return "Draw Circle"
end

Here we enter the name of the script as it will appear in Anime Studio menus.

As you can see, We use the array We created in conjunction with the Name() class to store the name of the script.

This way, Anime Studio can reference gc_drawcircle:Name() at any time to get the name of our script. We will do the same for the rest of the general information.

function gc_drawcircle:Version()
return "1.0"
end

Here you insert the current development version of your script, scripters often put in the lowest version of Anime Studio your script can run in.

function gc_drawcircle:Description()
return "Draws a circle on the workspace"
end

Here you enter the description for you script that will appear right on top of Anime Studio workspace.

function gc_drawcircle:Creator()
return "Gilles Charbonneau."
end

Here you enter the name of the creator of the script, in this case me, Gilles Charbonneau (boasting with pride on my chair here!)

function gc_drawcircle:UILabel()
return("Draw Circle")
end

In this last function of the general part of our script, we insert the title of the script, as it will appear in either the Scripts drop-down window or as users will pass their mouse cursor on top of the script icon in the tools palette.

-- **************************************************
-- The guts of this script
-- **************************************************

With this comment, we are now entering the heart of the script. This is where we actually do our coding or more precisely our scripting.

function gc_drawcircle:Run(moho)
local mesh = moho:Mesh()

On the first line of code, we create a function that tells the moho module to run this script.

Remember that there are 3 main scripting modules in Anime studio and that moho is the one that we use the most.

We use this line mostly with menu scripts, as they need to run as soon as they are called. Usually, a tool script listens to a mouse event to do anything once activated, while a menu scripts mostly only need to be run once.

We also create a local variable called mesh. This variable is constructed with the Mesh() class, which is part of the moho module and reference the current vector layer.

The mesh variable we just created is basically a reference to the current vector layer on which the script will work. It can contain points, curves, shapes and color fills.

if (mesh == nil) then
LM.GUI.Alert(LM.GUI.ALERT_INFO, "This script only works on vector layers!")
return
end

In this block of the script we have the conditional statement IF/THEN.

What IF does is this, it ask the question, are we on a vector layer right now?

It does that by checking if the mesh variable is empty (nil), if mesh is empty, it means that a vector layer was not selected at the time the script was run.

If we are not on a vector layer, the second line of code is run, which displays an alert window telling us that we need to be on a vector layer to run this script, then it runs the third line of the code, which exit the script.

But if the current layer is a vector layer, then the script continues.

Note that we use the Alert() class from the LM.GUI module to display the message.

local v = LM.Vector2:new_local()

This time, We create the local variable named "v", using the LM module class Vector2, which references a 2D vector or point.

In other words, v holds any information on the current 2D vector or point and can be used to reference any of its properties.

mesh:SelectNone()

This line of code deselect everything on the current layer.

v.x = -.25
v.y = 0
mesh:AddLonePoint(v, moho.layerFrame)

In this part of the code, we create the first point of our circle.

We assign -.25 to the x position (horizontal) value of the v variable, then we assign 0 to its y (vertical) value.

That value represent a coordinate on Anime Studio work space.

We then create our first point by calling the AddLonePoint() class from the moho module and assign it the coordinate values we entered in the v variable, we do so on the current layer frame.

What this does, is create a single point on the current vector layer at the specified coordinates.

v.x = 0
v.y = 0.25
mesh:AppendPoint(v, moho.layerFrame)

v.x = 0.25
v.y = 0
mesh:AppendPoint(v, moho.layerFrame)

v.x = 0
v.y = -0.25
mesh:AppendPoint(v, moho.layerFrame)

v.x = -.25
v.y = 0
mesh:AppendPoint(v, moho.layerFrame)

Here we are creating 4 more points, each at different coordinates.

The only difference we have here is that We use the AppendPoint() class instead of the AddLonePoint() class, which append a new point to the last one created.

In other words, the second point is appended to the first point we created with the AddLonePoint() class, then the third point is appended to the second point we created and so on.

At this stage we have created 5 points, and the first point and the last point are on top of each other, now we need to weld those overlapping points.

numpoints = mesh:CountPoints()

In this line of code, we create the numpoints variable and we assign it the amount of points in the current layer with the CountPoints() class.

We will use that information in the next few steps.

mesh:WeldPoints(numpoints-1, numpoints-5, 0)

This line of code weld the two overlapping points.

It does so with the WeldPoints() class.

The thing to understand here, is that each points in Anime studio is assigned an ID number, and that the last points created have the highest ID numbers.

So, say the current layer already has shapes on it, and that those shapes have 100 points in all, the numpoints variable we created should hold a number of 105, that is, the 100 points of the current layer, plus the 5 points we just created.

Now, to weld the overlapping points, we need to know the ID number of the first and last points we created, that is, the value of numpoints, which is 105, minus 1, for the last point and minus 5, for the first point we created. (Point ID start at 0, not 1)

So, in our example, assuming that the current layer already had 100 points in it before we created our first point (points 0 - 99), the first point we created would inherit the ID number 100, and the last one we created the ID number 104.

In this case, the WeldPoints() class will weld point ID 104 to point ID 100, on frame 0

WeldPoints(numpoints-1, numpoints-5, 0)

If the point we want to weld is not exactly on top of the target point, the point will be moved to the location of the target point then welded.

We now have a circle with welded points.

The only problem is that the amount of default curvature on the points of our circle is not high enough to make a perfect circle, so our circle is somewhat deformed.

mesh:Point(numpoints-5):SetCurvature(.4, 0)
mesh:Point(numpoints-4):SetCurvature(.4, 0)
mesh:Point(numpoints-3):SetCurvature(.4, 0)
mesh:Point(numpoints-2):SetCurvature(.4, 0)

In these 4 lines of codes, we set the curvature for each of the points we created, from ID numpoints-2 to ID numpoints-5 at a curvature value of .4 on frame 0.

Note: The point with the ID numpoints-1 was merged with the point with ID numpoints-5, so it does not exist anymore.

This gives us a perfect circle with start and finished points welded.

mesh:SelectConnected()

This line of code selects all the connected points we just created.

moho:CreateShape(true)

This line of code assigns a shape with the current style to the selected points.

end

This ends the script and returns us to Anime Studio, showing a brand new circle on the workspace.

HOW TO USE THE SCRIPT

This is a menu script, therefore it needs to be copied in the Scripts/menu folder in your Anime Studio installation folder.

You can put the script in any of the sub-folders, or you can create a new sub-folder to put it in.

You then call the script from the Scripts menu at the top of Anime Studio interface.

Remember that if you do not select a vector layer before you rune the script, a window will pop-up telling you to select a vector layer and the script will exit.

CONCLUSION

Here you have it, a basic introduction to scripting in Anime Studio.

Of course there is a better way to make a circle with scripting in Anime Studio, I went around the bush a few times to demonstrate some of the functions and classes available in the Anime Studio scripting interface.

As I said before, there is very little documentation on scripting in Anime Studio, but you can find some at these addresses.

Anime Studio V8 scripting interface. (Right-click then save as.)
http://www.lostmarble.com/downloads/pkg_moho.lua_pkg

Anime Studio V6.1 scripting interface.
http://my.smithmicro.com/downloads/files/AnimeStudio6.1ScriptingInterfaces.zip

Anime Studio 5.x scripting documentation.
http://www.lostmarble.com/moho/extras/scripts/moho_scripting.zip

In these documents you can find information on the constants, functions and classes you will need to make scripts for Anime Studio.

You can also find a very good online book on Lua scripting at this address.
http://www.lua.org/pil

Last but not least, I want to say thank you to Wes (SynthSin75) from www.animatorsforum.com for his help in clarifying some of the terms and concepts introduced in this tutorial, thanks Wes! :)

Well, I hope that this tutorial will give you a taste for scripting in Anime Studio.

After you have a grasp on the basics of scripting in Anime Studio, I suggest that you open existing scripts and learn from them, as they are the best source of information to develop your scripting skills.

If you have any questions, please do ask and I will do my best to answer them.

Good scripting!

Gilles

26 comments:

  1. Very good post, Gilles! This article is a perfect introduction to anyone interested in AS scripting. Great job!

    ReplyDelete
  2. Hello Hans and thanks.

    This was actually fun, and I hope it will help some peoples to get into scripting.

    ReplyDelete
  3. Hello! I'm not a skilled person in writing scripts. The only my experience is making jesusonic plugs for REAPER DAW. I understand well the algorithm structure and math, but I'm not familar with the concept of object-oriented programming. Maybe that is the cause why I have some stupid questions about the example given in Gilles Charbonneau's "Scripting in Anime Studio"
    Explain me please the next things, if it's possible:

    As I understand, the functions like this
    > function gc_drawcircle:Name()
    > return "Draw Circle"
    > end
    have predefined names and can be called by the host when the script is integrated into it. And statements like this:
    > local v = LM.Vector2:new_local()
    use some variables defined by the host.
    If so, where can I read the documentation about all these variables and functions? I'd like to know their names, their meaning and how is this all organized...

    Thank you for every helpful word.

    ReplyDelete
  4. Hello ortseam.

    You can find links to several documents at the bottom of the blog.

    These documents will show you all the constants, functions and classes needed to create scripts for Anime Studio.

    As for object programming, well, it is a vast subject, entire books have been published on the subject.

    To put it simply, what object oriented programming (OOP) allow, is the use of classes (objects) that can be called and used with parameters.

    In other words, instead of having tens if not hundreeds of code lines to achieve something, you use a few objects (classes) with parameters that will do the same thing.

    This makes for very re usable code that can be called easily!

    Hope this helps, don't be shy to ask questions.

    Gilles

    ReplyDelete
  5. Thanks Gilles. I think not only is scripting extra animating power... ASPro scripting and this tutorial gives insight into program behaviours that otherwise can seem a bit mysterious. Like point welding and ordering for instance.

    Thanks again - I haven't seen a beginners scripting document like this anywhere else.

    Gray

    ReplyDelete
  6. You are welcome gray.

    Yeah, ASP needed one of those and I am glad you appreciate it.

    It is quickly becoming the post with the most views on my blog.

    I am working on a new one, more advanced that should be out next Friday!

    ReplyDelete
  7. Hi am totally green on the scripting subject and I've tried opening the scripts but am stuck. I need to know how I intially open the tab for scripting in AS Pro8 coz I cant make my way through.

    Roy

    ReplyDelete
  8. I looked on the internet for the issue and found most individuals will go along with your opinion. Thanks!2d animation studios

    ReplyDelete
  9. I use a tablet and I'm used to a live preview of my lines being smooth from Sai Paint Tool and Inkscape:

    http://www.youtube.com/watch?v=3a9HNJ7qj1c

    and

    http://www.youtube.com/watch?v=tGcgglQCvAA

    Does anyone know someone who can do this for me in Anime Studio? I am 14 btw so if anyone replies I might need to be talked down to a little bit. (So sorry)

    ReplyDelete
  10. Just open the Display Quality dropdown menu at the bottom right or Anime Studio interface, then check antialiazing.

    ReplyDelete
  11. HOW CAN I TO FINISH THE SKETCHY EFFECT (I MADE IT ACCIDENTALLY)

    ReplyDelete
  12. Great stuff. Excellent read. Now it's playtime...

    ReplyDelete
    Replies
    1. I have a more advanced tutorial on scripting, look it up, and I am glad You like this one! :)

      Delete
  13. Thanks, Gilles! That was a great introduction. I'll be sure to check out your advanced tutorial.

    ReplyDelete
  14. Hello - I have not worked your script from this lesson
    I have Anime Studio Pro 10

    ReplyDelete
    Replies
    1. Hello Elli, I take it that You meant to say that the script does not work in V10, and if that is the case, it is quite possible as scripting evolves with new releases of Anime Studio.

      I will try it in V10 as soon as I can, and if need be I will modify it so it works in it, and probably look into modifying the tutorial as well.

      Thank You for letting me know!

      Delete
  15. Hi Gilles ,And Thanks Alot For The Article , But Dont Get Where Can I Write Script And Debug That For AnimeStudio !?

    ReplyDelete
    Replies
    1. Hello Hamed!
      You can use notepad or any Lua editor to write a script, then You need to install it for testing!

      Delete
  16. Can you help me little script for Selected Bone Angles Changing. Eg. I selected 2 Bones for Eye Blink, now i want to add 3 Key frames at 3 different frames by angle 90-0-90. It would be nice if I can do it with one click.

    ReplyDelete
  17. Can you help me little script for Selected Bone Angles Changing. Eg. I selected 2 Bones for Eye Blink, now i want to add 3 Key frames at 3 different frames by angle 90-0-90. It would be nice if I can do it with one click.

    ReplyDelete
    Replies
    1. Cant on top of my head, I will try to look it up, but I know this can be done in Moho!

      Delete
  18. Hi Giles. Thanks for posting these tutorials! I have a little bit of experience scripting for AE but I wasn't sure where to get started with Moho. This post puts me on the right path.

    ReplyDelete
    Replies
    1. Glad I could help, I have another tutorial on scripting, a more advanced one!

      Delete
  19. I really need a tool for MOHO, but I'd rather not take the time to learn Lua. This is a simple idea, but I can't get through to anyone on it. I would like to copy and paste all of the keyframes, at one point on the timeline, but only for ONE group layer, and all the sublayers. The theory is to copy a pose for a character, to another spot on the timeline. Then the character would animate to that pose, from the nearest keyframes. I do not like to use the bone tools, so far I find that to be a limiting 'flat' effect. I would use it for repeating poses, for example, a gesture and return to pose. Moho is driving me nuts, because I can only select, say, a few keyframes, from different sub-layers, at once. Sure, you can make keyframes for all the sublayers at once, but you can only paste what you can copy, which isn't much. The copy frame function isn't any good- either it works on the one sub-layer, or everything in the document, which is no good either. It might work- if I could compress the timeline vertically- like you can in some programs, so that the mouse/graphics pad could highlight all the keyframes, on selected layers. There are so many ways that this ALMOST works, the way Moho is written, but I can't do it.

    ReplyDelete