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
0
Question by Excrubulent · Apr 23, 2012 at 02:16 PM · c#propertiescustom-editor

Custom Editor Properties Revert to Defaults on Play

EDIT: I've more clearly figured out the problem, and made the code simpler to read.

I'm trying to create a manager class for flocking AI, so I can make one change and update every single member of the flock at once, rather than having to change the properties of every single member individually.

So I've got TestPropertyManager, which has an internal class called TestProperties. TestProperties is an internal class so that other internal classes can inherit from it in a way that mirrors the inheritance of the objects whose properties I'm managing.

 using UnityEngine;
 using System.Collections;
 
 public class TestPropertyManager : MonoBehaviour
 {
     public TestProperties TestManager = new TestProperties();
     
     public float TestA;
     public float TestB {get; set;}

             [System.Serializable]
     public class TestProperties
     {
         public float TestC;
         public float TestD {get;set;}
     }
 }

Then I've got the custom inspector script, TestPropertyEditor, which just exposes the floats to the editor:

 using UnityEditor;
 using UnityEngine;
 
 [CustomEditor (typeof(TestPropertyManager))]
 public class TestPropertyEditor : Editor
 {
     public override void OnInspectorGUI()
     {
         TestPropertyManager temp =    target as TestPropertyManager;
         
         temp.TestA = EditorGUILayout.FloatField("Test A", temp.TestA);
         temp.TestB = EditorGUILayout.FloatField("Test B", temp.TestB);
         
         temp.TestManager.TestC = EditorGUILayout.FloatField("Test C", temp.TestManager.TestC);
         temp.TestManager.TestD = EditorGUILayout.FloatField("Test D", temp.TestManager.TestD);
         
     }
 }

The problem that I'm having with this system is that whenever I Play/Stop the game, the properties (TestB & TestD) revert to 0. The fields (TestA & TestC) retain the values they had in the editor. However, if I change TestA or TestC at runtime, then press Stop, they still revert to the values they had before pressing Play.

I also tried using SerializedProperty, but it had problems with the fact that Test belongs to TestManager, so I can't access Test with serializedObject.FindProperty(string propertyPath). I also can't get SerializedProperty to accept TestProperties, because it's not a type that it recognizes.

So basically I need the floats to persist when I press Play/Stop.

Comment
Add comment · Show 1
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 Excrubulent · Apr 24, 2012 at 04:18 AM 0
Share

A development, but not quite there yet:

The [System.Serializable] attribute applied to the TestProperties class will allow TestC to persist when Play is pressed, but still not when Stop is pressed. Edited question to reflect this.

4 Replies

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

Answer by Excrubulent · Apr 24, 2012 at 05:34 AM

This is a better answer than my other one, because it retains the private accessibility of the fields using [SerializeField].

Here's the updated version of TestPropertyManager that allows the property fields to persist on Play (although not on Stop):

 using UnityEngine;
 using System.Collections;
 
 public class TestPropertyManager : MonoBehaviour
 {
     public TestProperties TestManager = new TestProperties();
     public float TestA;
     
     [SerializeField]
     float _testb;
     
     public float TestB
     {
         get {return _testb;} 
         set {_testb = value;}
     }
     
     [System.Serializable]
     public class TestProperties
     {
         public float TestC;
         
         [SerializeField]
         float _testd;
         
         public float TestD
         {
             get{return _testd;}
             set
             {
                 _testd = Mathf.Clamp(value, 0, UnityEngine.Mathf.Infinity);
             }
         }
     }
 }

Notice the [SerializeField] attribute on the _testb and _testd fields. This allows Unity to retain their values while maintaining their private accessibility. I'm still using the same custom inspector script from the question.

Also, I've cast all my 3 votes for this feature request and would like to spread the word: If you also have this problem, go there and cast some votes.

Now the only problem is how to get those fields to persist on Stop. However, since this is a solution for one piece of the problem, I'm going to mark this question answered and start a new question.

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
2

Answer by Kryptos · Apr 23, 2012 at 03:24 PM

Add this code at the end of OnInspectorGUI() in your editor class:

 if(GUI.changed)
 {
      EditorUtility.SetDirty( target );
 }

Reference: EditorUtility.SetDirty

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 Excrubulent · Apr 24, 2012 at 12:35 AM 0
Share

I was hoping it was some simple call that I had to make. Unfortunately it has no effect on the behaviour that I've described. Perhaps it's to do with the fact that I'm not changing the field directly, but ins$$anonymous$$d changing a property that sets the field?

avatar image Excrubulent · Apr 24, 2012 at 03:23 AM 1
Share

Never $$anonymous$$d, read the updated question. SetDirty still doesn't have any effect.

avatar image
0

Answer by Excrubulent · Apr 24, 2012 at 04:31 AM

Okay, half-success. Here's the updated version of TestPropertyManager that allows the property fields to persist on Play (although not on Stop):

 using UnityEngine;
 using System.Collections;
 
 public class TestPropertyManager : MonoBehaviour
 {
     public TestProperties TestManager = new TestProperties();
     
     public float TestA;
             
     public float _testb;
     public float TestB
     {
         get {return _testb;} 
         set {_testb = value;}
     }
     
     [System.Serializable]
     public class TestProperties
     {
         public float TestC;
         
         public float _testd;
         public float TestD
         {
             get{return _testd;}
             set{_testd = value;}
         }
     }
 }

Notice that TestB and TestD are accessing public fields _testb and _testd. This appears to be the only way to get Unity to not reset these fields when play is pressed. It's not ideal, because I'd like those fields to be private, but since I'm using a custom inspector, I can hide them from the inspector, which will do for now. No-one else will be using this code for the moment.

Also, I've cast all my 3 votes for this feature request and would like to spread the word: If you also have this problem, go there and cast some votes.

Now the only problem is how to get those fields to persist on Stop. However, since this is a solution for one piece of the problem, I'm going to mark this question answered and start a new question.

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 Excrubulent · Apr 24, 2012 at 05:35 AM 0
Share

I'm leaving this answer here so future forum spelunkers can see the process I went through.

avatar image
0

Answer by theLittleSettler · Jun 17, 2013 at 03:01 AM

After allot of trouble with that sort of problem this morning, I saw all I needed was to call serializedObject.Update and serializedObject.ApplyModifiedProperties at the start and end of OnInspectorGUI. It works on both Play/Stop.

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

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

C# - Doesn't Unity support Expression Bodied Properties? 3 Answers

multiple c# properties declaration 1 Answer

How to keep private variables, while being able to access them in the custom EditorWindow. 2 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