Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
0
Question by firedup15 · Sep 18, 2013 at 08:48 PM · c#materialmaterial color

Changing an object's material script C#

I am new to Unity and I am having some trouble. I am creating a role playing scene where there are 2 quads and each has a separate 2d image of a character. At a certain point in the script I change a variable and when this changes I want the material to change one quad at a time. I tried using this script and put my alternateMaterial in the Resources folder:

 public Material alternateMaterial;

 renderer.material = alternateMaterial;

and while this does not give me an error, it just simply does not work. What am I doing wrong? Is there a way to assign the object multiple materials and just swap which material is shown?

Thanks in advance!

Comment
Add comment · Show 10
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 DaveA · Sep 18, 2013 at 08:50 PM 0
Share

Did you assign alternate$$anonymous$$aterial in the Inspector? Did you set a breakpoint to ensure that this line gets executed? What is 'not work'? Can you edit and post more code?

avatar image gardian06 · Sep 18, 2013 at 08:59 PM 0
Share

if you Debug.Log(renderer.material.name) both before, and after the this assignment

  Debug.Log("before assignment, current $$anonymous$$at " + renderer.material.name + " alt $$anonymous$$at "+ alternate$$anonymous$$aterial.name);
  renderer.material = alternate$$anonymous$$aterial;
  Debug.Log("after assignment, current $$anonymous$$at " + renderer.material.name);

do both of them display, and does the name actually display?

is alternate$$anonymous$$aterial actually different then the

avatar image firedup15 · Sep 18, 2013 at 08:59 PM 0
Share

I know the line gets executed because I have a log statement right above it. I dont know if I can assign alternate$$anonymous$$aterial in the Inspector because I already have a material on the object

avatar image firedup15 · Sep 18, 2013 at 09:18 PM 0
Share

do both of them display, and does the name actually display?

No it does not. I get an error: UnassignedReferenceException: The variable alternate$$anonymous$$aterial of 'ChangeScript' has not been assigned.

avatar image gardian06 · Sep 18, 2013 at 09:20 PM 0
Share

as long as alternate$$anonymous$$aterial is public, and Unity knows how to serialize it can be assigned in the inspector (on the script)

if you are getting an UnassignedReferenceException then that means you have not assigned it. (wonder why it didn't just through NullReferenceException, but this is more telling)

Show more comments

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by gardian06 · Sep 18, 2013 at 09:15 PM

if I want to assign potentially multiple different materials to the same object, or even different materials to different objects. instead of having to track down each and every object that needs to have their materials switched out (tedium in large scenes). I create a static MaterialRepo class that can be called, and used to assign to any object. then I just have a script on the object that needs its material to change just reference the MaterialRepo.

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class MaterialRepo : MonoBehaviour {
     public List<Material> mats;
     public static MaterialRepo inst;
 
     // Use this for initialization
     public void Awake () { if(inst == null){ inst = this; } }
     // Update is called once per frame        public void Update () { }
     
     public Material GetMat(string _name){
         if(mats != null && mats.Count > 0 && _name != null && _name != ""){
             foreach(Material mat in mats){ if(mat.name == _name){ return mat; } }
         }
         return null;
     }
     public Material GetMat(int _index){
         if(mats != null && mats.Count > 0 && _index >= 0 && _index < mats.Count){
             return mats[_index];
         }
         return null;
     }
     
     public Texture GetTex(string _name){
         if(mats != null && mats.Count > 0 && _name != null && _name != ""){
             foreach(Material mat in mats){ if(mat.name == _name){ return mat.mainTexture; } }
         }
         return null;
     }
     public Texture GetTex(int _index){
         if(mats != null && mats.Count > 0 && _index >= 0 && _index < mats.Count){
             return mats[_index].mainTexture;
         }
         return null;
     }
 }

then when I want an object to get a material from the repo while maintaining a reference to their previous one I can just have it do so by:

 using UnityEngine;
 using System.Collections;
 
 [RequireComponent(typeof(Renderer))]
 public class MatChangeExample : MonoBehaviour {
     public int desiredMat;
     public bool useMat1;
     private Renderer _rend;
     private Material mat0;
     private Material mat1;
     
     // Use this for initialization
     void Start () {
         _rend = renderer;
         mat0 = _rend.material;
         mat1 = MaterialRepo.inst.GetMat( desiredMat );
     }
     // Update is called once per frame
     void Update () {
         if(useMat1 == true && _rend.material != mat1){
             _rend.material = mat1;
         }else if(useMat1 == false && _rend.material != mat0){
             _rend.material = mat0;
         }
     }
 }
Comment
Add comment · Show 2 · 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 Pulov · Mar 03, 2015 at 06:39 PM 0
Share

Awesome job gardian06!

I modified the "swapper" script so that it can support multiple materials applied to the mesh. For multiple swaps simply add multiple times this script. I'm not a coder so surely it would be possible to pack multiple swaps in a single script but...

 public class ThermalSwap : $$anonymous$$onoBehaviour {
 
 
         public int index;//refers to the index of the multiple materials aplied to the mesh. 1,2,3....
         public int desired$$anonymous$$at;//Index of the material in the $$anonymous$$aterial Repo 0,1,2...
         public bool use$$anonymous$$at1;
 
         private $$anonymous$$aterial[] mat_reset;
         private $$anonymous$$aterial [] mat0; // position of existing material to swap
         private $$anonymous$$aterial mat1;//thermal material
 
 
 
 
 
         // Use this for initialization
         void Start () {
 
             mat_reset = renderer.materials;
             mat0 = renderer.materials ;
             mat1 = $$anonymous$$aterialRepo.inst.Get$$anonymous$$at( desired$$anonymous$$at );
         }
 
         // Update is called once per frame
         void Update () {
         //for (var i = index; i > renderer.materials.Length; i=index-1 )
 
         //    index = i;
 
             if(use$$anonymous$$at1 == true ){
                 //mat0[i] = mat0;
             mat0[index] = mat1;
                 renderer.materials = mat0;
 
             }else if(use$$anonymous$$at1 == false){
             mat0[index] = mat_reset [index];
                 renderer.materials = mat0;
 
             }
         }
     }
 
avatar image Pulov · Mar 03, 2015 at 06:50 PM 0
Share

nope sorry it wont work swapping multiple materials. Yes it works with a mesh with multiple materials but if you duplicate script only one swap will be performed.

I'll make an array of public materials and not consider the neat $$anonymous$$aterial Repo.

Anyway probably one might find usefull the previous script.

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

19 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Rainbow Material Script Not properly running 1 Answer

Change skybox color via script? 0 Answers

Setting texture for a transparent material in c# 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