Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Targeting a material[] array element via GetComponent dot notation?

Discussion in 'Image Effects' started by surfcode, Dec 16, 2018.

  1. surfcode

    surfcode

    Joined:
    Oct 10, 2018
    Posts:
    15
    Hi Devs,

    After some research today, i found that when a material[] array variable is declared and instantiated, a copy of the material array is returned, not a reference.

    Does this impact the dot notation capacity to reference a specific material within an array of materials on an object?

    For example, this code scrolls the texture on an object with a single material.

    GetComponent<Renderer> ().material.mainTextureOffset = new Vector2 (offsetHorizontal, offsetVertical);

    ... I tried placin an array reference in that line of code "material[2].mainTextureOffset"

    ... the compiler complained with error CS0021: Cannot apply indexing with [] to an expression of type `UnityEngine.Material'

    I suppose the proper way to do it is declare a variable of type materials[]
    get a copy of the materials array held by the object
    make the Vector2 offset to the mainTextureOffset of the required element in the cached material[] array
    set the object's material[] array with the cached material[] array.

    although it would be nice to somehow access and adjust the mainTextureOffset of the object's material[] array's third element directly.
     
  2. samizzo

    samizzo

    Joined:
    Sep 7, 2011
    Posts:
    487
    renderer.material
    returns the first material on the renderer. If the renderer uses multiple materials and you want to access them then you should use
    renderer.materials
    instead (note plural "materials"). See here for more info.

    I'm not exactly sure what you mean by your first line. I think you're confusing a couple of things. The
    renderer.materials
    array will return a copy of the materials array on the renderer. Even though it returns a copy, you are still free to modify the material properties itself, so you can do this:

    renderer.materials[2].mainTextureOffset = new Vector2(offsetHorizontal, offsetVertical);


    However if you want to assign a brand new material to slot 2, because you get a copy of the array, you'll have to do this:

    Code (csharp):
    1. var materials = renderer.materials;
    2. materials[2] = someNewMaterial;
    3. renderer.materials = materials;
    Sam
     
    surfcode likes this.
  3. surfcode

    surfcode

    Joined:
    Oct 10, 2018
    Posts:
    15
    cheers for the valuable information.

    very satisfying to find a solution so very simple. change the "material" reference to plural "materials" and then include the array element reference in square brackets.

    also the quick code snippet on how to assign a new material to a material array element at runtime is super appreciated. this could make it easy to allow for player customisation of game elements, interactive runtime responsiveness of objects.