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 Shiolle · May 05, 2011 at 10:15 AM · editor-scriptingasset

Replacing materials in sharedMaterials in an editor script.

I have a problem similar to http://answers.unity3d.com/questions/36659/setting-sharedmaterial-only-setting-for-one-object but the proposed solution does not satisfy my needs. I have a lot of prefabs imported into my project with multiple materials per mesh.

When I import an FBX into my project, UNity creates a set of materials for it. The thing is, there are a lot of materials on different objects that should be the same. The good example is glass material on buildings: I have a lot of different buildings with different wallsand roof materials, etc. but I want them all to use the same glass material, so I could set it up once, and every time I change it, all the windows would change.

Thing is there are tons of cross used materials (around 100) like that and a lot of prefabs (like 200 with 5-10 materials per prefab), so setting materials list manually would be a huge task.

I wrought an editor script to search for materials with certain names in objects and replace them with materials form a preset. It's working perfectly with an object, but never changes a prefab. I cannot use CopyPropertiesFromMaterial because it won't make different objects use the same material, just copy settings from my preset materials to another. Here's the code I use:

Material[] tempList = recipient.renderer.sharedMaterials; int changesDone = 0; for(int i = 0; i < tempList.Length; i++) { string replacingName = ParseMaterialName(tempList[i].name); if(replacingName == "") { ..... continue; }

     if(nativeMaterials.ContainsKey(replacingName))
     {
         tempList[i] = nativeMaterials[replacingName];
         changesDone++;
         ......
         continue;
     }

     if(SharedMaterials.ContainsKey(replacingName))
     {
         tempList[i] = SharedMaterials[replacingName];               
         changesDone++;
         .....
         continue;
     }
     .....
 } 
 .....
 if(changesDone &gt; 0)
 {
     recipient.renderer.sharedMaterials = tempList;
     return true;
 }
 ......
         EditorUtility.SetDirty(recipient);
         AssetDatabase.SaveAssets();

What am I doing wrong? Is it possible to somehow change the whole materials list of a prefab and save the changes to asset database?

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

2 Replies

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

Answer by Shiolle · May 05, 2011 at 01:01 PM

I found a solution. Instead of

        EditorUtility.SetDirty(recipient);
        AssetDatabase.SaveAssets();

I should have used

        target.name = obj.name;
    UnityEngine.Object newPref = EditorUtility.CreateEmptyPrefab("Assets" + path + obj.name + ".prefab");
    EditorUtility.ReplacePrefab(target, newPref);
    AssetDatabase.Refresh();

The answer was as usual in docs all along: http://unity3d.com/support/documentation/ScriptReference/EditorUtility.ReplacePrefab.html

I have to note two peculiarities though:

  1. I have to refresh database after every object. Placing AssetDatabase.Refresh(); after all the objects were modified somehow failed to update prefabs for unknown reason.
  2. target.name = obj.name; is there because target (the object instantiated from initial prefab and being modified) has a "(clone)" part attached to it's name by default.

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 Bunny83 · May 05, 2011 at 12:11 PM

The problem here is that model-prefabs can't be saved because they are generated with the ModelImporter. There are different types of prefabs in Unity. Take a look at PrefabType.

Furthermore Unity is just doing what you told it ;). The modelimporter have a setting which materials it should create.

If you have many models that are updated very often you should create an AssetPostProcessor. Take a look at .OnPreprocessModel, .OnPostprocessModel and .OnAssignMaterialModel.


edit

To modify an existing prefab i always go this way:

  1. Get a prefab reference with prefab = AssetDatabase.LoadAssetAtPath.
  2. Instantiate the prefab using obj = EditorUtility.InstantiatePrefab.
  3. Apply your changes to the instantiated object.
  4. Save the changes to the prefab with EditorUtility.ReplacePrefab(obj,prefab).
  5. Use either AssetDatabase.ImportAsset or AssetDatabase.Refresh to update the asset.

I've discovered when you use CreateEmptyPrefab you might loose the references to this prefab because it's a new one. Just use the original prefab for ReplacePrefab it exchange the "content" and keep the prefab itself.

Comment
Add comment · Show 4 · 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 Shiolle · May 05, 2011 at 12:55 PM 0
Share

I wasn't talking about model-prefab, but regular prefabs (GetPrefabType returns Prefab). I was only talking about modifying prefabs made upon those models. Thanks for hinting about post processing models though.

avatar image Bunny83 · May 05, 2011 at 01:24 PM 0
Share

Well, you said "when you import a fbx model..." so i thought you talk about a $$anonymous$$odelPrefab ;). I've added some info on changing prefabs.

avatar image Shiolle · May 05, 2011 at 02:27 PM 0
Share

Thanks, figured out that part already (see my answer). Two things I noticed. LoadAssetAtPath as well as Load$$anonymous$$ainAssetAtPath always return 0 assets. 1. LoadAllAssetsAtPath works fine, although I need to filter through them in order to find the type I need (GameObject). 2. ReplacePrefab somehow does not work with existing prefab. I had to create empty prefab at the same location as the old one and place ReplacePrefab onto new one.

avatar image Bunny83 · May 05, 2011 at 03:33 PM 0
Share

That's strange. It works fine for me. Are you sure you used EditorUtility.InstantiatePrefab to instantiate the object? I can remember that if the prefab has changed you have to "refresh" your prefab reference. I use a script with the exact order i've posted above and everything works.

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

1 Person is following this question.

avatar image

Related Questions

Connecting oracle with unity tutorial, Steps or a way? 1 Answer

How to save changes of fbx subassets ? 0 Answers

CreateAssetMenu below builtin/default create asset menu items 1 Answer

How do I make copies of my Font with an editor script? 2 Answers

Adding an element to List a .asset file of ScriptableObject 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