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 Cousken · Jun 09, 2014 at 02:41 PM · prefabmaterialinstance

Copying material destroys prefab

I'm working on a 3d tile based game. I've reached a point where i need to replace one tile for another. The tile i'm replacing is an instanced prefab (GameObject), and the way i'm going about it is simply trying to replace it's material with the material of the prefab of the tile i want it to turn into.

In short, i'm replacing the material of a game object which is a instanced prefab.

First i've tried this:

 gameObject.renderer.material = prefab.renderer.material;

The first time i run the game this works well. After i quit, my prefab looses it s material component for some reason. The result are very unexpected to me: alt text

The magenta colored squares are the tiles i was trying to replace. What is most surprising is that this is caused by permanent damage to the prefab i have in the editor... The material it had simply disappeared.

I tried a couple of different ways, and the one that worked was:

 gameObject.renderer.material = Resources.Load<Material>("Materials/Dirt");

However this is not optimal, since i will not know the path of the materials... i need to be able to get them from the prefab. Also, this is done run time and i don t think the Load method has acceptable performance.

Can you explain to me why my prefab looses it's material component? Also, i would like some input on what is the best / correct way of replacing a material of a prefab instanced with a material from another prefab.

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

1 Reply

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

Answer by Owen-Reynolds · Jun 09, 2014 at 04:18 PM

The problem comes from just looking at the prefab's material: prefab.renderer.material. When you touch renderer.material for the first time, Unity automatically copies it, and assigns the copy to that renderer. If you've seen "smart" pointers to invariants, it's the same idea. All boxes share a red material: setting box6.material to blue requires that we split off a copy for box6.

So, during play it modifies the editor copy of the prefab. Once the game stops, the copied material is destroyed, as usual, and the prefab's Material link is now null. (So, in theory, the problem might not happen in a build.)

The only solution I've found is never to do that. Either to provide a separate public prefabMat var. Or to pre-spawn the prefab, and read materials from there.

I'm not aware of anything else that works like this. Probably safe to examine all of a prefab's children, collider sizes, script values, meshes... . Just never the materials.

Why does just reading a material cause a new copy to be made? Well, Material m1 = A.renderer.material; could be followed by m1.color=, when it would be too late to make a copy.

Comment
Add comment · Show 3 · 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 Cousken · Jun 10, 2014 at 05:43 AM 0
Share

Thanks a lot! Great answer!

I still require to retrieve materials and meshes, probably scripts at this point in runtime, based on an enum that describes the prefab i want to use.

I could either introduce some factories, that return these components... Or have some instances of the game objects which i can copy things from.

Do these instances need to be in the game scene? I think that would be ok if i can disable their rendering and all the scripts they might have.

avatar image Owen-Reynolds · Jun 10, 2014 at 05:10 PM 0
Share

I believe you can safely exa$$anonymous$$e a mesh straight off a prefab, and $$anonymous$$aterials are the only oddballs.

Also believe you can safely Instantiate, SetActive(false), and use the object as a reference. Not sure if you need to Destroy scripts, but I think I've done that. One reason people think you can't use inactives is that you can't GameObject.Find them. But if you preserve a link, inactives work like normal.

avatar image Cousken · Jun 11, 2014 at 06:42 AM 0
Share

Thanks a lot, really :) I wish i could upvote your answer but i don't have reputation enough yet :(

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

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

Related Questions

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

Change material inside instanced prefab, gameobject.renderer is NULL 1 Answer

change prefab material 2 Answers

How to change material without creating a new material instance? 1 Answer

Possible Unity Glitch. A few lines of code erasing prefab data. 1 Answer


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