UV mapping

Hello guys.

I am making a game similar to minecrafts graphic style.
I only work as a programmer, so I am a total noob when it comes to 3D models.
So for example: I have a grass block where the sides are going to be the same, but the top and bottom have different textures.
So I was wondering if I could UV map the standard cube in Unity from within my script.

Thanks a lot.

I have listed all the ways to custom UV map a unity cube here : Apply uv coordinates to unity cube by script - Questions & Answers - Unity Discussions

Imagine looking at the front of the cube, the first 4 vertices are arranged like so

//   2 --- 3
//   |     |
//   |     |
//   0 --- 1

then the UV’s are mapped as follows :

theUVs[2] = Vector2( 0, 1 );
theUVs[3] = Vector2( 1, 1 );
theUVs[0] = Vector2( 0, 0 );
theUVs[1] = Vector2( 1, 0 );

//    2    3    0    1   Front
//    6    7   10   11   Back
//   19   17   16   18   Left
//   23   21   20   22   Right
//    4    5    8    9   Top
//   15   13   12   14   Bottom

So where the UV’s for Vertices 2 is ( 0, 1 ), so is 6, 19, 23, 4, 15.

You can test this by replacing all the zero’s with 0.5, then check every face of the cube has the same portion of the image, and rotated the correct way (not inverted) . Note if standing at the origin looking up the positive Z-Axis, Right is your right.

for example this script would map the TOP of the cube to any UV coordinates of a texture you like :

#pragma strict
// TOP

function Start() 
{
    // Get the mesh
    var theMesh : Mesh;
    theMesh = this.transform.GetComponent(MeshFilter).mesh as Mesh;

    // Now store a local reference for the UVs
    var theUVs : Vector2[] = new Vector2[theMesh.uv.Length];
    theUVs = theMesh.uv;

    // set UV co-ordinates
    theUVs[4] = Vector2( 0.5, 1.0 );
    theUVs[5] = Vector2( 1.0, 1.0 );
    theUVs[8] = Vector2( 0.5, 0.5 );
    theUVs[9] = Vector2( 1.0, 0.5 );

    // Assign the mesh its new UVs
    theMesh.uv = theUVs;
}

EDIT, In reply to : So if I create a texture atlas and assign sections to the different sides of the cube, is it possible to tile each side differently? Or would everything get tiled by the same amount? Cheers for the help, Muzzstick.

Me : I think an example scene would be a good visual demonstration. First, grab this texture : http://metaverse.mitsi.com/Secondlife/posts/uvmaps/images/uv_checker%20large.png

Now create a new scene, create a cube and attach that texture as a material. Create a new script and attach it to the cube. Copy in the below code, then hit play.

You see for each face a different part of the texture has been assigned, this is basically UV mapping. Change the values in the cube Inspector, then hit the Left mouse button. First try changing the width and height just to see the effects. Then change the x and the y for different start positions on the texture.

Hopefully this shows what UV mapping is, and how it usually applies to one texture atlas (sometimes called a texture map). Again, for a different texture, the plane method is the way to do it.

Anyway, here is the code :

#pragma strict

// using an image that is an 8x8 grid
// each image is 0.125 in width and 0.125 in height of the full image

// UVs in this example are given as a Rect
// uvs : start position X, start position y, width, height
// start positions are staggered to show different images
// width and height are set to 0.125 (1/8th square of the full image)

public var uvsFront : Rect = new Rect( 0.0, 1.0, 0.125, 0.125 );
public var uvsBack : Rect = new Rect( 0.125, 0.875, 0.125, 0.125 );
public var uvsLeft : Rect = new Rect( 0.25, 0.75, 0.125, 0.125 );
public var uvsRight : Rect = new Rect( 0.375, 0.625, 0.125, 0.125 );
public var uvsTop : Rect = new Rect( 0.5, 0.5, 0.125, 0.125 );
public var uvsBottom : Rect = new Rect( 0.625, 0.375, 0.125, 0.125 );

private var theMesh : Mesh;
private var theUVs : Vector2[];
private var xOffset : float = 0.0;

function Start() 
{
	theMesh = transform.GetComponent(MeshFilter).mesh;
    theUVs = new Vector2[theMesh.uv.Length];
    theUVs = theMesh.uv;
    
    SetUVs();
}

function Update() 
{
    // change the UV settings in the Inspector, then click the left mouse button to view
    if ( Input.GetMouseButtonUp(0) )
    {
    	SetUVs();
    }
}

// 2 --- 3
// |	 |
// |	 |
// 0 --- 1

function SetUVs() 
{
	// - set UV coordinates -
	
	// FRONT    2    3    0    1
    theUVs[2] = Vector2( uvsFront.x, uvsFront.y );
    theUVs[3] = Vector2( uvsFront.x + uvsFront.width, uvsFront.y );
    theUVs[0] = Vector2( uvsFront.x, uvsFront.y - uvsFront.height );
    theUVs[1] = Vector2( uvsFront.x + uvsFront.width, uvsFront.y - uvsFront.height );
	
	// BACK    6    7   10   11
    theUVs[6] = Vector2( uvsBack.x, uvsBack.y );
    theUVs[7] = Vector2( uvsBack.x + uvsBack.width, uvsBack.y );
    theUVs[10] = Vector2( uvsBack.x, uvsBack.y - uvsBack.height );
    theUVs[11] = Vector2( uvsBack.x + uvsBack.width, uvsBack.y - uvsBack.height );
	
	// LEFT   19   17   16   18
    theUVs[19] = Vector2( uvsLeft.x, uvsLeft.y );
    theUVs[17] = Vector2( uvsLeft.x + uvsLeft.width, uvsLeft.y );
    theUVs[16] = Vector2( uvsLeft.x, uvsLeft.y - uvsLeft.height );
    theUVs[18] = Vector2( uvsLeft.x + uvsLeft.width, uvsLeft.y - uvsLeft.height );
	
	// RIGHT   23   21   20   22
    theUVs[23] = Vector2( uvsRight.x, uvsRight.y );
    theUVs[21] = Vector2( uvsRight.x + uvsRight.width, uvsRight.y );
    theUVs[20] = Vector2( uvsRight.x, uvsRight.y - uvsRight.height );
    theUVs[22] = Vector2( uvsRight.x + uvsRight.width, uvsRight.y - uvsRight.height );
	
	// TOP    4    5    8    9
    theUVs[4] = Vector2( uvsTop.x, uvsTop.y );
    theUVs[5] = Vector2( uvsTop.x + uvsTop.width, uvsTop.y );
    theUVs[8] = Vector2( uvsTop.x, uvsTop.y - uvsTop.height );
    theUVs[9] = Vector2( uvsTop.x + uvsTop.width, uvsTop.y - uvsTop.height );
	
	// BOTTOM   15   13   12   14
    theUVs[15] = Vector2( uvsBottom.x, uvsBottom.y );
    theUVs[13] = Vector2( uvsBottom.x + uvsBottom.width, uvsBottom.y );
    theUVs[12] = Vector2( uvsBottom.x, uvsBottom.y - uvsBottom.height );
    theUVs[14] = Vector2( uvsBottom.x + uvsBottom.width, uvsBottom.y - uvsBottom.height );
     
    // - Assign the mesh its new UVs -
    theMesh.uv = theUVs;
}

alt text

You can modify the mesh, yes. But really, there are many voxel systems available, I would strongly suggest getting one of them, it will save you a LOT of work. Voxelform, for example, uses tri-planar world-space shaders so it gets grass on top and dirt underneath and seamless textures.

I would UV unwrap and texture in Blender.

In 2018, this can be done using Unity’s free ProBuilder add-on.

This example shows how to do that with a cube, and other shapes.