I am trying to do a game like minecraft and im using chunks to generate the scene. The problem is that i can’t assign a specific texture or material to a specific cube in the chunk, since the chunk is a gameobject with generated cubes/meshes trhough script. How do I assign a texture to a specific mesh in that chunk, so that I can define the what type of block it is (grass, stone, wood, etc…)
I found the code here http://unitycoder.com/blog and did some changes.
Is there any tutorial on how to use voxels, chunks and marching cubes in the internet (specifically for Unity) so that I can understand better what I am dealing with? At this point the game has only one chunk, so I wanted to know how to put more than one chunk in the scenery to have this large terrain like in minecraft.
This is the code:
// ChunkRenderer testing in unity javascript - mgear - http://unitycoder.com/blog
// *ORIGINAL SOURCE: Rendering sorcery II by "paulp" > http://www.blocksters.com/node/57
#pragma strict
import System.Collections.Generic;
var heightMap : Texture2D;
private var s : int = 40; // size n*n*n
//private var lineRenderer : LineRenderer;
//public var explofx:Transform; // disabled for now
private var chunk : int[,,] = new int[s,s,s];
function Start ()
{
var pixels : Color[] = heightMap.GetPixels();
for (var x : int=0; x < heightMap.width; x++)
{
for (var z:int=0; z < heightMap.height; z++)
{
var indice : int = z + (x*heightMap.height);
var altura : int = pixels[indice].grayscale * 10;
for (var y : int = 0; y < altura + 5; y++)
{
chunk[x,y,z] = 1; //Random.Range (0,2); // 0 or 1
}
}
}
/*for (var x:int=0; x< s; x++)
{
for (var y : int=0; y < s; y++)
{
for (var z : int = 0; z < sbyte; z++
{
chunk[x,y,z] = 1; //Random.Range (0,2); // 0 or 1
}
}
}*/
gameObject.AddComponent ("MeshCollider");
ChunkRender(chunk);
}
function Update ()
{
var ray : Ray = Camera.main.ScreenPointToRay(Vector3(Screen.width/2, Screen.height/2, 0));
var hit : RaycastHit;
if (Physics.Raycast(ray, hit, 5))
{
if(Input.GetMouseButtonDown(0))
{
var hx : int = hit.point.x - hit.normal.x/10;
var hy : int = hit.point.y - hit.normal.y/10;
var hz : int = hit.point.z - hit.normal.z/10;
chunk[hx , hy, hz] = 0;
ChunkRender(chunk);
}
else if(Input.GetMouseButtonDown(1))
{
var hxx : int = hit.point.x + hit.normal.x/10;
var hyy : int = hit.point.y + hit.normal.y/10; //-0.2
var hzz : int = hit.point.z + hit.normal.z/10;
var Player : Transform;
Player = GameObject.Find("Player").transform;
if(Vector3.Distance(hit.point, Player.position) > 1.5)
{
chunk[hxx , hyy, hzz] = 1;
ChunkRender(chunk);
}
}
}
}
function ChunkRender(chunk : int[,,])
{
var vertices : List.<Vector3> = new List.<Vector3>();
var uvs : List.<Vector2> = new List.<Vector2>();
var triangles : List.<int> = new List.<int>();
var vertexIndex : int;
var top : int;
var north : int;
var east : int;
var south : int;
var west : int;
var bottom : int;
for (var x : int = 0; x < s; x++)
for (var y : int = 0; y < s; y++)
for (var z : int = 0; z < s; z++)
{
var block = chunk[x, y, z];
if (y==s-1)
{
top = 0;
}
else
{
top = chunk[x, y + 1, z];
}
if (y==0){bottom = 0;}else{bottom = chunk[x, y - 1, z];}
if (z==s-1){north = 0;}else{north = chunk[x, y, z+1];}
if (z==0){south = 0;}else{south = chunk[x, y, z-1];}
if (x==s-1){east = 0;}else{east = chunk[x+1, y, z];}
if (x==0){west = 0;}else{west = chunk[x-1, y, z];}
// we are checking the top face of the block, so see if the top is exposed
if (block == 1 && top == 0)
{
vertexIndex = vertices.Count;
vertices.Add(new Vector3(x, y + 1, z));
vertices.Add(new Vector3(x, y + 1, z+1));
vertices.Add(new Vector3(x+1, y + 1, z+1));
vertices.Add(new Vector3(x+1, y + 1, z));
// first triangle for the block top
triangles.Add(vertexIndex);
triangles.Add(vertexIndex+1);
triangles.Add(vertexIndex+2);
// second triangle for the block top
triangles.Add(vertexIndex+2);
triangles.Add(vertexIndex+3);
triangles.Add(vertexIndex);
// add UV
uvs.Add(Vector2 (0, 0));
uvs.Add(Vector2 (0, 1));
uvs.Add(Vector2 (1, 1));
uvs.Add(Vector2 (1, 0));
}
if (block == 1 && north == 0)
{
vertexIndex = vertices.Count;
vertices.Add(new Vector3(x, y, z+1));
vertices.Add(new Vector3(x+1, y, z+1));
vertices.Add(new Vector3(x+1, y + 1, z+1));
vertices.Add(new Vector3(x, y+1 , z+1));
// first triangle for the block top
triangles.Add(vertexIndex);
triangles.Add(vertexIndex+1);
triangles.Add(vertexIndex+2);
// second triangle for the block top
triangles.Add(vertexIndex+2);
triangles.Add(vertexIndex+3);
triangles.Add(vertexIndex);
// add UV
uvs.Add(Vector2 (0, 0));
uvs.Add(Vector2 (0, 1));
uvs.Add(Vector2 (1, 1));
uvs.Add(Vector2 (1, 0));
}
if (block == 1 && east == 0)
{
vertexIndex = vertices.Count;
vertices.Add(new Vector3(x+1, y, z));
vertices.Add(new Vector3(x+1, y + 1, z));
vertices.Add(new Vector3(x+1, y + 1, z+1));
vertices.Add(new Vector3(x+1, y , z+1));
// first triangle for the block top
triangles.Add(vertexIndex);
triangles.Add(vertexIndex+1);
triangles.Add(vertexIndex+2);
// second triangle for the block top
triangles.Add(vertexIndex+2);
triangles.Add(vertexIndex+3);
triangles.Add(vertexIndex);
// add UV
uvs.Add(Vector2 (0, 0));
uvs.Add(Vector2 (0, 1));
uvs.Add(Vector2 (1, 1));
uvs.Add(Vector2 (1, 0));
}
if (block == 1 && south == 0)
{
vertexIndex = vertices.Count;
vertices.Add(new Vector3(x, y, z));
vertices.Add(new Vector3(x, y + 1, z));
vertices.Add(new Vector3(x+1, y + 1, z));
vertices.Add(new Vector3(x+1, y , z));
// first triangle for the block top
triangles.Add(vertexIndex);
triangles.Add(vertexIndex+1);
triangles.Add(vertexIndex+2);
// second triangle for the block top
triangles.Add(vertexIndex+2);
triangles.Add(vertexIndex+3);
triangles.Add(vertexIndex);
// add UV
uvs.Add(Vector2 (0, 0));
uvs.Add(Vector2 (0, 1));
uvs.Add(Vector2 (1, 1));
uvs.Add(Vector2 (1, 0));
}
if (block == 1 && west == 0)
{
vertexIndex = vertices.Count;
vertices.Add(new Vector3(x, y, z+1));
vertices.Add(new Vector3(x, y + 1, z+1));
vertices.Add(new Vector3(x, y + 1, z));
vertices.Add(new Vector3(x, y , z));
// first triangle for the block top
triangles.Add(vertexIndex);
triangles.Add(vertexIndex+1);
triangles.Add(vertexIndex+2);
// second triangle for the block top
triangles.Add(vertexIndex+2);
triangles.Add(vertexIndex+3);
triangles.Add(vertexIndex);
// add UV
uvs.Add(Vector2 (0, 0));
uvs.Add(Vector2 (0, 1));
uvs.Add(Vector2 (1, 1));
uvs.Add(Vector2 (1, 0));
}
if (block == 1 && bottom == 0)
{
vertexIndex = vertices.Count;
vertices.Add(new Vector3(x, y, z));
vertices.Add(new Vector3(x+1, y, z));
vertices.Add(new Vector3(x+1, y, z+1));
vertices.Add(new Vector3(x, y , z+1));
// first triangle for the block top
triangles.Add(vertexIndex);
triangles.Add(vertexIndex+1);
triangles.Add(vertexIndex+2);
// second triangle for the block top
triangles.Add(vertexIndex+2);
triangles.Add(vertexIndex+3);
triangles.Add(vertexIndex);
// add UV
uvs.Add(Vector2 (0, 0));
uvs.Add(Vector2 (0, 1));
uvs.Add(Vector2 (1, 1));
uvs.Add(Vector2 (1, 0));
}
}
// Build the Mesh:
var mesh : Mesh = GetComponent(MeshFilter).mesh;
mesh.vertices = vertices.ToArray();
mesh.triangles = triangles.ToArray();
mesh.uv = uvs.ToArray();
mesh.RecalculateNormals();
// update mesh collider
GetComponent(MeshCollider).sharedMesh = null;
GetComponent(MeshCollider).sharedMesh = mesh;
}
The problem is that chunk[x, y, z] is not a gameObcjet, it is an int, therefore I can’t use .renderer.material = material and I don’t know how to change the material directly in the mesh.
Thanks in advance.