Skip to content

Instantly share code, notes, and snippets.

@bcatcho
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bcatcho/9755907 to your computer and use it in GitHub Desktop.
Save bcatcho/9755907 to your computer and use it in GitHub Desktop.
An example off the top of my head to show how to use a single mesh to make many with different textures from an atlas. Is a reply to a reddit thread: http://www.reddit.com/r/Unity3D/comments/2199b2/a_little_help_with_playing_cards/

Note: This has not been compiled. It is straight off the top of my head.

That being said it should be close and I believe it demonstrates my point. My explination will assume that this compiles.

Prerequisites

  1. A Mesh for your card. Make sure that all UV's are unitized. In other words. The UVs for the each face of the card should be a square stretching from (0,0) in the bottom left corner to (1,1) in the top
  2. A texture atlas with all of your card faces.
  • each texture needs to be spaced consistently

How to use this example

  1. Make a new game object with the CardFactory MonoBehaviour from this Gist.
  2. Fill out the public properties in the inspector.
  • This script assumes that the size of the texture atlas along each side is a perfect multiple of the size of your cards. In other words, if the Rows = 3 & Colums 4, a single card texture will have a height exactly 1/3 of the atlas height and 1/4 of the atlas width.
  1. Create a Material asset with your texture. Any will do.
  2. Make another gameobject with a MeshRenderer, MeshFilter and add the Material from step 3 to this gameObject.
  3. Run the scene. Once the gameobject awakes, it should fill up the Deck array on the CardFactory with new meshes. Simply drag one of the Meshes in the Deck array into the MeshFilter mesh slot to check it out.
using UnityEngine;
public class CardFactory : MonoBehaviour
{
// this will be the source mesh that every card will be based off of
public Mesh SourceMesh;
// the number of rows & columns in your texture atlas
public int AtlasRows;
public int AtlasColumns;
// a place the result of this factory.
public Mesh[] Deck;
private void Awake()
{
Deck = new Mesh[AtlasRows * AtlasColumns];
var cardTextureSize = new Vector2(1 / AtlasColumns, 1 / AtlasRows);
// build all the cards
for (int y = 0; y < AtlasRows; y++)
{
for (int x = 0; x < AtlasColumns; x++)
{
Deck[y*AtlasColumns + x] = CardMeshBuilder(SourceMesh,cardTextureSize, new Vector2(x,y) );
}
}
}
}
using UnityEngine;
public class CardMeshBuilder
{
public static Mesh BuildNewMesh(Mesh source, Vector2 textureSize, Vector2 textureCoordinates)
{
// make a temp array for uvs
var uv = new Vector2[source.uv.Length];
// calculate the bottom left corner of the texture.
// this will be UV 0,0
var offset = Vector2.scale(textureSize, textureOffset);
// calculate all the uvs for the new mesh
// each uv will be scaled down to the individual texture size and offset
for (int i =0; i < uv.Length; i++)
{
uv[i] = offset + Vector2.scale(source.uv[i], textureSize );
}
// build the resulting mesh
var result = new Mesh();
result.Clear();
result.vertices = source.vertices;
result.uv = uv;
result.normals = source.normals;
result.triangles = source.triangles;
return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment