Home > Net >  How can I change one material texture in an array?
How can I change one material texture in an array?

Time:01-13

How can I change one material in an array?

I've imported a Daz figure into unity, all of the materials are stored in an array for the figure.

Here is a screenshot of the array

I'm trying to change the texture of the Irises with the click of a button.

The code below does change the material but only on the first material in the array. I've attempted to alter the code to change the Irises, but I have been unable to.

{
//Component
private Renderer _rendereyes;

//Game Object
public GameObject eyes;

//etc
public Object[] texEyes;
public int texID;

// Start is called before the first frame update
void Start()
{
    //Get Component
    _rendereyes = eyes.GetComponent<Renderer>();

    //Change eye tex
    string texPath = "Textures";
    texEyes = Resources.LoadAll(texPath, typeof(Texture2D));
}

public void SetEyeTexture()
{
    if (texID < texEyes.Length - 1)
    {
        texID  ;
    }
    else
    {
        texID = 0;
    }
    _rendereyes.material.SetTexture("_DiffuseMap",(Texture2D)texEyes[texID]);
}

Here is the 2nd iteration of the code which is my attempt to alter the Irises texture.

{
//Component
private Renderer[] _rendereyes;

//Game Object
public GameObject eyes;

//etc
public Object[] texEyes;
public int texID;

// Start is called before the first frame update
void Start()
{
    //Get Component
    _rendereyes = eyes.GetComponent<Renderer[]>();

    //Change eye tex
    string texPath = "Textures";
    texEyes = Resources.LoadAll(texPath, typeof(Texture2D));
}

public void SetEyeTexture()
{
    if (texID < texEyes.Length - 1)
    {
        texID  ;
    }
    else
    {
        texID = 0;
    }
    _rendereyes[15].material.SetTexture("_DiffuseMap",(Texture2D)texEyes[texID]);
}

What is the best way to change the Irises texture?

CodePudding user response:

First of all in general avoid using Resources at all. (See Best practices -> Resources)

Don't use it!


Then if you use it and in general I would be more specific and do

public Texture2D[] texEyes;

and then

texEyes = Resources.LoadAll<Texture2D>(texPath);

or rather simply drag and drop them into the slots via the Inspector


And finally

GetComponent<Renderer[]>

makes no sense. You always want to either get a single component or use GetComponents.

However, it sounds like you actually have only one single object with one single Renderer and want to stick to

_rendereyes = eyes.GetComponent<Renderer>();

or directly make it

[SerializeField] private Renderer _rendereyes;

and drag the object into the slot in the Inspector.

And then rather access the according index from Renderer.materials.

And then you have a little logical mistake in your SetEyeTexture method.

You do

if (texID < texEyes.Length - 1)
{
    texID  ;
}

which might result in texID = texEyes.Length which will be out o bounds since in c# all indices go from 0 to array.Length - 1.

Your code should rather look like

public void SetEyeTexture()
{
    // Simple modulo trick to get a wrap around index
    texID = (  texID) % texEyes.Length;
    
    // Note that according to your screenshot the Material "Irises" is at index 14 not 15!
    _rendereyes.materials[14].SetTexture("_DiffuseMap", texEyes[texID]);
}
  •  Tags:  
  • Related