• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
Question by Nelia-Xurina · Feb 01, 2013 at 02:18 AM · meshrenderingcolor

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;
 }
Comment
Bunny83

People who like this

1 Show 4
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image youngapprentice · Feb 01, 2013 at 02:31 AM 0
Share

You should build the cube in an external editor and assign an independent material per face. Then, when you import it into unity, you can index the material slots and change the color at will. Good luck :)

avatar image Eric5h5 · Feb 01, 2013 at 02:56 AM 1
Share

It would be better to use Color32 instead of Color; then you can use 0 to 255, and it's 4X less expensive for RAM usage and is faster. Naturally you'd use Mesh.colors32.

avatar image robertbu · Feb 01, 2013 at 07:36 AM 0
Share

A couple more ideas. If you build each face with its own vertices, the you can change the uv coordinates for each face depending on what color you want it to be. I've not played with vertex color, but I believe you could reset the vertex colors for a face as well. RaycastHit gives back a triangle index, so you can build a map between each triangle and its vertices so when you get a click on a triangle you know which uv coordinates to change or which vertices to assign new colors to.

avatar image Nelia-Xurina · Feb 01, 2013 at 02:31 PM 0
Share

I don't understand ur ideas... A new cube...Then i have the Problem that i have 16*16 cubes in 256 Chunks...that are 16*16*256 cubes. That give a huge lag is think. Colors32 doesnt work too. And how can i build each face with own vertices? And how to detect it

1 Reply

· Add your reply
  • Sort: 
avatar image
Best Answer

Answer by robertbu · Feb 02, 2013 at 05:43 AM

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[i] = 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[i] = 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<VertixColorPlay>();
                 if (vcp != null)
                     vcp.ChangeColor(hit.triangleIndex);
             }
         }
     }
 }
Comment
monogon
7a
Bunny83

People who like this

3 Show 11 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Nelia-Xurina · Feb 02, 2013 at 03:45 PM 0
Share

This is beautiful! But it doesn't work 100%. But i can Fix that. Thank u

avatar image robertbu · Feb 02, 2013 at 04:07 PM 0
Share

What problem did you find that it doesn't work 100%?

avatar image Nelia-Xurina · Feb 02, 2013 at 05:06 PM 0
Share

Okay, i can't fix it. I try to save the color of each side...But i don't get it. I want that the player can spawn and delete new Cubes. But how to save the color?

And how can i delete a Cube? It's so difficult...

My code: http://pastebin.com/0KaPTq36

avatar image robertbu · Feb 02, 2013 at 05:48 PM 1
Share

You are trying to be super efficient by only generating the sides you need. And this is going to cause you a bunch of programming pain to make it work. It can be done, but you will need to track sides and have use counts for sides, and a bunch of other stuff. Before you go to all that work, I'd make sure it is necessary.

Take the code that makes a cube that I posted above and make it into a prefab. Spawn 256 of them in some pattern representative of your game. Put it on the target device and see how it performs. All of the cubes should be batched, so there will only be one draw call. Plus given what you are building, a high percentage of the faces will be culled. I suspect that having 256 game object will work just fine on most mobile platforms.

If you have a single game object per cube, then processes like deleting and saving colors becomes easy to program.

avatar image Jelverine · Feb 12, 2014 at 10:19 AM 1
Share

Thanks for the above Robert, from a random Googler :)

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

14 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Camera not showing a mesh 0 Answers

How do I change the color of imported blender models 2 Answers

Does anybody know why this happens to the mesh's color? 1 Answer

How to make colored voxels?!? 1 Answer

What is the most efficient way to sample the color at a point on a mesh? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges