Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

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:
    123
    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.