Sprite Factory - Sprite Animation System

Does this asset do anything that 2DToolkit doesn’t? Does it make sense to own both? Thank you

Hi,

One of the biggest differences is Sprite Factory’s editor workflow. I designed the interface to be very straightforward instead of having to jump from window to window to get different tasks done. In the editor, you do everything in one interface including creating sprites and groups, creating animations, adding, removing, reordering frames, copying animations and frames, setting wrap modes, loop points, frame timings, frame events, aligning frames, creating, configuring, and animating colliders and locators (2DTK calls these Attach Points), creating atlases, creating material sets, etc, etc.

Other than the editor workflow, by far the standout feature of Sprite Factory is the animated collider system. If you’re planning on making a beat-em-up, one-on-one fighter, or even a hack and slash platformer, the collider animation system will make this job far easier than if you were to roll your own system for animating colliders. For a one-on-one, collision detection is an extremely important part of the game. With Sprite Factory, you can fine tune your collision boxes using as many colliders as you need, then group them by type so responding to collisions becomes very easy.

Here’s a video on the collision system. Unfortunately, the video is a bit outdated and doesn’t show the true power of the system. Since the video was made, the colliders can now be rotated to any angle so you can even better match your sprite’s shape. Also, collider groups were added recently so you can quickly filter collisions by a group, eg: HitColliders, and react accordingly.

Also, Sprite Factory can be mixed and matched with other 2D systems including 2DTK and Unity’s native 2D system. You could potentially use 2DTK (or another AS package) for tiled backgrounds, Sprite Factory for your characters, and Unity’s system for other elements. As long as they’re all configured to use the same collision system (Unity 2D or 3D physics), everything should interact correctly. Sprite Factory also supports Unity 4.3 Sorting Layers as well so it works together with Unity 2D nicely.

For reference, here’s an example of what you can do with the collision system:

Today only (12/19) - Sprite Factory is featured as the 24-hour deal on the Asset Store! 50% off. For all the work I put into it, this price is a total steal.

1.098 is live on the asset store!

Thanks for that detailed reply! I guess your system has a very strong point in character animation then?

Well, the collider system was initially designed for character animation, as was the Locator system (which was mainly to address the issue of bullet origin points and other spawn points). But both systems can be used for more than just those initial use cases. Since the collider system uses Unity’s 2D and 3D collision systems, pretty much anything you could do with a box collider, you can do with an animated box collider. I can imagine a scenario where you set off a Rube Goldberg type contraption by clicking on one sprite, animating its collider into the space of another sprite and so on without ever having to move a single transform or rigidbody. Really, the potential uses are up to your imagination.

Apart from the collider system, Sprite Factory provides a solid platform for sprite animation of any type. It can certainly be used for background elements and implements a batch scaling feature so you can have many copies of a sprite at different scales while keeping rendering down to 1 draw call. It supports static and animated sprites, plus Sprite Groups for sharing atlases (useful for background elements.) It provides atlasing in both Unity free and Pro, which is something Unity’s 2D system reserves for Pro only. The Sprite Factory editor has been tested to work with sprites with over 1,000 high-resolution frames each (high-fidelity, arcade-style fighting games).

There are some things Sprite Factory doesn’t do. It doesn’t provide a background tiling system, but that may or may not be needed depending on your type of game, and can certainly be added by using another tiling package. (You can certainly tile sprites together, but it wont’ auto-generate a mesh for you, that’s all.) It doesn’t provide a 2D GUI system either. It doesn’t (currently) do sprite dicing or polygon meshes (though both are on the to-do list).

I agree with guavaman. I’m using Sprite Factory and it’s a perfect tool : so easy to use !!! The creator thought abou all we need for creating animations + collisions for games !
And the support can’t be better.

6R

Hello guavaman. I will ask a question.

Ex: I have 2 mastersprites for character. ( 1-mastersprite for idle,run. Other mastersprite for attacks)

Can I use other mastersprite animation in same prefab?

Ex Script:

Default Mastersprite animation code: Play.Sprite(“idle”); This okay…

How can I call attack mastersprite animation?

Hi David!

Yes you can. You would create both Sprites in the scene first, then create an empty game object to hold both Sprites. Drag the two sprites into the new empty game object. So now you should have a hierarchy something like this:

MyCharacter
|
— UpperBody
|
— LowerBody

UpperBody and LowerBody both have Sprite components. MyCharacter is just an empty game object to hold both.

So you would put your custom script which controls the character on “MyCharacter.” From this script, you need to get the other two SpriteFactory.Sprite components so you can tell them to animate. Probably the easiest way would be to create two public variables of type SpriteFactory.Sprite in your script and connect the UpperBody and LowerBody to those variables in the inspector:

using UnityEngine;
using System.Collections;
using SpriteFactory;

public class MyCharacter : Monobehaviour {

    // Assign these in the inspector
    public SpriteFactory.Sprite upperBody;
    public SpriteFactory.Sprite lowerBody;

    void Update() {
        // your game code here...
        
        // to make the character's legs walk
        lowerBody.Play("Walk");
        
        // to make the character's upper body attack
        upperBody.Play("Attack");
    }
}

If you’re using a CharacterController or collider + rigidbody to move your character around, you’d want to put it on MyCharacter as well.

Hope that helps!

Thanks! :slight_smile:

I may not have thought of everything, but I tried to make it versatile. But if there’s something that it doesn’t do that’s required for the type of game you’re making, let me know and I’ll try to make it happen.

Is there a way to import a sprite sheet that was already made using another program? Or should I always import each frame as separate images and then have sprite factory create a texture atlas?

Unfortunately, no. Sprite Factory only works with individual source frames at present. So, yes, you should import each frame as a separate image and it will create atlases for you. It will trim the frames for you automatically if you have it set to in the Editor Properties.

1.099 is live on the asset store.

This update requries data to be rebuilt, so back up your project before upgrading!

1.100 is live on the asset store.

Is it possible for different colliders have different properties? Example hitting with the tip of a sword has different effects etc. Since they’re all created at run-time I’m not sure how i would discern this. My initial thought was to have all these properties put into the game object class, and then have them referenced based on which hitbox hits the trigger.

Hi!

I’m not totally sure I’m understanding your question correctly. Do you want to have the collider send information to its target, as in damage effects (1)? (damage, type, stun, poison, etc.). Or do you want to play back some graphical effect when the tip of the sword hits something (2)?

If you’re trying to do #1, here’s some example code on how you could achieve sending damage data to the target. You could differentiate different parts of the sword by checking the name of the collider and choosing a different damage object from an array. (BTW, there may be typos, I didn’t test this code.)

// This is in the attacker's script ////////////////////////////
 
// Stats about the current attack the unit is making
public DamageData[] attacks; // define various attacks in the inspector
 
void OnTriggerEnterSprite(SpriteCollider.CollisionData collisionData) {
 
   if(collisionData.spriteColliderName == "SwordTip") { // our sword tip attack collider hit something
 
       Collider otherCollider = (Collider)collisionData.objectValue; // get the collider that collided with this attack
 
       DamageData damageData = attacks[0].Clone(); // get the data for this particular attack
 
       // Send a message to the root of the object we collided with
       otherCollider.transform.root.SendMessage("ApplyDamage", damageData, SendMessageOptions.DontRequireReceiver); // send the message to the root object and don't require a receiver
    }
}
 
// In another file ////////////////////////////
 
// A class to define damage properties and carry damage to the enemy
[System.Serializable]
public class DamageData {
    public int type; // type not used in this example, but you can have all sorts of stats for the damage
    public float amount; // how much damage does this attack do?
 
    public DamageData(int type, float amount) {
        this.type = type;
        this.amount = amount;
    }
    
    public DamageData Clone() {
        return new DamageData(this.type, this.amount);
    }
}
 
// In the enemy's script ////////////////////////////
 
void ApplyDamage(DamageData damageData) {
    // apply damage
    life -= damageData.amount;
 
    // check for death
    if (life <= 0) { // dead
        sprite.Play("death");
        Die();
    } else { // not dead, just play hurt
        sprite.Play("hurt");
        audio.Play();
    }
}

You can also filter by collider groups if you have several colliders which need to do the same effect but you don’t want to check every collider name.

If #2 is more what you’re looking for, its a bit simpler, but still similar.

// This is in the attacker's script ////////////////////////////
 
void OnTriggerEnterSprite(SpriteCollider.CollisionData collisionData) {
 
   if(collisionData.spriteColliderName == "SwordTip") { // our sword tip attack collider hit something
        
        // if you need the sword tip collider for some reason, do this:
        ColliderInfo colliderInfo = sprite.GetCollider("SwordTip");
        
        // Depending on the type of collider you're using...
        BoxCollider boxCollider = colliderInfo.GetCollider<BoxCollider>(); // for 3D colliders
        //BoxCollider2D boxCollider = colliderInfo.GetCollider<BoxCollider2D>(); // for 2D colliders
        
        // play some effect or instantiate a prefab which is stored in a variable in this script
    }
}

So in both these examples, your main script is holding the damage/effect data. But if you really want to add a component to the collider’s GameObject to hold the data instead, you can.

ColliderInfo colliderInfo = sprite.GetCollider("SwordTip");
Component comp = colliderInfo.colliderComponent; // get the collider component (doesn't matter whether its 2D or 3D)
GameObject go = comp.gameObject; // get the game object that owns this component
MyComponent myComponent = go.AddComponent<MyComponent>(); // add your new component to the game object
myComponent.SetData(someDataHere); // insert some data into your new component

I don’t recommend doing it this way because its a little clunkier than the first methods I showed you.

Let me know if that answered your question or if I totally misunderstood.

Some help pages on the topics I mentioned in this post:
Colliders (see Collider Groups)
Sprite.GetCollider
ColliderInfo
ColliderInfo.GetCollider

Thank you for the comprehensive reply. The 1st example is what I’m looking for. Looking through the documentation now. I don’t quite fully understand the code, but I appreciate it and am looking through it. So with this I could input damage data through the inspector into the public class DamageData? DamageData[ ] defining an array of different attacks that I could call upon depending on the hitbox name?

For my purposes I was thinking of merely sending data thats set as I play each animation(As I play Animation SlashA, my damage is set to 50 etc.). So I could re-use the same few colliders and just change the properties for each attack. I think I can do that with the code you gave. Thank you for the help.

I see. Yes, that’s generally how I would do it. Reuse the colliders and just change the data sent based on the attack. I have an example I made where I use ScriptableObjects to create predefined attack objects (like prefabs) that you can drop in an array and even reuse them on different characters. PM me your email and I’ll send you the project if you’d like to see how I did it.

Hi, I’ve just tried Sprite Factory and I have 2 questions.

It’s possible to just export the collider information? (ex: xml format) I really like the editor for the collider but I want to keep my sprite system. Or do I need to do it myself, you gave all the source right?

Second, do you plan to support undo in the collider editor?

Thanks

Hi,

To answer your questions:

  1. There’s no built-in way of exporting the collider information. You could look through the source code, but you probably don’t need to. All the collider data is serialized in the GMS file for your sprite under SpriteFactory/SaveData/Assets/Sprites/Game/GMS~YOURSPRITENAME~GMS. The animation for the colliders is stored under data.animations[#].frames[#].colliderFrames[#]. The collider frame # corresponds to a frame for a particular collider set, so if you have 4 collider sets defined, each frame has data for each of the 4 colliders. If you need the specific variable names and don’t feel like trudging through the source or using SerializedObject to find them, let me know. It shouldn’t be very difficult to make an exporter.

But you should know that getting animated colliders to work the way you’d expect them to isn’t just a matter of animating the size and position of the collider. There’s quite a bit of voodoo you have to do with regards to enabling/disabling the sprite and having the colliders still work, and a bunch of extra processing when doing it for 2D colliders because Unity’s 2D collision system doesn’t report events properly when animating the shape of the collider. Quite a few long nights of trial and error to get it working…

  1. I have no plans to add undo inside the editor right now. As far as I’ve been able to determine, Control + Z is treated in a special way by Unity and is always passed to the scene/inspector. I haven’t found a way around this problem if there is one. It’s not as nice as undo but reverting will allow you to undo all the changes made since your last sprite save.