Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
2 captures
13 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
0
Question by Cactusman · Dec 24, 2021 at 08:44 AM · editor-scriptingeditorguifile-io

Invoking a file dialogue from a PropertyDrawer

When invoking EditorUtility.OpenFilePanel from within PropertyDrawer.OnGUI my editor hits an error: InvalidOperationException: Stack empty.

Here is the propertydrawer code:

 public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
 {
     EditorGUI.BeginProperty(position, label, property);
     {
         GUILayout.BeginHorizontal();
         {
             GUILayout.Label(property.displayName);
             SerializedProperty stringGuidProperty = property.FindPropertyRelative("StringGuid");
             EditorGUILayout.SelectableLabel(stringGuidProperty.stringValue);
 
             // Select a file via a file browser and read the SerialID from that file
             if (GUILayout.Button("Copy Instance ID From File"))
             {
                 string path = EditorUtility.OpenFilePanel("Select Instance to Load", "", "xml");
                 if (path.Length != 0)
                 {
                     string id = DataSerializer.GetSerialIDFromFile(path);
                     stringGuidProperty.stringValue = id;
                 }
             }
         }
         GUILayout.EndHorizontal();
     }
     EditorGUI.EndProperty();
 }

While debugging this everything seems to work. The correct ID is assigned to the stringGuidProperty except when GUILayout.EndHorizontal() is executed an error is thrown which seems to prevent the property from being applied.

If I change the line opening the file panel to a hardcoded string everything works fine without any errors and the correct ID is loaded.

Here is the full error:

 InvalidOperationException: Stack empty.
 System.Collections.Generic.Stack`1[T].ThrowForEmptyStack () (at <0463b2ef957545c0a51b42f372cd4fbb>:0)
 System.Collections.Generic.Stack`1[T].Pop () (at <0463b2ef957545c0a51b42f372cd4fbb>:0)
 UnityEditor.PropertyDrawer.OnGUISafe (UnityEngine.Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) (at <bbfbd5a71eea45d1a1354233c800516b>:0)
 UnityEditor.PropertyHandler.OnGUI (UnityEngine.Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, System.Boolean includeChildren, UnityEngine.Rect visibleArea) (at <bbfbd5a71eea45d1a1354233c800516b>:0)
 UnityEditor.PropertyHandler.OnGUI (UnityEngine.Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, System.Boolean includeChildren) (at <bbfbd5a71eea45d1a1354233c800516b>:0)
 UnityEditor.PropertyHandler.OnGUILayout (UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, System.Boolean includeChildren, UnityEngine.GUILayoutOption[] options) (at <bbfbd5a71eea45d1a1354233c800516b>:0)
 UnityEditor.EditorGUILayout.PropertyField (UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, System.Boolean includeChildren, UnityEngine.GUILayoutOption[] options) (at <bbfbd5a71eea45d1a1354233c800516b>:0)
 UnityEditor.EditorGUILayout.PropertyField (UnityEditor.SerializedProperty property, UnityEngine.GUILayoutOption[] options) (at <bbfbd5a71eea45d1a1354233c800516b>:0)
Comment
Add comment · Show 3
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 Cactusman · Dec 24, 2021 at 08:48 AM 0
Share

Based on the error it seems like opening a file dialogue from a property drawer is somehow interfering with the how the GUI pushes and pops gui layers.

Unity supports asset selection windows by default though so there must be some way to do this sort of thing?

avatar image Cactusman · Dec 24, 2021 at 09:11 AM 0
Share

It looks like you can do this within a custom Editor. That's not really what I wanted though - this type should by default have a specific editor and it makes more sense for the type's propertydrawer to encapsulate weird editing behavior. I'm a complete beginner on Unity editor design philosophy though...

While searching for an answer I found ObjectField but it relies on the thing being selected being an actual Asset that unity knows about whereas I'm referencing files.

Anyway if someone comes along with decent editor knowledge and can explain better why OpenFilePanel doesn't work or a reasonable workaround that still uses propertydrawer I will mark that as the accepted answer.

avatar image ElicaIWD · Dec 28, 2021 at 03:19 PM 0
Share

It used to work in Unity 2018.4. I have just updraged to 2020 and I have the same error. I have even tried using an external browser tool that I use for runtime, and the result is the same.

On another (old!) post they recommend using GUIUtility.ExitGUI(). Indeed it suppresses the error, because it throws a silent exception just before, but then the property value does not get serialized, since we exit prematurely.

That's why I also called property.serializedObject.ApplyModifiedProperties(); before exiting.

I don't really like this hack, but I guess it will have to do.

My final code in OnGUI():

 if( GUI.Button( indentedPos, new GUIContent( property.stringValue) ) )
         {
             string newPath = EditorUtility.OpenFilePanel( "Choose FilePath", property.stringValue, ".json" );
 
             if( !string.IsNullOrEmpty( newPath ) )
             {
                 property.stringValue = newPath;
                 property.serializedObject.ApplyModifiedProperties();
             }
             GUIUtility.ExitGUI();
         }

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Namey5 · Dec 26, 2021 at 12:15 PM

It is possible that the GUILayout.Horizontal sections are messing with the file utility - have you tried moving the actual call to EditorUtility.OpenFilePanel to the outer scope?

  public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
  {
      EditorGUI.BeginProperty(position, label, property);
      {
          SerializedProperty stringGuidProperty = property.FindPropertyRelative("StringGuid");
          bool openFile = false;
 
          GUILayout.BeginHorizontal();
          {
              GUILayout.Label(property.displayName);
              EditorGUILayout.SelectableLabel(stringGuidProperty.stringValue);
  
              // Cache the button press
              openFile = GUILayout.Button("Copy Instance ID From File");
          }
          GUILayout.EndHorizontal();
 
          // Select a file via a file browser and read the SerialID from that file
          if (openFile)
          {
              string path = EditorUtility.OpenFilePanel("Select Instance to Load", "", "xml");
              if (path.Length != 0)
              {
                  string id = DataSerializer.GetSerialIDFromFile(path);
                  stringGuidProperty.stringValue = id;
              }
          }
      }
      EditorGUI.EndProperty();
  }
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

145 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

Related Questions

Should EditorGUILayout.PropertyField work with serializable classes? 1 Answer

How to execute a script each time I add a certain prefab to the scene? 2 Answers

GetPropertyHeight infinite recursion on drawer 1 Answer

Array of vectors lost in runtime, but not null 0 Answers

OnInteractivePreviewGUI multiple selection. Works but spams errors. 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