Search Unity

Change material of Probuilder object in code (runtime)

Discussion in 'World Building' started by sachinhosmani, Feb 9, 2019.

  1. sachinhosmani

    sachinhosmani

    Joined:
    Mar 19, 2016
    Posts:
    4
    Hi,

    I am using Probuilder to create custom models in my game. The traditional way of applying a material to a Probuilder mesh is using their UI like so: https://imgur.com/a/Mvm7Gjf

    But in my case I would like to change the material during runtime through code. I tried this piece of code, but it doesn't work like it does on normal objects.

    Code (CSharp):
    1. obj.GetComponent<MeshRenderer>().material = newMaterial;
    I thought that once you "build" an object using Probuilder it becomes a standard Unity object, but I find many random issues popping up like this.

    For example, I also see that each face of my Probuilder object gets a different material sometimes: https://imgur.com/a/ov0mNsy This is what I ended up with when I tried to add multiple materials via the Probuilder UI.

    Any suggestions?

    Thank you
     
  2. kaarrrllll

    kaarrrllll

    Unity Technologies

    Joined:
    Aug 24, 2017
    Posts:
    153
    Assuming you are using ProBuilder 4.0.0 or higher, your code should work just fine.

    Here is an example showing how to change the material per-object, as well as per-face.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.ProBuilder;
    3.  
    4. public class SetMaterial : MonoBehaviour
    5. {
    6.     public Material material;
    7.  
    8.     // Start is called before the first frame update
    9.     void Start()
    10.     {
    11.         // Set the material for the object
    12.         var mesh = ShapeGenerator.CreateShape(ShapeType.Cube);
    13.         mesh.transform.position = new Vector3(-1f, 0f, 0f);
    14.         mesh.transform.localRotation = Quaternion.Euler(0f, 45f, 0f);
    15.         mesh.GetComponent<MeshRenderer>().sharedMaterial = material;
    16.  
    17.  
    18.         // Set the material for a single face
    19.         var mesh2 = ShapeGenerator.CreateShape(ShapeType.Cube);
    20.         mesh2.transform.position = new Vector3(1f, 0f, 0f);
    21.         mesh2.transform.localRotation = Quaternion.Euler(0f, 45f, 0f);
    22.  
    23.         mesh2.GetComponent<MeshRenderer>().sharedMaterials = new Material[2]
    24.         {
    25.             BuiltinMaterials.defaultMaterial,
    26.             material
    27.         };
    28.  
    29.         // Faces are sorted into submeshes by their submeshIndex. Here we set even numbered faces to the second material
    30.         // in the MeshRenderer.sharedMaterials array.
    31.         for(int i = 0, c = mesh2.faceCount; i < c; i+=2)
    32.             mesh2.faces[i].submeshIndex = 1;
    33.  
    34.         // rebuild mesh topology (positions, submeshes)
    35.         mesh2.ToMesh();
    36.  
    37.         // rebuild generated data (UVs, normals, tangents...)
    38.         mesh2.Refresh();
    39.     }
    40. }
    41.