Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Change material runtime

Discussion in 'Scripting' started by Xhitman, Aug 17, 2019.

  1. Xhitman

    Xhitman

    Joined:
    Oct 30, 2015
    Posts:
    452
    I dont know why
    currentSelectedSubMaterial = metal.GetComponent<MeshRenderer>().material;
    not work.

    I think currentSelectedSubMaterial should refer to the object material in scene.



    Code (CSharp):
    1. //-------------UI----------
    2.     void LoadColorWindow(Transform part)
    3.     {
    4.         int i = 0;
    5.         colorEditWindow.gameObject.SetActive(true);
    6.         picker.gameObject.SetActive(false);
    7.  
    8.         //destory previous buttons
    9.         for (int k = colorEditWindow.GetChild(0).childCount - 1; k >= 0; k--)
    10.         {
    11.             Destroy(colorEditWindow.GetChild(0).GetChild(k).gameObject);
    12.             colorEditWindow.GetChild(0).GetChild(k).parent = null;
    13.         }
    14.  
    15.         // create new buttons
    16.         foreach (Transform p in part.GetComponent<StrongholdPart>().colorEditParts)
    17.         {
    18.             Material[] materialArray = p.GetComponent<MeshRenderer>().materials;
    19.  
    20.             foreach (Material m in materialArray)
    21.             {
    22.                 Button b = Instantiate(colorButtionPrefab, Vector3.zero, transform.rotation);
    23.                 b.GetComponent<RectTransform>().parent = colorEditWindow.GetChild(0);
    24.                 i--;
    25.                 b.GetComponent<RectTransform>().anchoredPosition = new Vector3(40, i * 30, 0);
    26.                 b.GetComponent<ButtonLinkTransform>().linkMaterial = m;
    27.                
    28.                 ColorBlock bc = b.colors;
    29.                 bc.normalColor = m.color;
    30.                 b.colors = bc;
    31.             }
    32.         }
    33.     }
    34.  
    35.     // called by UI button
    36.     public void ColorPickerTurnOn()
    37.     {
    38.         picker.gameObject.SetActive(true);
    39.         currentbutton = EventSystem.current.currentSelectedGameObject.GetComponent<Button>();
    40.         currentSelectedSubMaterial = EventSystem.current.currentSelectedGameObject.GetComponent<ButtonLinkTransform>().linkMaterial;
    41.     }
    42.  
    43. // currentSelectedSubMaterial is assigned by ColorPickerTurnOn
    44.     public void MaterialPicker()
    45.     {
    46. // metal is assigned in inspector
    47.         currentSelectedSubMaterial = metal.GetComponent<MeshRenderer>().material;
    48.     }
     
  2. Xhitman

    Xhitman

    Joined:
    Oct 30, 2015
    Posts:
    452
    After doing some more test, I find that

    This do not work.
    Code (CSharp):
    1.         subPart.GetComponent<MeshRenderer>().materials[0] = metal.GetComponent<MeshRenderer>().material;
    2.  
    3.  
    This work.
    Code (CSharp):
    1.  
    2.         subPart.GetComponent<MeshRenderer>().material = metal.GetComponent<MeshRenderer>().material;
    3.  
    Why?
     
  3. Xhitman

    Xhitman

    Joined:
    Oct 30, 2015
    Posts:
    452
    I finally fix it. Modify the member of the array do not work.

    Need to send the whole array back to the object.
     
  4. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,748
    .material and .materials creates a copy of material for you to use somewhere else
    .sharedMaterial and .sharedMaterials returns references to materials used in renderer

    You should check material instances count in the profiler, probably there are multiple issues in this code.