Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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
1
Question by Tom01098 · Jan 14, 2017 at 09:28 PM · c#editorcustom editorcustom-inspectorcustom-editor

Prefabs aren't saving with Undo.RecordObject

alt text My Inspector

Undo.RecordObject works as intended and sets the object dirty when I make a change in my custom inspector, but this doesn't seem to work for prefabs.

 using UnityEngine;
 using UnityEditor;
 
 //Displays a custom editor for the CollisionDetection script
 [CustomEditor(typeof(CollisionDetection))]
 [CanEditMultipleObjects]
 public class CollisionDetectionEditor : Editor 
 {
     CollisionDetection scriptTarget;
 
     private void OnEnable()
     {
         scriptTarget = target as CollisionDetection;
     }
 
     public override void OnInspectorGUI()
     {
         DrawDefaultInspector();
         DrawTags();
     }
 
     //Draws the tags section
     private void DrawTags()
     {
         //Title
         GUILayout.Space(5);
         GUILayout.Label("Tags this projectile will collide with", EditorStyles.boldLabel);
 
         //Loops through all tags
         for(int i = 0; i < scriptTarget.collidableTags.Count; i++)
         {
             GUILayout.BeginHorizontal();
 
             EditorGUI.BeginChangeCheck();
 
             //Editable text field
             string tag = GUILayout.TextField(scriptTarget.collidableTags[i].tag, GUILayout.MaxWidth(150), GUILayout.Width(150));
 
             //Boolean Field
             bool instantKill = GUILayout.Toggle(scriptTarget.collidableTags[i].instantKill, "Instant Kill");
 
             if (EditorGUI.EndChangeCheck())
             {
 
                 Undo.RecordObject(target, "Changed Collision Tag");
 
                 scriptTarget.collidableTags[i].tag = tag;
                 scriptTarget.collidableTags[i].instantKill = instantKill;
             }
 
             //Remove button
             if(GUILayout.Button("Remove"))
             {
                 scriptTarget.collidableTags.RemoveAt(i);
 
                 Undo.RecordObject(target, "Removed Collision Tag");
             }
 
             GUILayout.EndHorizontal();
         }
 
         //Additional buttons
         if(GUILayout.Button("Add Tag"))
         {
             scriptTarget.collidableTags.Add(new CollisionTag("New Tag", false));
 
             Undo.RecordObject(target, "Added Collision Tag");
         }
 
         if(GUILayout.Button("Clear Tags"))
         {
             scriptTarget.collidableTags.Clear();
 
             Undo.RecordObject(target, "Cleared Collision Tags");
 
         }
     }
 }

Inside the EndChangeCheck, it is correctly called when a change happens in the inspector, but not when a change happens on a prefab.

alt text This new entry will disappear when I close and reopen my project

Does anyone know of an alternate way to set a prefab dirty, so that it correctly saves? Otherwise I have to set the values in Unity's default list system, which completely negates all the hard work I've put into this inspector. Thanks!

unity2.jpg (23.3 kB)
unity1.jpg (18.7 kB)
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

4 Replies

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

Answer by Bunny83 · Jan 15, 2017 at 02:41 PM

You have to call Undo.RecordObject before your change, not after. In the first case (line 17 in your code above) you do it right. However in line 28, 40 and 48 you call it after you did changes to the object.

The way RecordObject works is that the moment you pass an object to the method Unity creates a snapshot of the current state. Unity automatically checks the list of recorded objects at the end of your custom inspector code and compare the recorded version with the current. If it differs it will create an undo step so the object can be reverted to the recorded state.

Now if you first do changes, then create a snapshot, at the end of your code the state will still be the same and no undo step is created.

So you should do:

         if(GUILayout.Button("Remove"))
         {
             Undo.RecordObject(target, "Removed Collision Tag");
             
             scriptTarget.collidableTags.RemoveAt(i);
         }

This assumes that "CollisionTag" is a [Serializable] custom class that is not derived from UnityEngine.Object (ScriptableObject or MonoBehaviour).

It's also a bit confusing what "scriptTarget" actually is. If it's a UnityEngine.Object derived class (like a MonoBehaviour for example) you might want to pass this reference to RecordObject. If scriptTarget is just a downcasted version of "target" this of course wouldn't change anything but it would make the code more clear, especially since you omitted the declaration and assignment of that variable.

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 Mikilo · Jan 15, 2017 at 03:33 PM 0
Share

This is right.

avatar image Adam-Mechtley · Jan 15, 2017 at 03:42 PM 0
Share

Although this is correct, if you are seeing a difference in behavior between scene objects and prefabs (as stated in the OP), it is a bug per the thread I linked in my answer.

avatar image Tom01098 · Jan 15, 2017 at 04:06 PM 0
Share

$$anonymous$$y apologies, scriptTarget is just target that has been downcasted, edited original question to make it clearer. Thank you for the clear and concise explanation :D

avatar image
2

Answer by v01pe_ · Feb 25, 2019 at 02:43 PM

There's another neat little function that needs to be called in order to make prefab instances save their changes… took me a few hours to figure that out and finally found this: PrefabUtility.RecordPrefabInstancePropertyModifications

since Unity 2017.4 this is also mentioned on the documentation page of Undo.RecordObject

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 Bunny83 · Feb 25, 2019 at 05:17 PM 0
Share

Yes, since Unity shipped the nested prefab feature a lot things got more complicated.

avatar image
1

Answer by Adam-Mechtley · Jan 15, 2017 at 02:09 PM

Please see my answer to this question and see if it helps: http://answers.unity3d.com/questions/1269406/ui-text-is-not-being-rebuiltupdated-in-edit-mode-w.html#comment-1269850

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
1

Answer by Damjan-Mozetic · May 14, 2018 at 08:23 AM

Just wanted to post a link that fixes the bugged implementation of Undo.RecordObject, which still causes problems on 2018.1. https://gist.github.com/lazlo-bonin/a85586dd37fdf7cf4971d93fa5d2f6f7

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

279 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 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 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 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 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 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 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 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 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 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 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 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 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

Create Spells through classes in custom editor? 1 Answer

Handles not displaying 1 Answer

Custom Inspector Horiztonal Vector2 and Button Spacing 0 Answers

Can a class's Editor call its component's Editor? Likewise, can a derived class's Editor call its base class's Editor? 1 Answer

Questions Regarding Images in Custom Inspector/Editor 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