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
1
Question by hoy_smallfry · Jul 08, 2013 at 08:04 PM · c#serializationeditorwindowondisable

EditorWindow member serialization in OnDisable

So I've recently run into an issue with transitioning an EditorWindow instance from editor mode to play mode. I want to set a serializable member to a value so that when play mode button is pressed (which reloads the Mono DLLs), the value of the member is set back to what it was in editor mode. I've read this blog post, which explained quite a bit about how it's done, and how to overcome some standard cases.

The problem is that I need to set the member at the end of the EditorWindow's edit mode lifespan, and as far as I'm aware, that means it has to be done in OnDisable(). However, it seems that the editor-to-play serialization happens sometime before OnDisable(), so any changes made to the member in that function aren't a part of serialization.

Here is the scenario at its simplest:

 using UnityEditor;
 using UnityEngine;
 
 public class ExampleWindow : EditorWindow
 {
     static ExampleWindow()
     {
         // prints out whatever libraries are reloaded
         System.AppDomain.CurrentDomain.AssemblyLoad += 
             (object sender, System.AssemblyLoadEventArgs args) =>
             {
                 Debug.Log("Assembly loaded: " + args.LoadedAssembly.FullName);
             };
     }
 
     [MenuItem("MenuItem/Example")]
     public static void Init()
     {
         GetWindow(typeof(ExampleWindow));
     }
 
     void OnEnable()
     {
         Debug.Log("OnEnable: " + x);
         x = 66;
     }
     void OnDisable()
     {
         Debug.Log("OnDisable");
         x = 42;
     }
 
     [SerializeField]
     int x;
 }

When the window is first created, OnEnable is called - x is logged as 0, then x gets set to 66. If play mode is entered while this instance is still open, OnDisable gets called - x is set to 42. The assemblies are then reloaded for play mode, so OnEnable gets called again - but instead of logging 42, x is 66. This is what leads me to believe that serialization has happened prior to OnDisable.

I was curious what you all had to make of this, and what I could do to get it working appropriately. Is there a function I'm not aware of that I could use to get this member set near the end of a lifespan but before serialization? If not, any other solutions? I'd like to avoid something redundant like setting in Update().

Comment
Add comment · Show 4
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 hoy_smallfry · Jul 08, 2013 at 10:44 PM 0
Share

The example I posted was just a simplification of my problem.

In reality, here's the situation: Throughout the life of the EditorWindow, I'm maintaining and updating a complex data structure. The design of this structure makes it impossible to derive ScriptableObject; I tried it a several days ago, and I ended up scrapping the changes because I reached a brick wall, mainly because ScriptableObject's factory-style creation didn't mix well with what was already in-place.

So, in the last few days, I've optioned to create a memento from the object, which has the bare $$anonymous$$imum info about the complex object. I can then reconstruct my complex object from the memento at a later time. (See: memento pattern). The memento is what derives from ScriptableObject.

I thought this would work excellently when switching from edit mode to play mode - just extract a memento from my complex object in OnDisable(), save it to a serializable member, then recreate my structure in OnEnable() with the serialized member.

But, of course, I ran into the problem I have now - serialization seems to happen before OnDisable().

avatar image hoy_smallfry · Jul 08, 2013 at 11:42 PM 0
Share

I was under the same impression about the flow, so I've modified the code above a bit, because sanity checks are always nice. I've even made it so that it prints out when an assembly is reloaded.

According to the output, our assumption is correct, so I'm still under the impression that Unity must serialize sometime before OnDisable.

OnLostFocus sounds like a good idea, since there really is no way to NOT call it when pressing Play. I'll try that and see how it pans out.

avatar image hoy_smallfry · Jul 09, 2013 at 05:41 PM 0
Share

Hey, using OnLostFocus seemed to do the trick. I'm not sure why I didn't think of it before; I guess I just got wound up with the problem.

I'll give credit where it's due if you convert your comment to an answer.

avatar image Loius · Jul 09, 2013 at 07:37 PM 0
Share

I done did it, glad to help :)

2 Replies

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

Answer by Loius · Jul 08, 2013 at 10:54 PM

I haven't encountered your specific issue, but I've been coding around the thought that the flow is:

{User clicks Play}, then OnDisable, then OnEnable

I may be wrong; have you tried Debug.Logs to be sure your OnEnable write isn't overwriting your OnDisable?

Perhaps OnLostFocus and OnDestroy might fit your model better?

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 Jamora · Jul 25, 2013 at 07:55 PM 1
Share

I recently found the EditorApplication.playmodeStateChanged event which is what I think the OP was looking for. It's called right before serialization, it seems.

avatar image
0

Answer by Jamora · Jul 08, 2013 at 08:45 PM

I hope by redundant you mean setting the values every frame, because mine involves a flag check in OnGUI in your EditorWindow...

If you just need different value for runtime and editor mode, then a simple hack could work:

     void OnGUI(){
         if(Application.isPlaying != modeFlag){
             modeFlag = Application.isPlaying;
             if(modeFlag)
                 x = 42;
             else
                 x = 66;
         }
         GUILayout.Label(x.ToString());
         Repaint();
     }

This would skip serialization completely.

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 hoy_smallfry · Jul 08, 2013 at 10:45 PM 0
Share

Yes, that is what I mean by redundant.

I'm not referring to having a different value in play mode than in edit mode. I've added some additional commentary to my post to help clarify the situation.

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

17 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

Related Questions

SerializedProperty and PropertyField NullReference 1 Answer

Inconsistancies between EditorWindow and MonoBehaviour Serialization 2 Answers

Custom Editor window loses values on play. 1 Answer

How do serialized Texture2D fields store and manage Texture2D data pulled from a dll ? 1 Answer

Multiple Cars not working 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