• 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
Question by Hurri04 · Nov 27, 2017 at 02:27 PM · unityeditoreditor-scriptingeditorwindow

Outsource EditorWindow code

My current project is a 2D platformer for which I'm building a level-editor by using an EditorWindow.

In previous projects where I created editor tools I noticed that this can quickly lead to very long classes (2000+ loc) which is why this time I want to outsource certain functions into their own classes (e.g FileManagerPanel, LevelInformationPanel, BackgroundLayerPanel, etc) and just call the Draw method I implemented for each of them from within the main EditorWindow. References to instances of these Panel classes are created when the EditorWindow is opened (this way I can later implement Dependency Injection).

 

The problem is that some Panels still need to access other Panels (e.g. the LevelInformationPanel needs to read data from/write data to a ScriptableObject which is loaded in the FileManagerPanel). When everything was still in the same EditorWindow class I would just create a new SerializedObject and call its Update method, then add EditorGUILayout.PropertyField(serializedObject.FindProperty("VariableName")); and afterwards call the ApplyModifiedProperties method.

This works because the EditorWindow class itself derives from UnityEngine.Object and thus can be serialized. With my outsourced classes however, I noticed that it's apparently not a good idea to inherit from UnityEngine.Object directly because the constructor will return null. When deriving these classes from System.Object instead the constructor will work but not the PropertyField.

 

I think ScriptableObject would probably work but I'd need to create file instances within my Asset folder which is kind of ugly. Also maybe PropertyDrawers would work but I don't like using them because it's annoying having to specify all the rects myself instead of being able to use the Layout classes. Is there maybe another option?

Comment

People who like this

0 Show 0
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
Best Answer

Answer by Bunny83 · Nov 27, 2017 at 10:37 PM

An EditorWindow is also just a ScriptableObject. You should never derive any class from UnityEngine.Object. It's just the base class for all objects that have a counterpart on the native C++ side. The only classes you should use as your baseclasses at runtime are MonoBehaviour and ScriptableObject. Of course in editor code we have some additional classes like EditorWindow and Editor (which are actually derived from ScriptableObject).


So you can just derive your classes from ScriptableObject. This will make your classes survive an assembly reload. If you create them in OnEnable only if they do not exist yet everything should be fine. Of course they won't survive a scene change or closing Unity. If you want them to survive that as well you have to store them as assets.

Comment
Hurri04

People who like this

1 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 Bunny83 · Nov 27, 2017 at 11:06 PM 1
Share

ps: You can still use SerializedObject / SerializedProperty as long as your desired field is in a serialized class that is part of the EditorWindow. You just need to use the correct property path. So you don't deal with the actual "panel class" but access it through a SerializedObject of the EditorWindow that is referencing your panel.


However we don't know enough about what kind of interactions you need between your classes. Also do you necessarily need a PropertyField? If you just want to display an GUI block for your panel just use GUILayout and EditorGUILayout controls for the things you actually need to display.


Depending on the usage it might also be a solution to actually make seperate EditorWindows. That way the user can dock them the way he likes. Keep in mind that you can "find" any UnityEngine.Object with FindObjectOfType if you want to make cross references..

avatar image Hurri04 · Nov 28, 2017 at 12:28 AM 0
Share

Ah, of course, thanks!

 

Yeah, I'm aware of the C++ side needed for the serialization. It seems I just didn't think about creating a ScriptableObject without saving the asset since in my previous projects I always needed to save them. However this time around I actually specifically don't want to save certain settings so that the user of the level-editor will always be presented with a fresh state when he opens it up.

 

About the ps:

Good call. I think with this I'll be able to have a reference to the main EditorWindow in the base class of the Panels and save 1-2 reference calls.

Since this is for a level-editor I'll need a few different data types (e.g. Texture2D), hence the PropertyField, at least for now while still testing some things.

 

I also thought about using different EditorWindows to give the user more freedom but decided not to do that for the moment since all panels will be needed at all times for the level-editor anyway.

Maybe later I'll add a toggle for this. I've seen there's an overload for the EditorWindow.GetWindow method which lets you specify another EditorWindow besides which the new one should be opened. I haven't tried it yet and the documentation is a bit vague but I suppose it docks the tab of the new EditorWindow as inactive behind the specified one, right? Though this means that the user will be presented with one long row of tabs (currently 10 Panels) which he then can sort himself (positive) but also has to sort himself (slightly negative). What would be great would be a way to get the information of which EditorWindows are docked in horizontal/vertical "split screen" view in relation to which other ones. If this doesn't exist or proves to be too complicated I can happily leave it out though, since this is pretty low on my todo list for now.

 

Cheers!

avatar image Bunny83 Hurri04 · Nov 28, 2017 at 01:46 AM 1
Share

But a PropertyField is never really needed. The only things which are a bit of a pain are UnityEvents and maybe arrays (though arrays and Lists are actually not that hard).

If you need a Texture2D field you just use an ObjectField. For any UnityEngine.Object type you can use an ObjectField. A PropertyField in the end does just use all those elements you'll find inside the EditorGUILayout class. (IntField, FloatField, Slider, Vector3Field, ...). A PropertyField is useful for generic property handling and when you want to use PropertyDrawers. However if you know the type and have access to the actual class it's actually faster and more flexible to use the proper GUI control directly.


Yes the scripting support for docking is still quite bad. Most of the required classes are internal. So currently it's not possible (without heavy use of reflection) to really create a splitview manually and arrange editor windows the way you want.


GetWindow is the "normal" way to actually create and open an editor window. It will ensure to reuse an existing window so it never opens a second window if there is already one open. I have never used the "desiredDockNextTo" parameter.

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

72 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

Related Questions

Create a custom window and set his position on second screen 1 Answer

Can't remove using Unity Editor, it is necessary for the development of the game. 0 Answers

Error: Unable to load the icon: 'CustomEditorWindow'. (Custom Scene View) 1 Answer

how to stop reorderable list from passing Event value to the new element 1 Answer

Custom Editor window loses values on play. 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