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 Glurth · Feb 11, 2017 at 05:14 PM · texturescriptableobjectlagpropertydrawer

Texture2D in ScriptableObject’s Property drawer experiences serious lag

I have created a simple test scriptable object (edit: tests show same behavior with custom serializable objects, that are NOT ScriptableObject derived):

 public class TestScriptableObj : ScriptableObject {
     public string title;
     public Texture2D insignia;
 }

And used it in a simple MonoBehavior:

 public class Monotest : MonoBehaviour {
   
     public TestScriptableObj tester;
 
     void Reset () {
         tester = TestScriptableObj.CreateInstance<TestScriptableObj>();
         tester.title = "testTitle2";
     }
 }

I also created a property drawer for it. In order to make the insignia show the texture, like on a material inspector, I was unable to use EditorGUI.PropertyField, and needed to use EditorGUI.ObjectField, and specify the type as Texture2D.

 [CustomPropertyDrawer(typeof(TestScriptableObj))]
 public class TestScriptableObjectPropertyDrawer :PropertyDrawer{
     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
     {
         
         if (property.objectReferenceValue == null)
         {
             EditorGUI.HelpBox(position, "Null object reference ", MessageType.Error);
             return;
         }
         EditorGUI.BeginProperty(position, label, property);
         
         //since TestScriptableObj is a ScriptableObject derivation (a Unity class)- we need to do this backasswards stuff, and get the object from the property:  FindPropertyRelative will return null
         SerializedObject propObj = new SerializedObject(property.objectReferenceValue);
         SerializedProperty title = propObj.FindProperty("title");
         SerializedProperty insignia = propObj.FindProperty("insignia");
 
         position.height = EditorGUIUtility.singleLineHeight;        position.width -= 80;
         EditorGUI.PropertyField(position, title, label);
 
         position.x = position.xMax;        position.width = 80;        position.height = 80;
         insignia.objectReferenceValue = EditorGUI.ObjectField(position, GUIContent.none, insignia.objectReferenceValue, typeof(Texture2D), true);
         
         propObj.ApplyModifiedProperties();
 
         EditorGUI.EndProperty();
     }
     public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
     {
         return 80f;
     }
 }

This works: kind-of. The displayed texture consistently fails to update properly. When it does eventual update, the time it takes to do so, is inconsistent, and seems to depend on what I do with the mouse. Before it updates, there is NO texture shown- just the field background.

alt text alt text What is causing the delayed update? Or, does nobody else experience these delays?

Edit/upadte:

NO!! Not this solution again!! New main question is: What the heck? Surely users of my ScriptableObject asset are not required to specify a do-nothing-custom-editor for their classes that use it, do they? Adding the following do-nothing script resolves the issue:

  using UnityEditor;
  
  [CustomEditor(typeof(Monotest))]
  public class MonoTestEditor : Editor {}


blanktexture-field.png (6.0 kB)
filledtexture-field.png (6.2 kB)
Comment
Add comment · Show 2
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 Glurth · Feb 14, 2017 at 06:12 PM 0
Share

@Bunny83 you helped me understand why the very same solution presented above (do-nothing-custom-editor, update at bottom of Q) fixed a completely different issue: http://answers.unity3d.com/questions/1094473/strange-resolution-to-editor-error-explanation-req.html This issue doesn't not appear to be a Layout system type issue, as I'm not using any such elements. Perhaps you have some advice?

avatar image Glurth · Sep 01, 2017 at 04:48 PM 0
Share

Submitted as a bug: https://fogbugz.unity3d.com/default.asp?947428_63j0ogjjrdnlsjm1

3 Replies

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

Answer by Adam-Mechtley · Sep 01, 2017 at 05:52 PM

This is a bug as a consequence of an implementation detail in Unity.

What is happening here is that Unity internally has a concept of what are called optimized GUI blocks in the Inspector. The idea is that the Editor tries to avoid redrawing stuff unnecessarily unless the user actually changes/interacts with something. This optimization helps tremendously with things like big arrays.

Whenever users define their own custom Editors, this code path is effectively ignored, because we don't want to make assumptions about what might need to be updated in the user's Editor.

Right now, textures drawn with GUI.DrawTexture (which is what this thumbnail uses internally) do not properly register themselves with the optimized GUI block. (The same goes for some things like Handles.) I'm looking into it, but it's unfortunately not a trivial fix. On the plus side, 2017.3 adds a method to PropertyDrawer, CanCacheInspectorGUI(), which you can override to disable the optimized path for individual property drawers. I confirmed that it fixes the problem in this case.

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
0

Answer by HenryStrattonFW · Feb 11, 2017 at 07:51 PM

This is likely due to the fact that the GUI does not repaint every "frame" like you would in a game. The editor GUI only updates and repaints as it needs to in response to various events. So what I think is happening here is that you're data is updating immediately, then when you move your mouse over the inspector, or some other event occurs that causes the GUI to update, you then see the inspector draw the new data, with the perceived delay having occurred.

However, you can get around this. I've not personally needed this yet for any of my drawers so I cant give exact code solution, however there is a post that has a number of suggested examples that appear to have success for various people on the post. So I'd suggest giving one of those a try.

http://answers.unity3d.com/questions/505697/how-to-repaint-from-a-property-drawer.html

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 Glurth · Feb 11, 2017 at 08:42 PM 0
Share

Thanks for the input Henry. I tried a bunch of the suggestion on that link, but none helped, so I tried a sanity check to confirm if it was in-fact a repainting issue. I added the following line after the ObjectField

 EditorGUI.DrawTextureTransparent(position, (Texture)insignia.objectReferenceValue, Scale$$anonymous$$ode.StretchToFill);

This call draws the texture every-time, without delay or issues, a soon as the inspector is shown. Which implies the PropertyDrawer does have the correct texture every-time it is drawn. Why does the ObjectField behave otherwise?

alt text

blankobjectfieldfilledtex.png (6.9 kB)
avatar image HenryStrattonFW Glurth · Feb 11, 2017 at 09:13 PM 0
Share

hmm interesting, I'm going to fire up unity and paste in your scripts, see if I can work out a way to get it to work.

avatar image Glurth HenryStrattonFW · Feb 11, 2017 at 09:20 PM 0
Share

Awsome! FYI: also added position.y+=80; before DrawTexture line, and changed GetPropertyHeight to return 160f;

Show more comments
avatar image
0

Answer by Bunny83 · Feb 17, 2017 at 01:30 PM

I'm not sure what might cause your updating problem, but it might still be related to the missing layout event. Maybe somethings else. Usually Unity will automatically repaint the inspector when an inspected object has changed. Though the object you are changing is not really "inspected". You can try to manually repaint the inspector when the value has changed. Unfortunately only custom Inspectors can request a redraw.

The Repaint method of the Editor class just calls the static InspectorWindow.RepaintAllInspectors(); method. Unfortunately this class and method are internal. So there are two ways to invoke it manually:

  • using reflection

  • using a temp "Editor" instance

This might work:

 if(propObj.ApplyModifiedProperties())
 {
     var tmp = ScriptableObject.Createinstance<Editor>();
     tmp.Repaint();
     DestroyImmediate(tmp);
 }

How exactly do you assign your texture? Do you use the object selector or do you use drag&drop? Is there a difference between the two ways?

You also might want to add a propObj.Update(); after you create the serialized object, just in case.

Comment
Add comment · Show 2 · 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 Glurth · Feb 19, 2017 at 05:12 PM 0
Share

Hi Bunny, away for a week, but will test your repaint suggestion upon return. Texture is assigned either with drag and drop or by hitting the select button, or hard coded. Same issue no matter the assignment method. Oh, also tried the update as suggetzed, no help.

avatar image Glurth Glurth · Feb 25, 2017 at 04:26 PM 0
Share

Alas, calling the repaint method as you suggested, didn't help. I also tried other repaint methods like: EditorUtility.SetDirty(property.objectReferenceValue); and EditorApplication.update.Invoke();

I should have added it to the initial Q, but the first comment on Henry's Answer had some interesting results, I suspect this clue is critical. Simply drawing the texture with EditorGUI.DrawTextureTransparent(position, (Texture)insignia.objectReferenceValue, Scale$$anonymous$$ode.StretchToFill); ALWAYS works/updates properly.

I will attach a zipped version of my current test project to the initial Q, in a moment. edit: oops max attachements on Q... here it is: link text

propertydrawertests.zip (48.7 kB)

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

113 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

Related Questions

WWW class texture lag and memory usage? HELP 1 Answer

ScriptableObject drawing error 0 Answers

optimizing game material with emission map? 0 Answers

How do I prevent the GUI from creating Lag? 1 Answer

Display Custom Inspectors for each class in a 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