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

Loading Material from Asset Bundle

Discussion in 'Editor & General Support' started by Blenderik, Jan 26, 2021.

  1. Blenderik

    Blenderik

    Joined:
    May 14, 2013
    Posts:
    146
    I have a Prefab, a shader, a cginc and a material (with textures assigned) stored in an AssetBundle.
    I want to instantiate it with different colors, several objects per color. I thought I could just set the color in the material, assign it to the original prefab and Instantiate, then repeat for the 2. color.
    1. issue: I can't change the material of the prefab, only the sharedMaterial, which still results in the material being null, I don't know why.
    Is there a good practice, making 1 instance, assigning the material and then Instantiate that Clone again seems not very straight forward.
    2. issue, and this really gets me: If I Clone the Material
    Code (CSharp):
    1. Material newMaterial = new Material(<MyMaterialFromAssetBundle>);
    2. GameObject preClonedPrefab = Instantiate(<MyModelFromAssetBundle>);
    3. preClonedPrefab.GetComponent<Renderer>().material = newMaterial;
    4. // then use a for loop instantiating the preClonedPrefab
    5.  
    Using breakpoints, I can see the newMaterial is correct. Textures are there and everything.
    But in the clones: The first one has the material, but it's pink, error: Texture is inaccessabel, the other clones don't have a material at all.
    if I use
    Code (CSharp):
    1. Material newMaterial = Instantiate(<MyMaterialFromAssetBundle>)
    I don't get the error message, but none of the instances have a material assigned.

    EDIT: If I drag the material into a public test variable in the inspector instead of loading it from the prefab and otherwise using the same code, all is fine.

    EDIT: I think it's a bug in the inspector, I have not tried it compiled, but if I use:
    Code (CSharp):
    1. MyClone.GetComponent<Renderer>().material;
    Anywhere after the cloning the material appears fine. I wanted to just print the material's name this way and it magically appeared.
     
    Last edited: Jan 26, 2021
  2. Blenderik

    Blenderik

    Joined:
    May 14, 2013
    Posts:
    146
    OK, figured it out:
    Using GetComponent to obtain the material creates an instance (I thought it would only do that when I change a value). At a later point in my script I accidentally destroyed the new material. So it did get assigned to all copies, but was destroyed globally at another point.
    MyClone.GetComponent<Renderer>().material;
    Created an instance, assigned that Instance and didn't care about me destroying the manually created copy.
    Hope that helps others struggling with the odd way material manipulation works in Unity.