Change the cube's material color

I am working through Junior Programmer: Create with Code 1, Mod the Cube.

I have coded on input to change the material color of the Cube. I have debugged the code and the material color is changing but does not show up in the game window or in the Unity Preview window. I have also sent my code to my professor who said it worked for him. Perhaps the fault is because I used editor version 6000.0.23f1 to create the project? Does anyone have any ideas why the color is not rendering? The other changes to rotation and scaling work fine.

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

public class Cube : MonoBehaviour
{
    public MeshRenderer Renderer;
    private float rotateX;
    private float rotateZ;
    private float redcolor;
    private float bluecolor;
    private float greencolor;
    private float seethrew;
    private Material material;
    private Color newcolor;
    private float cubescale;
    private Color testcolor;
    
    void Start()
    {
        cubescale = 1.3f;
        transform.position = new Vector3(3, 4, 1);
        transform.localScale = Vector3.one * cubescale;


        /*        redcolor = 0.5f;
                bluecolor = 0.3f;
                greencolor = 1.0f;
                seethrew = 0.4f;*/

        redcolor = 0.0f;
        bluecolor = 0.0f;
        greencolor = 0.0f;
        seethrew = 1.0f;

        material = Renderer.material;
        
        newcolor = new Color(redcolor, greencolor, bluecolor, seethrew);
        material.color = newcolor;
        rotateX = 10.0f;
        rotateZ = 0.0f;
    }
    
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            rotateX += 5f;
        }
        else if (Input.GetKeyDown(KeyCode.DownArrow))
        {
            rotateX -= 5f;
        }
        else if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            rotateZ += 5f;
        }
        else if (Input.GetKeyDown(KeyCode.LeftArrow))
        {
            rotateZ -= 5f;
        }
        else if (Input.GetKeyDown(KeyCode.Alpha1) && redcolor < 1.0f)
        {
            redcolor = Mathf.Min(1.0f, (redcolor + 0.1f));
            Debug.Log("red=" + redcolor.ToString("#.##"));
        }
        else if (Input.GetKeyDown(KeyCode.Alpha2) && redcolor > 0.0f)
        {
            redcolor = Mathf.Max(0.0f, (redcolor - 0.1f));
            Debug.Log("red=" + redcolor.ToString("#.##"));
        }
        else if (Input.GetKeyDown(KeyCode.Alpha3) && bluecolor < 1.0f)
        {
            bluecolor = Mathf.Min(1.0f, (bluecolor + 0.1f));
            Debug.Log("blue=" + bluecolor.ToString("#.##"));
        }
        else if (Input.GetKeyDown(KeyCode.Alpha4) && bluecolor > 0.0f)
        {
            bluecolor = Mathf.Max(0.0f, (bluecolor - 0.1f));
            Debug.Log("blue=" + bluecolor.ToString("#.##"));
        }
        else if (Input.GetKeyDown(KeyCode.Z) && cubescale < 3.0f)
        {
            cubescale = Mathf.Min(3.0f, (cubescale + 0.2f));
        }
        else if (Input.GetKeyDown(KeyCode.X) && cubescale > 0.2f)
        {
            cubescale = Mathf.Max(0.2f, (cubescale - 0.1f));
        }
        //newcolor = new Color(redcolor, greencolor, bluecolor, seethrew);
        newcolor = new Color(0.0f, 0.0f, 0.0f, 0.0f);
        //material = Renderer.material;
        //material.SetColor("_Color", newcolor);
        material.color = newcolor;
        testcolor = material.color;
        string rd = testcolor.r.ToString("#.##");
        string bl = testcolor.b.ToString("#.##");
        string gr = testcolor.g.ToString("#.##");
        string al = testcolor.a.ToString("#.##");
        Debug.Log(rd + " " + bl + " " + gr);
        transform.Rotate(rotateX * Time.deltaTime, 0.0f, rotateZ * Time.deltaTime);
        transform.localScale = Vector3.one * cubescale;
    }
}

I’m guessing you’re getting errors that you haven’t noticed in the console window.

Make sure your log console selector buttons are enabled. See this graphic:

If that’s not it, keep debugging. We know all this stuff works. Delete the cube, put it back in. Make a new scene, work there. etc

By debugging you can find out exactly what your program is doing so you can fix it.

Use the above techniques to get the information you need in order to reason about what the problem is.

You can also use Debug.Log(...); statements to find out if any of your code is even running. Don’t assume it is.

Once you understand what the problem is, you may begin to reason about a solution to the problem.

I finally was able to solve this problem. Since the tutorial said to use the latest stable version, I created the project with 6000.0.23f1 which seemed to be incompatible.

When I recreated the project with 2022.3.9f1 the code worked perfectly.

So, I would stay away from 6000.0.23f1 for now and don’t listen to the tutorials when they say to use the latest stable version.

You didn’t ask for my opinion but you mention that you are learning and you specifically mention a “professor”. So realize that you haven’t “solved” the problem but perhaps absolved yourself of it.

That one cannot change a material color in Unity 6 would be hard to believe. Your professor could have used this as an opportunity to instruct everyone in the class how to solve problems as a software developer. Did he try it using Unity 6? Did anyone else or would someone else be willing to try?

Listening to tutorials is (believe me) at least as good as listening to random beginners. Move up from beginner by learning to determine the actual cause and providing solutions to problems :slight_smile:

2 Likes

tleylan, I have been programming for over 50 years. I have used Unity before, but it was several years ago. I am currently taking a course where we follow certain Unity tutorials. I debugged the code and the code was working fine. I have run into this problem before, where a tutorial or an older project will not work in a newer version of Unity. I just did not think of trying this earlier. So, the solution is that the old project in the tutorial will not work with Unity 6. It works now. Maybe you could go back and tell the Apollo 13 astronauts they did not really solve their problem but just absolved themselves from not completing the mission?

Maybe you could go back and tell the Apollo 13 astronauts they did not really solve their problem but just absolved themselves from not completing the mission?

Excellent rebuttal BTW :slight_smile: I’m busy writing an article about what Francis Gary Powers could have done to avoid a Soviet missile.

I was mostly replying to others who might stumble upon the thread. “stay away from 6000.0.23f1 for now” because you encountered an error is odd advice. And again you mentioned “a professor” so could he discern the problem? It is 105 lines of code max. You don’t believe that none of it will work in 6.0 right?

Did you see/read Kurt’s reply? Were there any warnings or error messages?

So at some risk of upsetting you… encountering an issue with an older project in a newer version isn’t unheard of but didn’t mention some long ago deprecated library. You mentioned changing the material color.

It was a learning opportunity that in my opinion, you and your professor and others taking the course squandered. You could have posted the error message… and you still can. That way we would all understand what the problem was and realistically adjust it so it was compatible with 6.0.

So my guess is that you received IDE0051 warnings re: unused private members. These can easily be suppressed.

Having done that, commenting out a lot of the noise and leaving the following in your Update method and you can see that the material will switch colors when you press the 0 key.

{
	Debug.Log("Test.Update GetKeyDown Alpha0");
	Renderer.material.color = Renderer.material.color == Color.red ? Color.blue : Color.red;
}
2 Likes

Okay, Ignoring the others, here is a solution for you (your rotation works, so just copy paste the code for your rotation into what I have written) I re-wrote your code, and it will work for Unity6 as well as 2022. The mechanics are identical: Not using the new input system as you have used GetKey I used same (changed the key codes)

Create a new material:
Add it to your cube:
Drag the Material to the public variable on the script (we called it cube)
Run the “game” and press the buttons RGB to increase the RGB respectively, number pad decreases (current increments are also a variable if you want to increase its speed)

I tried to make it as efficient as possible without using the new input system. Comments included in code; any further questions feel free to ask, I am available all the time

using UnityEngine;

public class Cube : MonoBehaviour
{
    //Components - Best to keep these together
    private MeshRenderer renderer;
    public Material material;
    private Color materialColour;

    public float colourChangeSpeed;


    //Variables

    private float rotationSpeed;
    private float red, green, blue, alpha;

    private float cubeScale;

    //AUTOMATICALLY GRABS THE MESH RENDERER COMPONENT
    void Awake(){
        renderer = GetComponent<MeshRenderer>();
    }
    // ON START THIS WILL SET THE SCALE OF THE CUBE, THE POSITION, AND RESET MATERIAL COLOUR TO BLACK
    void Start()
    {
        cubeScale = 1.3f;
        transform.position = new Vector3(3, 4, 1);
        transform.localScale = Vector3.one * cubeScale;

        materialColour = new Color(0f,0f,0f,1);
    }
    
    //VOID UPDATE WILL CHANGE THE COLOURS RESPECTIVELY BASED ON EACH METHOD, THIS IS DONE ON A FRAME BY FRAME BASIS, SETTING THE MATERIAL INSTANTLY TO THE COLOUR REQUIRED
    void Update()
    {
        ChangeColourRedInput();
        ChangeColourGreenInput();
        ChangeColourBlueInput();
        ChangeColourAlphaInput();
        materialColour = ChangeColour(red, green, blue, alpha);
        material.color = materialColour;
    }

    /*THESE FOLLOWING METHODS CONTROL YOUR INPUT, CHANGING EACH COLOUR TO THE COLOUR YOU ARE DESIRING AT FRAME BASED INTERVALS, 
    THE VARIABLE HERE KNOWN AS COLOURCHANGESPEED YOU CAN ADAPT IN THE INSPECTOR TO MAKE IT SLOWER OR FASTER
    FEEL FREE TO CHANGE THE KEYCODES TO ONES YOU LIKE*/
    private void ChangeColourRedInput(){
        if(Input.GetKey(KeyCode.R)){
            red += colourChangeSpeed;
        };
        if(Input.GetKey(KeyCode.Alpha1)){
            red -= colourChangeSpeed;
        };
    }
        private void ChangeColourGreenInput(){
        if(Input.GetKey(KeyCode.G)){
            green += colourChangeSpeed;
        }; 
        if(Input.GetKey(KeyCode.Alpha2)){
            green -= colourChangeSpeed;
        }
    }
        private void ChangeColourBlueInput(){
        if(Input.GetKey(KeyCode.B)){
            blue += colourChangeSpeed;
        }
        if(Input.GetKey(KeyCode.Alpha3)){
            blue -= colourChangeSpeed;
        }
    }
    private void ChangeColourAlphaInput(){
        if(Input.GetKey(KeyCode.A)){
            alpha += colourChangeSpeed;
        }
        if(Input.GetKey(KeyCode.Alpha4)){
            alpha -= colourChangeSpeed;
        }
    }
    //THIS METHOD TAKES IN VARIABLES HERE THEY ARE RED, GREEN, BLUE, AND ALPHA EACH AS FLOATS AND OUTPUTS A COLOR BASED ON THEM.
    //IT CREATES YOUR MATERIALS COLOUR BASED ON THESE FLOATS AND RETURNS THE VALUE AS MATERIAL COLOUR, THIS IS THEN THE COLOUR THAT IS REFERENCED
    // IN THE EARLIER PART WHERE IT DICTATES MATERIAL.COLOR = MATERIALCOLOUR
    private Color ChangeColour(float red, float green, float blue, float alpha){
        materialColour = new Color(red,green,blue,alpha);
        return materialColour;
    }
}

We’re beating a dead horse here since the OP “solved” his own post but… :slight_smile: The issue became one about Unity 6 (he is taking a course and “the professor” said the code he posted works for him).

From an efficiency standpoint (again I doubt anyone cares) you resetting the material color even when nothing has changed. There is seemingly no purpose in doing that. You are also checking for the blue/green/ etc. inputs even if the red has changed.

As I interpret things if the Input.GetKey returns true then other checks in the same Update loop will not return true. I wouldn’t mind being corrected if this is incorrect.

Not ragging on your code but I for one appreciate good examples over “it works” examples. People are going to find these messages and might consider the code a good template to follow. I know that I try to choose examples that I trust and understand over the “at least it works now” style.