Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 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
6
Question by fborok · Sep 23, 2017 at 09:59 PM · c#custom editorprivate

Expose Private Field in Custom Editor

I am writing a custom editor for one of my scripts. The script has private fields that I want to expose to the editor. I want to keep them private as I don't want them to be able to be editable by other classes. I have used [SerializeField] to expose private variables in the standard editor, but I don't know how to expose them in a custom editor.

Class:

 public class Foo : MonoBehaviour
 {
     [SerializeField] private int bar;
 }

CustomEditor:

 [CustomEditor(typeof(Foo))]
 public class EditorFoo : Editor 
 {
     public override void OnInspectorGUI()
     {
         Foo script = (Foo)target;
 
         script.bar = EditorGUILayout.IntField("Bar:" script.bar); // Bar is inaccessible due to its protection level
         );
     }
 }

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

3 Replies

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

Answer by Bunny83 · Sep 24, 2017 at 12:45 AM

Well, there are generally 3 different ways:

  • Use the SerializedObject / SerializedProperty mechanics instead of using the "target" field. This is the recommended solution

  • Add some sort of public property or getter / setter to your class so the editor can actually access it. This of course indirectly makes the field editable by others.

  • Another way would be to use reflection to edit the private member field.

If it's important for you that the field should not be exposed (directly or indirectly) the second solution is out. If you insist in using the old way to write custom inspectors (using "target" or "targets") the only way to change private or protected members is to use reflection.

However the recommended way would be to use the serializedObject of the Editor. You would use FindProperty to get a SerializedProperty back. This can be used to modify the serialized data of that field.

The SerializedObject / SerializedProperty is actually a wrapper for the serialized data that Unity's serializer has stored on the native side. It's also used by the default inspector. Always keep in mind that the SerializedObject and SerializedProperty do not actually work on the class instance, but directly on the serialized data. That's why the usage might seem a bit strange at first glance.

You may want to have a closer look at the first example on the Editor page

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 fborok · Sep 24, 2017 at 01:45 AM 1
Share

I went with the SerializedObject/Property solution, this does exactly what I need it to. Took me a while to get it to work because I was forgetting to Apply$$anonymous$$odifiedProperties.

avatar image bab202 · Feb 26, 2021 at 04:13 AM 0
Share

Nice answer!

avatar image pitchblende · Jul 05, 2021 at 02:28 AM 0
Share

Would you still recommend using SerializedObject / SerializedProperty mechanics within a function like OnSceneGUI? I ask because the docs say (my emphasis):

"Do not use the serializedObject inside OnSceneGUI or OnPreviewGUI. Use the target property directly in those callback functions instead."

So in that case, what's the next best alternative?

avatar image
5

Answer by MaxGuernseyIII · Sep 23, 2017 at 11:28 PM

Private members are accessible to other members of the same class, including inner classes.

 using UnityEditor;
 using UnityEngine;
 
 public class Foo : MonoBehaviour
 {
   private int bar;
 
   [CustomEditor(typeof(Foo))]
   public class EditorFoo : Editor
   {
     public override void OnInspectorGUI()
     {
       var script = (Foo)target;
 
       script.bar = EditorGUILayout.IntField("Bar:", script.bar);
     }
   }
 }
 

Comment
Add comment · Show 5 · 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 · Sep 24, 2017 at 12:31 AM 1
Share

This doesn't make much sense as the editor script need to:

  • be placed in a folder called editor while the runtime script must not be in such a folder.

  • and a custom inspector (class derived from Editor) also need to have the filename match the classname since the Editor class is actually derived from ScriptableObject

avatar image MaxGuernseyIII Bunny83 · Sep 24, 2017 at 03:16 AM 1
Share

Rather than go by whatever you used to come up with those rules, I did something bizarre. I tested the code, saw that it actually worked, and posted my answer.

I don't think the Editor folder rule has been true for ages and I don't know what makes you think that the editor class needs to be in a file with a name that matches the class name. Are you a java developer, maybe?

avatar image Bunny83 MaxGuernseyIII · Sep 24, 2017 at 03:36 AM 4
Share

Well, have you tried building your project?

Unity's serialization of the Editor instance will break if the file name doesn't match the classname. That's a general rule for any class derived from $$anonymous$$onoBehaviour or ScriptableObject.

The only exception is when you compile your class manually into an assembly and you're using that assembly in the project. However as far as i know the class still can't be a nested class.

ps: No, i'm not a java developer. And yes, i do sometimes group multiple classes in a single file, but not $$anonymous$$onoBehaviours or ScriptableObjects. This includes Editor and EditorWindows as well.

Show more comments
avatar image
1

Answer by ZackOfAllTrades · Jun 12, 2020 at 08:30 PM

Another hot tip is make the class partial so your editor script can be in a different file.

       // in file named Foo.cs
       public partial class Foo : MonoBehaviour
       {
           private int bar;
       }
       
      // in a different file name Foo.Editor.cs
      public partial class Foo
      {
       [CustomEditor(typeof(Foo))]
         public class FooEditor: Editor
         {
           public override void OnInspectorGUI()
           {
             var script = (Foo)target;
       
             script.bar = EditorGUILayout.IntField("Bar:", script.bar);
           }
         }
      }

   
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 joshrs926 · May 07 at 12:23 AM 0
Share

I think this is a great solution. I use it too. Note if you use assembly definitions then the editor file needs to be in the same assembly as the monobehaviour. I believe you can still have the editor file in an editor folder in the same assemble as the MonoBehaviour and everything will build, but I haven't tested all that.

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

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

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Custom Assets do not save data that is not primitive 0 Answers

CustomEditor for an ScriptableObject asset only works after recompile. 1 Answer

CustomPropertyDrawer property set to null when in List 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