Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
6
Question by Mischa · Jun 01, 2011 at 01:03 PM · arraymaterialschangereplace

How to replace materials in the materials array

I try to replace all materials of an object to make the object transparent. No problem there with a single material attached to the object:

 cachedObject.renderer.material = inReplaceMat;

If I try to access all materials through the materials[] array though, the material doesn't change.

 cachedObject.renderer.materials[0] = inReplaceMat;

Any Ideas? Am I missing something?


The struct, where I try to do this, for better context:

 public struct IntersectingObject{    
     public Material[] cachedMaterial;
     public GameObject cachedObject;
     public IntersectingObject(GameObject inObj,Material inReplaceMat){
         cachedObject = inObj;
         cachedMaterial = cachedObject.renderer.materials;
         for(int i=0; i<cachedMaterial.Length;i++){
             cachedObject.renderer.materials[i] = inReplaceMat;
             //cachedObject.renderer.materials[0].SetTexture("_MainTex",cachedMaterial[i].GetTexture("_MainTex"));
         }
     }
     public void restore(){
         for(int i=0; i<cachedMaterial.Length;i++){
             cachedObject.renderer.materials[i] = cachedMaterial[i];
         }
     }
 }
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
17
Best Answer

Answer by Mischa · Jun 05, 2011 at 10:50 AM

After experimenting a lot I finaly found the solution to the problem: renderer.materials gives just a copy of the materials array, not a reference. Changing the materials in it doesn't have any effect on the actual materials of the renderer.

What works is to substitute the whole array at once with a new preconfigured materials array:

     intMaterials = new Material[cachedMaterial.Length];
     for(int i=0; i<intMaterials.Length;i++){
         intMaterials[i] = inReplaceMat;
     }
     cachedRenderer.materials = intMaterials;
Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image psdev · Jul 05, 2011 at 05:38 AM 0
Share

thanks - but can you please elaborate? Not to hijack your question - but I think my query here is the same thing.

This was driving me crazy why it wouldn't update a material when you'd just change one material in the array and your code of recreating the array and then changing one element and re-assigning the materials array works in that the property is now changing. But it's not changing to the right thing. I'm getting a pink empty material.

I'm setting one material in the new array to my newly loaded material but it doesnt work. $$anonymous$$y Resources.Load does seem to correctly load the material (I can debug out its name) - however when I attempt to set the one material in the way you specify here, the material says "None" in the inspector during the game when I assign it.

How can the value of the loaded material be correct in the variable when I Debug.Log it, but appear as "None" when assigned as part of a new materials array like this? Hopefully I am being clear.

$$anonymous$$aybe it's my loaded material? If I load a material, does it's normal map texture get automatically loaded too - or do I have to load that texture too? I thought I only need to load a texure if I want to reassign a texture in a given material, not just choose a different material?? thanks for any thoughts on this...

avatar image Mischa · Jul 05, 2011 at 07:10 AM 0
Share

Have you tried to assign your newly loaded material not to the array, but to the single material property of the renderer? This way you'll see if it's a problem with the array substitution or with the material itself.

If you get a pink rendering you most likely have an empty material in the materials[] array, means something with the recreating of the array or the re-assigning is wrong. Can you post some of your code there?

avatar image cgydev · Nov 04, 2015 at 03:03 AM 0
Share

Thanks $$anonymous$$ischa, just the thing I was looking for :)

avatar image egwillfriedel · Oct 21, 2017 at 07:28 PM 0
Share

Surprising lack of info on this subject! Your answer helped me a lot!

avatar image Noydj · Jul 17, 2018 at 11:00 PM 0
Share

A big thank you for your post, it solved a problem that I had for 2 days and you are the only one that the code really works.

Show more comments
avatar image
1

Answer by sisse008 · May 29, 2018 at 08:16 AM

in case this helps anyone, solution for bunch of renderers with each one having bunch of materials.

 private Dictionary<Renderer, Material[]> originalMaterials = new Dictionary<Renderer, Material[]>();
 
 void Awake () 
     {
 
         //children is a reference to the renderers
         children = GetComponentsInChildren<Renderer>();
 
         foreach (Renderer rend in children)
         {
             //make array of all materials in renderer
             Material[] materials = rend.materials;
             //add to dictionary renderer and material
             originalMaterials[rend] = materials;
         }
 
 
       }
 
 
 void ChangeToNewMaterial()
     {
         
 
         foreach (Renderer rend in children)
         {
             var mats = new Material[rend.materials.Length];
             for (var j = 0; j < rend.materials.Length; j++)
             {
                 mats[j] = newMaterial;
             }
             rend.materials = mats;
         }
 
     
     }
 
 
 void Reset()
     {
 
         foreach (KeyValuePair<Renderer, Material[]> pair in originalMaterials)
         {
             
             pair.Key.materials = pair.Value;
                 
         }
     }



in anyone has a better solution please share.

Thankyou

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by gwan · Sep 14, 2017 at 04:05 PM

Thanks!! This is exactly what i was looking for

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

10 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Remove content in an Array 1 Answer

Is there a way to replace the question mark in the WWW.LoadImageIntoTexture? 2 Answers

how to swap a mesh using an array 1 Answer

Changing or replace objects 2 Answers

How Change one object to another in animation? ( change Sphere to cube) 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges