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
6
Question by burnumd · Jun 16, 2010 at 07:06 PM · editorinspectoreditor-scriptingcustom-inspector

OnInspectorGUI changes reset when played in editor or building

I've created a custom inspector for a tile-based system I'm working on. The target's layout (the number and orientation of the tiles it takes up) is represented as a 2D list of boolean values (eg List<List<bool>>). The new inspector appears to work fine, adding and removing columns and rows as expected. If I go between an prefab with a MyClass MonoBehaviour and some other object, the layout values remain as expected. Pressing play or initiating a build, however, causes the values to get reset to the default. Am I wrong in believing that EditorUtility.SetDirty (target) should cause these values to be set in the target MonoBehaviour. Why does playing the scene cause the values to be reset?

using UnityEditor; using UnityEngine; using System.Collections.Generic;

[CustomEditor (typeof(MyClass))] public class FurnitureEditor : Editor {

 public override void OnInspectorGUI ()
 {
     MyClass tile = target as MyClass;
     DrawDefaultInspector ();
     EditorGUILayout.Separator ();
     GUILayout.Label ("Layout");
     EditorGUILayout.BeginHorizontal ();
     if (GUILayout.Button ("Add Row"))
     {
         tile.layout.Add (new List&lt;bool&gt; ());
         for (int i = 0; i &lt; tile.layout[0].Count; i++)
         {
             tile.layout[tile.layout.Count - 1].Add (false);
         }
     }
     if (GUILayout.Button ("Add Column"))
     {
         foreach (List&lt;bool&gt; boolList in tile.layout)
         {
             boolList.Add (false);
         }
     }
     EditorGUILayout.EndHorizontal ();
     EditorGUILayout.BeginHorizontal ();
     if (tile.layout.Count == 1)
     {
         GUI.enabled = false;
     }
     if (GUILayout.Button ("Remove Row"))
     {
         tile.layout.Remove (tile.layout[tile.layout.Count - 1]);
     }
     GUI.enabled = true;
     if (tile.layout[0].Count == 1)
     {
         GUI.enabled = false;
     }
     if (GUILayout.Button ("Remove Column"))
     {
         foreach (List&lt;bool&gt; boolList in tile.layout) {
             boolList.Remove (boolList[boolList.Count - 1]);
         }
     }
     GUI.enabled = true;
     EditorGUILayout.EndHorizontal ();
     for (int row = 0; row &lt; tile.layout.Count; row++)
     {
         EditorGUILayout.BeginHorizontal ();
         for (int col = 0; col &lt; tile.layout[row].Count; col++)
         {
             if (row == 0 &amp;&amp; col == 0)
             {
                 //Must always take up at least one square.
                 tile.layout[row][col] = EditorGUILayout.Toggle (true);
             }
             else
             {
                 tile.layout[row][col] = EditorGUILayout.Toggle (tile.layout[row][col]);
             }
         }
         EditorGUILayout.EndHorizontal ();
     }
     if (GUI.changed)
     {
         EditorUtility.SetDirty (target);
     }
 }

}

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 burnumd · Jun 28, 2010 at 09:07 PM 0
Share

As it seems no one has an answer, I've filed a bug on this issue. If there turns out to be a workaround or it's confirmed to work in a future version of Unity, I'll update with an answer.

avatar image Tanoshimi2000 · Apr 24, 2015 at 05:21 PM 0
Share

"Why does playing the scene cause the values to be reset?" I'm having the same problem, but not using an editor GUI script. $$anonymous$$y script takes the gameObject and resizes it. Works perfectly in the editor, but then when I run the game (from the editor) it calls that routine again, and changes the size. There's nothing in the Awake or Start functions. I even tried storing a variable that tells whether or not the resizing routine was called, and not calling it (again) if it already was, but it seems like that's getting reset as well.

Anyone know why variables are reset or routines are run twice when creating an object and then running the app?

2 Replies

· Add your reply
  • Sort: 
avatar image
7

Answer by edwood_grant · Jul 28, 2010 at 11:03 PM

I think EditorUtility.SetDirty(target) only sets changes of attributes that are being serialized.

A possible answer to this is that you have to set the [SerializeFiled] tag in each field of the class (Myclass in this case) you want to serialize in the inspector.

In this case I suppose it would be

[SerializeField]
private List<List<bool>> layout = new List<List<bool>>(); 

If you are using DrawDefautlInspector() and don't want the private item to show, you can add HideInInspector to hide it.

[SerializeField, HideInInspector]
private List<List<bool>> layout;

Putting it this way make Unity understand that this attribute must be serialized, and not shown in the inspector (altough that double list is not standard for unity, so probably it wont be shown either).

Another possible problem is that you may be making some "reintialization" of the code somewhere in your MyClass script, try to check that out (Maybe in Start() or Awake()).

A third possible solution is to enable the tag [ExecuteInEditMode()] in Myclass, to guarantee that the first true intialization takes place in the editor, and not when you play the game.

[ExecuteInEditMode()]
public class MyClass : MonoBehaviour
{
    ...
}

I hope this will help you. Italo F. Capasso B. AKA "Edwood Grant"

EDIT

Upong checking it further, it seems that List<List<bool>> cannot be serialized. So you must create another type of structure. For example a serialized class that contains a serialized list. (Usgin either public varsiables, or setting [SerializeField] on private variables.

[System.Serializable] public class Row { public List<Bool> value = new List<Value>(); }

public class MyClass : MonoBehaviour { public List<Row> columns = new List<Row>(); }

This should definetly work, and it wil even be shown in the default inspector with DrawDefautlInspector()

Italo F. Capasso B. AKA "Edwood Grant"

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 burnumd · Jul 29, 2010 at 01:56 PM 0
Share

Thanks for your suggestions. SerializeField and ExecuteInEdit$$anonymous$$ode didn't seem to work, sadly. I don't think it's a problem in Start/Awake, because the reset happens even to prefabs in the project pane as soon as I hit play (even if it's an empty scene).

avatar image edwood_grant · Jul 29, 2010 at 06:28 PM 1
Share

Well I've been cheking by myself, and it looks like List cannot be serialized, you will have to use another kind of construct to make that work... I managed to do it by creating a serializable class that contains bool list, and then create another list in $$anonymous$$yClass that contains the list of that class

avatar image burnumd · Aug 02, 2010 at 01:52 PM 0
Share

Huh. That's an onerous way of having to go about it, but thanks! If you'd care to type that up in an answer, I'd like to mark it as answered appropriately.

avatar image Lukas_GMC · Nov 21, 2012 at 09:51 PM 0
Share

I was having a similar issue. SetDirty worked for me. Thanks edwood.

avatar image alanag · Apr 02, 2017 at 12:32 AM 0
Share

After trying multiple solutions from SetDirty() to EndChangeCheck() to System.Serializable, this is finally the solution that fixed it. Thanks!

avatar image
3

Answer by Lucas Meijer 1 · Sep 11, 2010 at 08:51 PM

I'll bite :), List> cannot be serialized.

I'd need to check, but I think we fixed this for Unity3.

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 jujunosuke · Mar 11, 2016 at 02:55 PM 0
Share

[SerializeField, HideInInspector] Dude you save me..... Genius

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Script to create instance from in inspector 2 Answers

How can i get SerializedProperty from UnityEvent which in List. Sorry for my Eng. 2 Answers

How can I recreate the Array Inspector element for a custom Inspector GUI? 7 Answers

How to record hideFlags for Undo/Redo 0 Answers

Custom Inspector (Editor) - override just one field control 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