1
\$\begingroup\$

I'm writing a simple C# Script to change Materials color of a object.

public class Highlight : MonoBehaviour {

    public bool Mouse_Over = false;
    public Color Highlight_Color = Color.white;
    private Renderer rend;
    private Material[] mats;

    // Use this for initialization
    void Start () {
        rend = this.GetComponentInChildren< Renderer >();
        mats = rend.materials;
    }

    public void ToggleHighlight(bool t){
        if (mats.Length == 0) {
            return;
        }
        for(int i=0; i < mats.Length; i++){
            if (t) {
                rend.materials[i].color = Highlight_Color;
            } else {
                rend.materials[i].color = mats[i].color;
            }
            Debug.Log ("Material_" + i + ".Color = " + mats[i].color.ToHexStringRGBA());
        }
    }

    void OnMouseEnter(){
        if (Mouse_Over) {
            ToggleHighlight (true);
            Debug.Log ("MouseEnter");
        }
    }

    void OnMouseExit(){
        if (Mouse_Over) {
            ToggleHighlight (false);
            Debug.Log ("MouseExit");
        }
    }
}

As you can see, I store my original Materials inside the mats array, in the Start function. This is to revert the renderer Materials to the original Materials, but it isn't working. The color doesn't change to the original value.

I tried to check where the problem was, and in the Debug statement inside the for loop, the color is getting updated also inside mats Array. Why is this happening?

Seems like that mats is only a pointer to rend.materials, am I wrong?

\$\endgroup\$
  • \$\begingroup\$ try mats = (Material[])rend.materials.Clone(); into the start() and let me know \$\endgroup\$ – dnk drone.vs.drones Sep 7 '15 at 6:46
3
\$\begingroup\$

I am answering my own question because i have found the problem, it may be useful for someone else.

The problem is that mats is just a reference to rend.Materials, so changing values inside rend.Materials, also changes the values inside mats.

I had to create an Array of Colors to store the original Color of the materials, and then use that array to set the color when I want to revert back to the original color.

public class Highlight : MonoBehaviour {

public bool Mouse_Over = false;
public Color Highlight_Color = Color.white;

private Color[] oldColors;
private Renderer rend;

// Use this for initialization
void Start () {
    rend = this.GetComponentInChildren< Renderer >();
    CacheColors ();
}

private void CacheColors(){
    oldColors = new Color[rend.materials.Length];
    for (int i = 0; i < oldColors.Length; i++) {
        oldColors[i] = rend.materials[i].color;
    }
}

public void ToggleHighlight(bool t){
    if (rend.materials.Length == 0) {
        return;
    }
    for(int i=0; i < rend.materials.Length; i++){
        if (t) {
            rend.materials[i].color = Highlight_Color;
        } else {
            rend.materials[i].color = oldColors[i];
        }
    }
}

void OnMouseEnter(){
    if (Mouse_Over) {
        ToggleHighlight (true);
        Debug.Log ("MouseEnter");
    }
}

void OnMouseExit(){
    if (Mouse_Over) {
        ToggleHighlight (false);
        Debug.Log ("MouseExit");
    }
}
\$\endgroup\$
0
\$\begingroup\$

Just came across this problem myself, many of the answers were old so will update with my solution that works

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


public class Mat_library2 : MonoBehaviour
{
  [Header("Materials")]
  public Material[] myMaterials;
  private Material newMaterial;
  public GameObject elypseTile;
  public int RequiredColorIndex;

  public void Start()
  {
    findAllMaterials();
  }

  public void findAllMaterials()
  {
    //find all materials in resources folder Assets>Resources>Materials>
    myMaterials = Resources.LoadAll("Materials", 
    typeof(Material)).Cast<Material>().ToArray();
    Debug.Log("Materials " + 
    Resources.FindObjectsOfTypeAll(typeof(Material)).Length);

    foreach (Material mat in myMaterials)
    {
      Debug.Log("Material is: " + mat);
      Debug.Log("RequiredColorIndex: " + RequiredColorIndex);
    }

    //Apply material from indes to game object
    elypseTile.GetComponent<Renderer>().material.color = 
    myMaterials[RequiredColorIndex].color;
  }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.