Create a mesh and color cubes

Hi,

i try to make a chunksystem for my game, to place, remove and color cubes.

But my problem is that i can’t color each side from a normal cube. I tried to make a mesh but i don’t find out how to color spezefic areas.

Sorry for my bad english, i’m german^^

So i try that the player can place a cube on a 16*16 chunk. When the cube is placed the player should be able to color each side. like the front red, the back green etc.

I tried to make a cube out of planes, but that a way to much objects and couses into lags.

Maybe u have an idea? Please i try it now for over 3 days^^

My code for now: (I Already have a cube place system etc. This is a new try)

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class World_Chunks : MonoBehaviour 
{
	public List<MP_Chunk> thisChunk = new List<MP_Chunk>();
	
	void Start()
	{
		
		
		
	}
	
	IEnumerator FloorkRender()
	{
		GameObject.DestroyImmediate(GetComponent<MeshCollider>());
		GameObject.DestroyImmediate(GetComponent<MeshFilter>());
		
		gameObject.AddComponent<MeshCollider>();
		gameObject.AddComponent<MeshFilter>();
		
		Mesh          mesh      = GetComponent<MeshFilter>().mesh;
		List<Vector3> vertices  = new List<Vector3>();
		List<Vector2> uvs       = new List<Vector2>();
		List<int>     triangles = new List<int>();
		List<Color>   colors   = new List<Color>();
		int           vertexIndex;
		vertexIndex = 0;
		mesh.Clear();
		
        for (int x = 0; x < World_ChunkLoader.instance.chunk_X_Width; x++)
		{
			for (int z = 0; z < World_ChunkLoader.instance.chunk_Z_Width; z++)
			{
				MP_Chunk tempchunk = new MP_Chunk();
				tempchunk.x        = x;
				tempchunk.y        = 0;
				tempchunk.z        = z;
				tempchunk.isLoaded = false;
				
				tempchunk.Render_Top    = true;
				tempchunk.Render_Bottom = false;
				tempchunk.Render_Left   = false;
				tempchunk.Render_Right  = false;
				tempchunk.Render_Back   = false;
				tempchunk.Render_Front  = false;
				
				
				thisChunk.Add (tempchunk);
				
				vertices.Add(new Vector3(x, 0 + 1, z));
				vertices.Add(new Vector3(x, 0 + 1, z+1));
				vertices.Add(new Vector3(x+1, 0 + 1, z+1));
				vertices.Add(new Vector3(x+1, 0 + 1, z));
				
				colors.Add (new Color(Random.Range (1,254), Random.Range (1,254), Random.Range (1,254)));
				colors.Add (new Color(Random.Range (1,254), Random.Range (1,254), Random.Range (1,254)));
				colors.Add (new Color(Random.Range (1,254), Random.Range (1,254), Random.Range (1,254)));
				colors.Add (new Color(Random.Range (1,254), Random.Range (1,254), Random.Range (1,254)));
				
				// 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(new Vector2(0, 0));
				uvs.Add(new Vector2(0, 1));
				uvs.Add(new Vector2(1, 1));
				uvs.Add(new Vector2(1, 0));
				vertexIndex += 4;
			}
		}
		
		// Build the Mesh:
		mesh.vertices = vertices.ToArray();
		mesh.triangles = triangles.ToArray();
		mesh.colors = colors.ToArray ();
		mesh.uv = uvs.ToArray();
		mesh.Optimize();
		mesh.RecalculateNormals();
		
		// update mesh collider
		GetComponent<MeshCollider>().sharedMesh = null;
		GetComponent<MeshCollider>().sharedMesh = mesh;
		yield return null;
    }
	
	void Update()
	{
		if(Input.GetMouseButtonDown (0))
			StartCoroutine(FloorkRender());
	}
}

public class MP_Chunk
{
	public int       x;
	public int       y;
	public int       z;
	public bool      isLoaded;
	public Transform ChunkObj;
	
	public bool      Render_Top;
	public bool      Render_Bottom;
	public bool      Render_Left;
	public bool      Render_Right;
	public bool      Render_Front;
	public bool      Render_Back;
}

The basic idea is to build each face with its own vertices. This increases the vertex count, but not the triangle count. Each face has it own set of vertices, then you can color the face by either by using a Vertex Colored shader and changing the vertex colors, or by using a texture atlas and changing the UV coordinates to a different point in the atlas.

There are three scripts below. The first is a very simple vertex shader, the second creates a cube mesh and processes the hit on a triangle in that mesh. The third processes the mouse click and passed the triangle index. If you setup all three correctly, you will be able to click on a cube face to change it to random color.

This is the simplest vertex color shader I know. If you Google “Unity3d Vertex Colored Shader” you will find others with more features.

Shader "Custom/Vertex Colored" {
Properties {
}
    SubShader {
            Pass {
                    ColorMaterial AmbientAndDiffuse
            }
    } 
}

The following code builds a cube. The mesh does not have to be a cube to work. The more important ingredient is that each face you want to color has its own set of vertices. Attach the script to an empty game object that has these three components: a) MeshCollider b) Renderer, c) MeshFilter.

public class VertixColorPlay : MonoBehaviour {
	private Mesh mesh;
	
	void Start () {
		MeshFilter mf = GetComponent<MeshFilter>();
		if (mf == null) return;
		mesh = MakeCube(2.0f);
		mf.mesh = mesh;
		MeshCollider mc = GetComponent<MeshCollider>();
		if (mc != null)
			mc.sharedMesh = mesh;
	}
	
	public void ChangeColor(int iTriangle)
	{
		Color colorT = new Color(Random.Range (0.0f, 1.0f), Random.Range (0.0f, 1.0f), Random.Range (0.0f, 1.0f), 1.0f);
		Color[] colors = mesh.colors;
		int iStart = mesh.triangles[iTriangle*3];
		for (int i = iStart; i < iStart+4; i++)
			colors *= colorT;*
  •  mesh.colors = colors;*
    
  • }*

  • Mesh MakeCube(float fSize)*

  • {*

  •  float fHS = fSize / 2.0f;*
    
  •  Mesh mesh = new Mesh();	*
    
  •  mesh.vertices = new Vector3[] {*
    
  •  	new Vector3(-fHS,  fHS, -fHS), new Vector3( fHS,  fHS, -fHS), new Vector3( fHS, -fHS, -fHS), new Vector3(-fHS, -fHS, -fHS),  // Front*
    
  •  	new Vector3(-fHS,  fHS,  fHS), new Vector3( fHS,  fHS,  fHS), new Vector3( fHS,  fHS, -fHS), new Vector3(-fHS,  fHS, -fHS),  // Top*
    
  •  	new Vector3(-fHS, -fHS,  fHS), new Vector3( fHS, -fHS,  fHS), new Vector3( fHS,  fHS,  fHS), new Vector3(-fHS,  fHS,  fHS),  // Back*
    
  •  	new Vector3(-fHS, -fHS, -fHS), new Vector3( fHS, -fHS, -fHS), new Vector3( fHS, -fHS,  fHS), new Vector3(-fHS, -fHS,  fHS),  // Bottom*
    
  •  	new Vector3(-fHS,  fHS,  fHS), new Vector3(-fHS,  fHS, -fHS), new Vector3(-fHS, -fHS, -fHS), new Vector3(-fHS, -fHS,  fHS),  // Left*
    
  •  	new Vector3( fHS,  fHS, -fHS), new Vector3( fHS,  fHS,  fHS), new Vector3( fHS, -fHS,  fHS), new Vector3( fHS, -fHS, -fHS)}; // right*
    

_ int triangles = new int[mesh.vertices.Length / 4 * 2 * 3];_

  •  int iPos = 0;*
    
  •  for (int i = 0; i < mesh.vertices.Length; i = i + 4) {*
    
  •  	triangles[iPos++] = i;*
    
  •  	triangles[iPos++] = i+1;*
    
  •  	triangles[iPos++] = i+2;*
    
  •  	triangles[iPos++] = i;*
    
  •  	triangles[iPos++] = i+2;*
    
  •  	triangles[iPos++] = i+3;*
    
  •  }*
    
  •  mesh.triangles = triangles;*
    
  •  Color colorT = Color.red;*
    
  •  Color[] colors = new Color[mesh.vertices.Length];*
    
  •  for (int i = 0; i < colors.Length; i++) {*
    
  •  	if ((i % 4) == 0)*
    
  •  		colorT = new Color(Random.Range (0.0f, 1.0f), Random.Range (0.0f, 1.0f), Random.Range (0.0f, 1.0f), 1.0f);*
    

_ colors = colorT;_
* }*

* mesh.colors = colors;*
* mesh.RecalculateNormals();*
* return mesh;*
* }*
}
Note the statement “int iStart = mesh.triangles[iTriangle*3];” works to find the beginning index of the four vertices (or four colors matched to the indices) because the two trangles both use the first of the four points as the start of each rectangle.
And here is a script that does the Raycasting and triggers the change in color. Attach it to an empty game object.
public class RaycastToColorTriangle : MonoBehaviour {

* void Update () {*
* if (Input.GetMouseButtonDown (0)) {*
* Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);*
* RaycastHit hit;*
* if (Physics.Raycast(ray, out hit))*
* {*
* VertixColorPlay vcp = hit.collider.gameObject.GetComponent();*
* if (vcp != null)*
* vcp.ChangeColor(hit.triangleIndex);*
* }*
* }*
* }*
}

Thanks to all. It work now.

I just needed a shader and a new Material so that i can change each vertex.

And the Color must be a float between 1 and 0.