Unity2D – Sprites 1

17 10 2013

Heh, nothing to do with the official release of Unity’s 2D support (which I found somewhat underwhelming to be honest, but that’s what you get from trying to add more features instead of making a proper new editor, anyway I digress). There are a lot little tricks and improvements I’ve employed during the last few months in order to constrain Unity3d to 2d while making a 2d game (the budding website of which you can find here). One of the important things I wanted to address first was sprite creation and manipulation by the designer. As we all know using Unity’s in-built plane mesh is kind of rubbish and while I know there’re plenty of other ways to generate a simple quad mesh I’ve opted to generate my own (as many others have before me).

The code for this is contained in the following factory [SpriteMesh];

/// <summary>
/// This factory class is responsible for manufacturing quad meshes for use with sprite objects in the game.
/// </summary>
public static class SpriteMesh
{
  public static Mesh Make(Vector2 size)
  {
    var mesh = new Mesh
      {
        name = "sprite-mesh",
        vertices = MakeVertices(size),
        triangles = MakeTriangles(),
        uv = MakeUV(),
        normals = MakeCameraFacingNormals(),
      };
    
    mesh.RecalculateBounds();
    return mesh;
  }
  
  public static Vector3[] MakeCameraFacingNormals()
  {
    var normals = new Vector3Collection();
    for (var index = 0; index != 4; ++index)
      normals.Add(0.0f, 0.0f, -1.0f);
    return normals.ToArray();
  }

  public static Vector2[] MakeUV()
  {
    var uv = new Vector2Collection
      {
        {0.0f, 0.0f},
        {0.0f, 1.0f},
        {1.0f, 1.0f},
        {1.0f, 0.0f},
      };
    return uv.ToArray();
  }
  
  public static int[] MakeTriangles()
  {
    var triangles = new TriangleIndexCollection
      {
        {0, 1, 3},
        {3, 1, 2},
      };
    return triangles.ToArray();
  }

  public static Vector3[] MakeVertices(Vector2 size)
  {
    var half = size/2.0f;
    var vertices = new Vector3Collection();
    vertices.AddXY(-half.x, -half.y);
    vertices.AddXY(-half.x, +half.y);
    vertices.AddXY(+half.x, +half.y);
    vertices.AddXY(+half.x, -half.y);
    return vertices.ToArray();
  }
}

Ok, few things to notice before continuing on, since, if you just copy/paste this code it won’t work.

First, I’m using three specialized containers called, Vector2Collection, Vector3Collection and TriangleIndexCollection. These are just classes which wrap around a List<Vector2>, List<Vector3> and List<int> respectively and provide an easier interface for managing those cases.

Secondly, read the code again. The mesh is generated in a clockwise direction and with a very specific triangle and UV space orientation.

And lastly I want to mention that the underlying methods making the mesh are also marked public because they can be useful later.

Alright. We have an easy way to generate a mesh for use with our sprites. Now what?
I’m glad you asked. Because even if you didn’t I’m going to answer anyway.

Next we need to figure out exactly what is a sprite in Unity and how to create one…
The following definition is my own interpretation of Unity’s component model and how it can be used (your mileage may vary).
“A Sprite is a [GameObject] node which renders a specific material/texture across a [quad] mesh while allowing mesh control”.

And finally, creating a sprite. If you read the previous definition you’ll see that my sprite requires first and foremost a mesh and a material/texture. Since we’re creating the mesh ourselves we need some way to accept a material/texture. Let’s start with the simple case of having a single texture we want to use for our sprite (we’ll continue from there to create sprite objects from texture atlases). Finding and selecting textures for making sprites is easy! we have them in our asset folder (under /Textures/ if you’re like me). So let us make a menu item for creating a sprite from a selected texture.

/// <Summary>
/// This menu item allows the designer to generate a sprite object from the currently selected texture.
/// </Summary>
public static class MakeSpriteFromTexture
{
  [MenuItem("Found Cake Studio/Utilities/Make Sprite From Texture" + Hotkey.Alt.S)
  public static void Perform()
  {
    var selected_texture = Selection.activeObject as Texture2D;
    if (selected_texture == null)
      throw new UnityException("No texture was selected");
    
    SpriteObject.Make(selected_texture);
  }
}

If you’re wondering where that “Hotkey.Alt.S” came from then read the previous post. If you’re also wondering what’s that SpriteObject.Make() then have some patience, that’s our factory for making the sprite object. Let’s stub that factory class/method.

public static class SpriteObject
{
  public static GameObject Make(Texture2D texture)
  {
    throw new NotImplementedException(); 
  }
}

Annnnnd that’s it for today; part 2 to come in the next couple of days, complete with making the graphic components as well as the sprite mesh control.

“See the falls of Erloria, The grey mountains are near, Dark shadows falling, Daylight’s end is here…”

Advertisements

Actions

Information

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: