1

I'm trying to automatically generate cubes in Unity with c#.

I have finally succeed in creating a large number of cubes (300x300), positioning them and naming them, but I have a problem when it comes to colouring them (last part of the code).

I want to colour them by using three variables, one for each RGB value. The variables I define in my code are rnewcolor, gnewcolor and bnewcolor, and they are attributed to each component by using (last part of the code):

go.GetComponent<Renderer>().material.color = new Color(rnewcolor/255f, gnewcolor/255f, bnewcolor/255f)

When I attribute random values to these three variables for example:

int rnewcolor = UnityEngine.Random.Range(0, 255))

then the code works, and the cubes are coloured with random colours as expected (image here https://ibb.co/pXDmhfB )

But when I try to read the RGB values from a file, storing them on the arrangements Rcolor[i,j,k], Gcolor[i,j,k] and Bcolor[i,j,k], to pass them later to the variables rnewcolor, gnewcolor, bnewcolor, then the colour attribution does not work and I get all the cubes with a kind of grey colour which is not the colour read from the file (image https://ibb.co/S3JRnBr )

Some more images:

Inspector on the first cube (used for the instancing): https://ibb.co/VNsCy5b (it has the code "ProgramCubeNew.cs" added as a component) Inspector on the first cube (also in prefab): https://ibb.co/tKrVD2V

Some comments:

By printing some debugging, I know that the variables rnewcolor, gnewcolor, bnewcolor, Rcolor[,,], Gcolor[,,] and Bcolor[,,] are all of the same type, which is Int32.

Also, I know that the values read from the file and stored in the Rcolor[,,], Gcolor[,,] and Bcolor[,,] variables are right.

I know that here:

go.GetComponent<Renderer>().material.color = new Color(rnewcolor/255f, gnewcolor/255f, bnewcolor/255f)

the fucntion Color(,,) works with float numbers ranging from 0 to 1. It works perfectly when random numbers are assigned to the variables gnewcolor, bnewcolor and gnewcolor but it does not work when values are read from the file.

As the colouring process work when using random numbers, i assume that the articulation between objects in the Unity interface must be right (?)

Does anybody knows why I can't attribute the colours when values are read from file?

Thank you!

using System.Collections;
using UnityEngine;
using System;
using System.IO;
using System.Text;


public class ProgramCubeNew : MonoBehaviour
{
    public Int32[,,] Rcolor = new Int32[400, 400, 400];
    public Int32[,,] Gcolor = new Int32[400, 400, 400];
    public Int32[,,] Bcolor = new Int32[400, 400, 400];

    // Start is called before the first frame update
    void Start()
    {
        GameObject prefab = Resources.Load("Cube") as GameObject;
        string path = @"H:\Unity\Learn_Everything_Fast\Cube_script_generation\export_bones_scene\rgb_bones_scene.txt";

        using (var reader = new StreamReader(path))
        {
            while (!reader.EndOfStream)
            {
                var line = reader.ReadLine();
                var values = line.Split(' ');

                int i = Convert.ToInt32(values[0]);
                int j = Convert.ToInt32(values[1]);
                int k = Convert.ToInt32(values[2]);
                Rcolor[i, j, k] =  Convert.ToInt32(values[3]);
                Gcolor[i, j, k] = Convert.ToInt32(values[4]);
                Bcolor[i, j, k] = Convert.ToInt32(values[5]);
            }    
        }

        // I'm using theese three lines in order to know if the file is being read ok, it seems so.
        Debug.Log(Rcolor[50, 50, 50]);
        Debug.Log(Gcolor[50, 50, 50]);
        Debug.Log(Bcolor[50, 50, 50]);

        for (int i = 0; i <= 300; i++)
        {
            for (int j = 0; j <= 300; j++)
            {
                int k = 50;
                string name = string.Format("cube_{0}_{1}_{2}\n", i, j, k);
                string namemat = string.Format("mat_{0}_{1}_{2}\n", i, j, k);
                GameObject go = Instantiate(prefab) as GameObject;
                go.transform.position = new Vector3(i, j + 20, k);
                go.transform.name = name;

                // int rnewcolor = UnityEngine.Random.Range(0, 255); // it works ok
                // int gnewcolor = UnityEngine.Random.Range(0, 255); // it works ok
                // int bnewcolor = UnityEngine.Random.Range(0, 255); // it works ok
                int rnewcolor = Rcolor[i, j, k];               
                int gnewcolor = Gcolor[i, j, k];               
                int bnewcolor = Bcolor[i, j, k];                

                // I'm using this to print some debug
                if (i == 50 && j == 50)
                {
                    Debug.Log(Rcolor[i, j, k]);
                    Debug.Log(Gcolor[i, j, k]);
                    Debug.Log(Bcolor[i, j, k]);
                    Debug.Log(Rcolor[i, j, k].GetType());
                    Debug.Log(Gcolor[i, j, k].GetType());
                    Debug.Log(Bcolor[i, j, k].GetType());
                    Debug.Log(bnewcolor.GetType());
                }

                go.GetComponent<Renderer>().material.color = new Color(rnewcolor/255f,gnewcolor/255f,bnewcolor/255f);
            }
        }
    }

    // Update is called once per frame
    void Update()
    {

    }
}
derHugo
  • 83,094
  • 9
  • 75
  • 115
P.cordo
  • 31
  • 5
  • 1
    Maybe it would help to know how your file looks like .. it's a bit hard for me to understand why you are using arrays there and why `k` is always `50` anyway.. – derHugo Jul 20 '19 at 10:07
  • 1
    Btw `int` is just a synonym for `System.Int32` you can simply use `int` ;) – derHugo Jul 20 '19 at 10:20
  • Thank you derHugo for your comments. K is 50 because I'm only generating 1 slide of cubes (300x300x1), however, the file contains the entire set of data (300x300x300). I'm trying to send you the file, but I can't paste a wetransfer link in this commet :-( – P.cordo Jul 20 '19 at 11:25
  • You can [edit](https://stackoverflow.com/posts/57122927/edit) your question and add it there. Maybe don't use WeTransfer but add relevant content directly to your question (doesn't have to be the complete data but maybe an excerpt like for reproducing the issue for 10x10x1 cubes) – derHugo Jul 20 '19 at 11:36
  • Thank you derHugo. https://fromsmash.com/fileforunity here is a smash link, I hope It will make it. The file is about 0.5gb, still consistent with the images and code I send (300x300x1) // That would be great if you can find out what is going on! Thank you again. – P.cordo Jul 20 '19 at 12:49
  • 1
    Taking a peek at the file....the vast, ***vast*** majority of the colors in there are `200 208 197` or similarly close values (like `201 209 198` or `202 214 202`). Voting to close with "garbage data in, garbage data out." There are some blacks (`2 1 7`) but a cursory glance has all three values (the RGB) as very similar (i.e. a shade of gray). – Draco18s no longer trusts SE Jul 20 '19 at 15:53
  • Thank you Draco18s and Thank you derHugo. After your comment I have checked and yes I had a big bug when generating the file in another script. I'm really sorry!!! Thank you all, I hope my code (that is in fact working well, though maybe not optimised) may help others. – P.cordo Jul 20 '19 at 16:11
  • As a side node, if you generate 300x300 cubes, don't use the Renderer.material field, as this will duplicate the material -> more draw calls. Use a shader that allows per instance colors and modify the color that way. Check [here](https://answers.unity.com/questions/411601/change-the-color-of-a-material-for-only-one-object.html) for more information. – Chillersanim Jul 21 '19 at 19:07
  • Chillersanim: I'll definitively take a look as the method I'm using is really slow. Thank you very much! – P.cordo Jul 22 '19 at 14:28

0 Answers0