Getting Started

IMPORTANT

If you're having trouble, be sure to see the Troubleshooting section, as well as the relevant topic pages. If you still have an unresolved issue, be sure to visit the forum at forum.anbsoft.com.

Installation

  1. Open your Unity project and click Assets->Import Package->Custom Package...

  2. Locate the core SM2 unityPackage file which came with the SM2 distribution. Select it and click “Open”. Import all files.

IMPORTANT

For better performance, SM2 uses generics. If you receive a parsing error upon importing and are using Unity iPhone 1.7, make sure your project is set to use .NET 2.1. In Unity iPhone, click Edit->Project Settings->Player and change "Api Compatability Level" to .NET 2.1.
NOTE: There are usually two .unityPackage files included with a distribution: a “core” package which includes all necessary files, and a “sample” package which includes sample assets and demonstrates some of the features.

All scripts will be imported under the "Editor" and "Plugins" folders. The main scripts you will be accessing directly are found under:

Plugins/Sprite Scripts

Basic Setup

It is important to understand that SpriteManager 2 offers two different kinds of sprites (PackedSprite and ManualSprite) depending on what functionality you need.  We will look at step-by-step instructions for setting up each kind:
PackedSprite

The PackedSprite class is the more feature-rich of the two types of Sprites and probably the easiest to use.  It is particularly useful for people who do not want to have to layout their own texture atlases ahead of time or who want to make the most of their texture memory by using non-uniform sprite animations.  The PackedSprite class allows you to specify animations by dragging and dropping individual textures which, by themselves, constitute a single frame of sprite animation.  Then, as a separate step, you compile your sprite atlas(es) and each of these separate textures will be combined into a single texture without duplication.  Let's see how this works, step-by-step:

  1. Drag a PackedSprite script onto an existing GameObject.  In addition to the PackedSprite class, a Mesh Renderer and a Mesh Filter will also be added.  Under the Mesh Renderer, you must choose a material.  The material need not have a texture assigned to it yet as it will be assigned later when we generate our sprite atlas(es).  When the sprite atlas is generated for this material, it will be named after the material, so keep that in mind when naming your material.  It is recommended that this material should use a shader that uses vertex coloring so that you can take advantage of the Color feature (see Sprite settings for more information).  A sample material has been included with this package called "Sprite Material" you may want to use here.
        Material selection is very important here because sprites that share a material will share an atlas as well.  When two or more sprites point to the same material, any textures they use will be put together onto the same atlas.  This is important to remember if you are using lots of textures since this could wind up maxing out the texture size, forcing the individual textures to be reduced to make them fit.  If this happens, you will need to have some of your sprites use a different material so that their textures get placed onto a different atlas.

  2. In the inspector, you will now see the properties for the sprite.  These are the bare minimum settings you should setup to be able to use the sprite  in a static (non-animating) way:
    • Plane - Select the plane in which the sprite will be rendered.  (See the script reference entry for SPRITE_PLANE.)
    • Winding - The winding order of the sprite. (See the script reference entry for WINDING_ORDER.)
    • Width - The width of the sprite in the world.
    • Height - The height of the sprite in the world.

  3. Now open the Sprite Animation Timeline editor by clicking Windows -> Sprite Timeline.  We will now assign a static texture - the texture to use for the sprite before animation (see the script reference entry for staticTexture).  We do this by dragging a texture onto the "Static Texture" slot in the timeline editor window.

    With that set, we could build our atlas now and be ready to go with a non-animating sprite.  But let's continue on discussing how to setup animation.

  4. To create an animation, simply click the "+" button in the timeline editor.

  5. Now you should see the following settings in the timeline window:
    • Name - This is the name of the animation and can be used to refer to this particular animation in-script, provided it is unique.
    • Loop Cycles - The number of times the animation should repeat before stopping (set to -1 for infinite looping). For more info, see the script reference entry for loopCycles.
    • Loop Reverse - Whether the animation should reverse when it reaches the end. For more info, see the scrip reference entry for loopReverse.
    • Framerate - The rate at which the animation should place in frames per second.


  6. To add frames to the animation, simply drag one or more textures onto the timeline window. You will see them added to the timeline. You may drag frames around to reorder them. You can also click "Preview" to preview how the animation will look.

  7. We are now finished setting up animation on this sprite. We are ready to build our texture atlas. To do this, click the "Tools->A&B Software" menu item at the top and then select "Build Sprite Atlases", or alternatively, use the keyboard shortcut (Option+A / Alt+A). A menu will appear with options for creating your sprite atlases:
    • Atlas Folder - This is the folder off of the Assets folder where the generated atlases will be placed.
    • Max Atlas Size - The maximum size of an atlas in pixels. NOTE: If your textures, when combined, exceed the max atlas size, they will be scaled down to fit. The default value is 1024 which is the maximum texture size for iPhone.
    • Padding - The number of pixels to place around the borders of the sprites when stitched together. This can help prevent "bleeding".
    • Trim Images - When this is checked, any "empty" space surrounding the content of a sprite texture will be trimmed away before being added to the atlas. this can save a lot of texture space.
    • Force Square - Force the atlas to be square. This is useful if you plan on using PVRTC compression, which requires the texture to be square.
    • Scan Project Folder - Scans the project folder for prefabs containing sprites when building the atlas. It is important to know when to use this feature. For all the details, see Building Atlases.

    NOTE: Remember that anytime you change the frames in any of your sprite animations, or the static texture, you will need to re-build your atlases for the changes to take effect.

  8. By now your atlases are now generated and you are ready to go! If you have checked the box next to "Play Anim On Start", just hit play and see your animation. We have only scratched the surface of what we can do with SpriteManager 2. Now would be a good time to review the other Sprite settings, Animation Settings, and Building Atlases sections.

ManualSprite

The ManualSprite class works in a similar fashion to the original SpriteManager sprites.  Animations consist of a series of uniformly-sized sprite frames.  This class is useful if you want to use pre-made sprite atlases and do not want to use the new atlas generation feature.  To setup a ManualSprite component, follow these steps:

  1. Drag a ManualSprite script onto an existing GameObject.  In addition to the ManualSprite class, a Mesh Renderer and a Mesh Filter will also be added.  Under the Mesh Renderer, you must choose the material that uses the texture for your sprite(s).  It is recommended that this material should use a shader that uses vertex coloring so that you can take advantage of the Color feature (see Sprite settings for more information).

  2. In the inspector, you will now see the properties for the sprite. The bare minimum settings you should setup to be able to use the sprite are:
    • Plane - Select the plane in which the sprite will be rendered. (See the script reference entry for SPRITE_PLANE.)
    • Winding - The winding order of the sprite. (See the script reference entry for WINDING_ORDER.)
    • Width - The width of the sprite in the world.
    • Height - The height of the sprite in the world.
    • Lower Left Pixel - The coordinate of the lower-left pixel of the sprite in the source texture.
    • Pixel Dimensions - The width and height of the sprite, in pixels, as it appears in the source texture.

  3. If all you want is a basic "static" (non-animating) sprite, you can stop here. But let's continue on discussing how to setup animation. To create animations, click the arrow next to Animations to expand it. Now you should see a "Size" value you can set. Set this to the number of animations you want the sprite to have.

  4. Now you should see an "Element #" for each corresponding animation you chose to add. Let's expand the first one to setup the first animation in the list. Once we've done so, we see we can set a few settings:
    • Name - This is the name of the animation and can be used to refer to this particular animation in-script, provided it is unique.
    • Loop Cycles - The number of times the animation should repeat (in addition to the initial play-through) before stopping (set to -1 for infinite looping). For more info, see the script reference entry for loopCycles.
    • Loop Reverse - Whether the animation should reverse when it reaches the end. For more info, see the scrip reference entry for loopReverse.
    • Framerate - The rate at which the animation should place in frames per second.

  5. Finally, you'll see an array called "Clips". To give you maximum flexibility in creating your animations, the way animations work with the ManualSprite class is that an animation is actually a collection of one or more "clips". A clip is its own little animation. By combining clips together, you can re-use portions of your sprite animations by mixing and matching to build a single, continuous animation.
        Expand the "Clips" array and set the "Size" to the number of frames you wish to have in this clip. You will see many similar settings to what we encountered in the animation settings. They each work the same as their animation counterparts, only on the clip level. But for now, let's move on to defining the actual frames of our animation.

  6. To define the actual frames of animation we will use from our source texture, we need to set the following settings:
    • Start - The lower-left pixel of the first frame of animation on our sprite atlas.
    • Pixels To Next Column And Row - The number of pixels from one sprite to the next. For a more detailed description, see the script reference entry for pixelsToNextColumnAndRow.
    • Cols - The number of columns in the animation grid.
    • Rows - The number of rows in the animation grid.
    • Total Cells - The total number of frames (cells) of animation in the grid.

    Now that we've configured an animation clip, we've covered the gamut of setting up the basic static (non-animating) and animated features of the sprite. Now would be a good time to review the other Sprite settings, Animation Settings, and Building Atlases sections.

Playing Animations

There are several ways to play animations on a sprite. You can play them by name, by index, or by reference. The fastest method is by reference, and a close second is by index. However, most of the examples you will find in this documentation will use the name method because it is easier to read and simpler to understand.

There are two main method categories which will play an animation: PlayAnim() and DoAnim(). The difference between these two is that PlayAnim(), anytime it is called, will re-start the animation at the first frame (or frame specified). DoAnim(), on the other hand, will only start an animation if that same animation is not already running. It is therefore a good idea to use DoAnim() in places where you just know that a certain animation ought to be running if it isn't already but don't want to have to check first. Use PlayAnim() in places where you know the animation should always start over, or start from a particular frame.

Both PlayAnim() and DoAnim() have versions which accept the animation's name, index, or reference as arguments. Some examples of these are shown below ("sprite" in the code below, is assumed to reference a ManualSprite or PackedSprite script).
// Play "walk" animation:
sprite.PlayAnim("walk");

// Play "walk" animation if it isn't playing already:
sprite.DoAnim("walk");

// Play the animation at index 3:
sprite.PlayAnim(3);

// Play the animation referenced in the variable walkAnim:
sprite.DoAnim(walkAnim);
In addition to these, the PackedSprite class also has versions of each which also accept an additional frame number argument. This second argument is the 0-based index of the desired frame on which the animation should start playing. Some examples:
NOTE: These versions are only available on PackedSprites
// Play "walk" animation, starting at frame 3:
sprite.PlayAnim("walk", 3);

// Play animation at index 2, starting with frame 1:
sprite.DoAnim(2, 1);

// Play animation referenced by walkAnim, starting with frame 5:
sprite.PlayAnim(walkAnim, 5);
Stopping and Pausing

You may also stop and pause playback of an animation using the StopAnim() and PauseAnim() methods, and can unpause using UnpauseAnim():
// Pause playback of the current animation:
sprite.PauseAnim();

// Resume playback:
sprite.UnpauseAnim();

// Stop the animation entirely:
sprite.StopAnim();
Posing

    You may have a sprite that instead of, or in addition to, using animation, it uses a series of "poses" depending on its state.  An example would be an overhead view of an airplane that shows the airplane at various angles of banking depending on how steep the player is turning.  For situations like this, you wouldn't want to play an animation but you can't get by with only one static frame either.
    In this situation you can use multiple, single-frame animations and simply "play" each animation that is needed for the particular pose.  This will effectively change the frame being displayed. Alternatively, you can store the entire range of "poses" in a single animation, and simply play the animation starting at a specific frame, and then immediately pause the animation, like so:
// Frame 4 contains our desired "pose":
sprite.PlayAnim("Poses", 4);

// Immediately pause here:
sprite.PauseAnim();

Additional Notes

Making Changes

Always remember, whenever you make changes to a sprite, such as changing its static texture or the frames in its animations (including deleting them), you must rebuild your atlases for the changes to take effect.

IMPORTANT NOTE: If your game consists of more than one scene that contain identical sprites, or you have any prefabs with sprites, it is recommended that every sprite you create be associated with a prefab, and then as you make design changes to your sprites (such as changing their textures), only make these changes to the prefabs directly and let the instances of those prefabs in your scene(s) be automatically updated. Making changes directly to sprites in a scene which are linked to a prefab will cause the properties you change to "override" the same properties in the prefab. The problem with this is that the atlas builder will skip prefab instances and only look at the "source" prefab, meaning a prefab instance that has a different set of textures than its original prefab will not get updated with the correct UVs and will not have its differing source textures included on the atlas. This is by design so that sprites in a non-open scene do not get "left behind" when a new atlas is generated.
The rule of thumb is to manage and keep all your sprite types in prefabs and only modify the properties of the prefabs themselves and not the prefab instances in a scene.

Note

Sprites in a scene which are marked as inactive cannot be included when the atlas is rebuilt. In such cases, make any inactive sprites into prefabs and use the Scan Project Folder setting when building your atlases.
Texture Sharpness

Even when using Pixel Perfect, the Unity renderer may generate somewhat blurry results depending on what settings you use for mip mapping and texture filtering. If you desire pixel-perfect rendering, it is recommended that you disable mip map generation for the generated texture atlas and change the texture filtering mode to "Point", as well as disable compression. Disabling mip map generation will also save memory and would not be used anyway if the sprite is always displayed pixel-perfect.
Destroying sprites (Unity 3.1 and earlier only)

If you destroy sprites at runtime using Destroy(), be sure that you call Delete() on the sprite script before doing so. Otherwise, you may experience a memory leak as the sprite's mesh does not get freed. This is a result of a peculiarity in how Unity handles meshes. Calling Delete(), however, ensures that the mesh gets freed properly.