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
3
Question by Tietsap · Sep 04, 2014 at 11:06 PM · c#materialinstance

Changing one material instance affects all instances?

I am trying to instantiate a prefab gameobject using 'Instantiate(myObject);', of which i need a lot more than one. For some reason though i can't seem to create new instances of the gameobject. Each 'new' instance is a clone of an existing one. I need the instances to be fresh instances instead of clones, because i want to be able to change a texture by code and having the code apply to one instance instead of all instances. Whenever I change the texture on the object the texture changes for all objects.

The code I use looks somewhat like this:

 ObjectController object = gameObject.AddComponent<ObjectController>();
 Instantiate(object.Object);

The ObjectController contains a gameobject called Object, which is loaded like this:

 this._object = (GameObject)Resources.Load ("Models/object");

For some reason this code looks fine and it spawns no errors / doesn't cause any problems. How do I go about trying to accomplish this?
Do I really need to create separate prefabs with preselected textures for each instance i want to create?

EDIT:

I found out it's not necessarily a problem with clones of the object, as much as a problem with shared materials. For some reason every instance of the object uses the same material, or links to the same material. I've been searching google on how to create a new instance of a material and assigning it to an object, but somehow none of the results seemed to work for me.

So I guess my question remains sort of the same, except it doesn't involve gameobjects but materials.

EDIT 2:

I know this question is related to other questions that have frequently been answered on this board, however as you say, by accessing a renderer's material it creates a new instance of the material does not apply to me.

I've tried changing the material's textures by using the following code:

 foreach(Material material in this.object.renderer.materials) {
     if(material.name == "face") {
         material.mainTexture = this.replacementTexture;
     }
 }

I obviously access the renderers material here, but still all the object instances change textures instead of just the one i perform the texture change on. I know I am probably overlooking something but I wasn't able after a couple of hours of searching for a solution (both on this board as well as in other locations) to resolve this problem.

Comment
Add comment · Show 3
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 rutter · Sep 04, 2014 at 10:42 PM 0
Share

Instantiate can clone objects in the scene, or it can clone prefabs. If you want a fresh GameObject, you can always clone a prefab that's not even in the scene.

As far as creating material instances, Unity usually handles that for you. The first time you access a renderer's material, an instance will automatically be created and assigned to the renderer.

I'm hesitant to let this through the moderation queue because it's a frequently asked question. It's not a bad question, we're just trying to cut down on the number of duplicate threads in this area of the site. If you have anything else to add, feel free to comment here; if not, I'll drop the question from the queue in a little while.

If you can't find help, here, you can always try the forums or look up some tutorials online.

avatar image Tietsap · Sep 04, 2014 at 10:50 PM 0
Share

@rutter I placed a reply in the question (EDIT 2).

avatar image rutter · Sep 04, 2014 at 11:09 PM 0
Share

Your problem is somewhere else, then. Perhaps your code is accidentally editing more materials than you think, or you're editing the material of an object which you later clone. If you edit the "base" object, any clones made from it will also be affected.

4 Replies

· Add your reply
  • Sort: 
avatar image
5

Answer by Nemarques · Jun 18, 2017 at 03:26 PM

Hey @Tietsap i suggest you to take a look at this. http://thomasmountainborn.com/2016/05/25/materialpropertyblocks/ You just have to mark on your shader the properties that will differ. And then in the script you can manipulate the values of each object despite of being the same material.

You also have here some documentation by unity https://docs.unity3d.com/ScriptReference/MaterialPropertyBlock.html

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
5

Answer by bloodthirst69 · Jul 24, 2018 at 07:15 PM

So i was fiddling a bit on my own since i needed this , and it was actually much simpler than i thought , here's a code example :

public class ButtonColorSelector : MonoBehaviour {

 public Color MainColor;

 public Color SecondaryColor;


 // Use this for initialization
 void Start () {

     GetComponent<Image>().material = Instantiate<Material>(GetComponent<Image>().material);
     
 }

 private void Update()
 {
     GetComponent<Image>().material.SetColor("_ButtonColor", MainColor);
     GetComponent<Image>().material.SetColor("_Color1", SecondaryColor);
 }


}

Just set the original Material from the inspector and each instance will have its properties set by the script , in my example the material was attached to 4 diffent Images with the same material but different properties BAM done !

Comment
Add comment · Show 1 · 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 ThomLaurent · Jul 01, 2020 at 05:04 PM 1
Share

Cool example but I need to fix your code just in case someone would copy-paste it in a real project :

 // Within an Example.cs file

 // We requirement this component to have an Image nearby, otherwise Unity will create it
 [RequireComponent(typeof(Image))]
 public class Example : $$anonymous$$onoBehaviour
 {
     // Better encapsulation
     [SerializeField] private Color _mainColor;
     [SerializeField] private Color _secondaryColor;
 
     private Image _image;
 
     private void Start()
     {
         // We do this GetComponent() only once
         _image = GetComponent<Image>();
         if (_image.material != null) // We dodge the null ref exception
             _image.material = Instantiate(_image.material);
     }
 
     private void Update()
     {
         // GetComponent() is a costly operation, doing it twice in a frame was rough for your game ;)
         _image.material.SetColor("_ButtonColor", _mainColor);
         _image.material.SetColor("_Color1", _secondaryColor);
     }
 }
avatar image
1

Answer by toddisarockstar · Jun 18, 2017 at 03:45 PM

you need to create a new material instance instead of just changing the texture of the current one. i would recommend droping an alternative material into the inspector for use. but if you wanted to create it at runtime you can make it like this. this will work and only apply to one object

         someobject.renderer.material = new Material(Shader.Find("Diffuse"));
         someobject.renderer.material.color = Color.blue;
         someobject.renderer.material.mainTexture = sometexture2D

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 naklow12 · Oct 10, 2019 at 11:55 AM

 Material material = new Material(Shader.Find("Shader Graphs/SHADER_NAME_HERE"));
         material.SetColor("Color_C6F9B478", Color.blue); // CHANGE  Color_C6F9B478 with your Color prop ID
         gameObject.GetComponent<Renderer>().material = material;

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

8 People are following this question.

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

[C#] Checking InstanceOf? 2 Answers

How can I set the material on an instance after creating it? 1 Answer

Is it possible to calculate batch count of each material ? 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