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
9
Question by vogles · Sep 25, 2013 at 08:13 AM · editorscriptableobjectnullserializedproperty

SerializedProperty.FindPropertyRelative returns null with ScriptableObjects

I'm trying to write some editor scripts, but I keep running into some really weird behavior for FindPropertyRelative.

Let's say I have these classes:

 [Serializable]
 public class SimpleClass : ScriptableObject
 {
     [SerializeField]
     public int myField;
 }

 public class SimpleClassBehavior : MonoBehaviour
 {
     [SerializeField]
     private SimpleClass simple;
 }

 [CustomEditor(typeof(SimpleClass))]
 public class SimpleClassEditor : Editor
 {
     public override void OnInspectorGUI()
     {
         var myField = serializedObject.FindProperty("myField");
         // This works fine
     }
 }

 [CustomEditor(typeof(SimpleClassBehavior))]
 public class SimpleClassBehaviorEditor : Editor
 {
     SerializedProperty simpleClass = null;
     SerializedProperty myField = null;
 
     void OnEnable()
     {
         simpleClass = serializedObject.FindProperty("simple");
         // This works fine
 
         myField = simpleClass.FindPropertyRelative("myField");
         // This does NOT work. This returns null 100% of the time.

         int myFieldInt = (simpleClass.objectReferenceValue as SimpleClass).myField;
         // This works perfectly, but I shouldn't have to do this.
     }
 }

I'm having an issue where calling FindPropertyRelative returns null. I know the object I'm looking for exists, because I can get it in other ways.

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

4 Replies

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

Answer by dkozar · Oct 03, 2013 at 05:23 PM

Any news on this issue?

Having similar problems (thought property is not always null, getting null sporadically).

Thanks!

EDIT: Just installed the latest Unity version (4.2.1f4) and it works. It was broken in 4.2.1.

Comment
Add comment · Show 6 · 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 vogles · Oct 03, 2013 at 11:45 PM 0
Share

I have not found a true solution. I am already using 4.2.1f4.

avatar image dkozar · Oct 03, 2013 at 11:49 PM 0
Share

Hm... what I did is I don't do a property lookup (FindPropertyRelative) within the Editor.

I created a base class for the structure I'd like to display in the editor, which has it's property drawer.

So I'm doing the lookup and rendering inside of the property drawer. This is what didn't work properly with the old Unity version.

You might want to check article on property drawers by CatlikeCoding: http://catlikecoding.com/unity/tutorials/editor/custom-data/ Great articles! $$anonymous$$ight inspire you...

avatar image dkozar · Oct 03, 2013 at 11:55 PM 0
Share

It works from $$anonymous$$onoBehaviour as well.

$$anonymous$$y $$anonymous$$onoBehaviour is having only a single property (no 'FindPropertyRelative' calls here):

 public class Your$$anonymous$$onoBehaviour: $$anonymous$$onoBehaviour
 {
     public YourClassToSerialize YourClass;
 }

There's an editor for it:

 [CanEdit$$anonymous$$ultipleObjects]
 [CustomEditor(typeof(Your$$anonymous$$onoBehaviour))]
 public class Your$$anonymous$$onoBehaviourEditor : Editor {
     private SerializedProperty GetYourClass()
     {
         return serializedObject.FindProperty("YourClass");
     }
     void OnGUI() {
         if (GUILayout.Button(new Rect(10, 10, 100, 30), "Click me") {
             SerializedProperty yourClass = GetYourClass();
             yourClass.FindPropertyRelative("yourField"); // works!
         }
     }
 }
avatar image vogles · Oct 03, 2013 at 11:56 PM 0
Share

Yeah, I actually tried using PropertyDrawers, with the same result. No matter the approach, I can only get a SerializedProperty from a SerializedObject. But I can't get a SerializedProperty from another SerializedProperty.

avatar image Neovivacity · Mar 12, 2015 at 06:09 PM 14
Share

This thread is pretty old, but in case anyone stumbles across it looking for answers like me, I solved the issue stated by vogles:

To get a SerializedProperty of a SerializedProperty, create a new SerializedObject from the the first SerializedProperty.objectReferenceValue. Then use FindProperty from that.

Example:

 SerializedProperty prop;//Your existing property
 
 SerializedObject propObj = new SerializedObject(prop.objectReferenceValue);
 
 SerializedProperty childProp = propObj.FindProperty("name");


Show more comments
avatar image
6

Answer by Hanh · May 24, 2018 at 09:51 AM

Try this one. It works for me.

    SerializedObject newserobj = new SerializedObject(serializedObject.FindProperty("scriptable").objectReferenceValue );
      EditorGUILayout.PropertyField(newserobj.FindProperty("value"));   
      newserobj.ApplyModifiedProperties();

http://answers.unity.com/answers/1188103/view.html

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
1

Answer by Glurth · Apr 19, 2018 at 04:57 PM

This has been annoying me for too long, so I wrote up a "fix" version of the FindPropertyRelative function using Neovivacity's solution. It has one important difference from the usual Unity-version of this function. It takes, as the last parameter a reference to a SerializedObject. You can start out with this value as null, and the function will create one (if needed). The important thing to remember is to apply changes to this SerializedObject, at the end of your Drawing functions.

If you spot any flaws or holes in the following, please let me know.
Sample usage:

 public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
 {

 SerializedObject so = null;
 SerializedProperty spSegements = property.FindPropertyRelativeFix("numberOfRadialSegments", ref so);
 SerializedProperty spgearInnerRadiusFraction = property.FindPropertyRelativeFix("gearInnerRadiusFraction", ref so);

 position.height = EditorGUIUtility.singleLineHeight;

 EditorGUI.PropertyField(position, spSegements);
 position.y += EditorGUI.GetPropertyHeight(spSegements);

 EditorGUI.PropertyField(position, spgearInnerRadiusFraction);
 position.y += EditorGUI.GetPropertyHeight(spgearInnerRadiusFraction);

 if (so != null)
     so.ApplyModifiedProperties();
 }

The actual fix function, and a function it uses:

  static public SerializedProperty FindPropertyRelativeFix(this SerializedProperty sp, string name, ref SerializedObject objectToApplyChanges)
         {
             SerializedProperty result;
             if (typeof(ScriptableObject).IsAssignableFrom(sp.GetFieldType()) )
             {
                 if (sp.objectReferenceValue == null) return null;
                 if (objectToApplyChanges == null)
                     objectToApplyChanges = new SerializedObject(sp.objectReferenceValue);
                 result = objectToApplyChanges.FindProperty(name);
             }
             else
             {
                 objectToApplyChanges = null;
                 result = sp.FindPropertyRelative(name);
             }
             return result;
         }
 
 
  static public System.Type GetFieldType(this SerializedProperty property)
         {
             if (property.serializedObject.targetObject == null) return null;
             System.Type parentType = property.serializedObject.targetObject.GetType();
             System.Reflection.FieldInfo fi = parentType.GetFieldViaPath(property.propertyPath);
             string path = property.propertyPath;
             if (fi == null)
                 return null;
            
             return fi.FieldType;
         }

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 Glurth · Apr 20, 2018 at 05:57 PM 0
Share

@Bunny83 Just wanted to see if the expert had any criticism/suggestions regarding this answer/solution- I feel like something is "off" serialization-wise, but I'm not sure what (works fine, for my limited tests).

avatar image
0

Answer by luislodosm · Jan 21, 2018 at 08:37 PM

So MyClass references MyScriptable that contains MyProperty. We want to access MyProperty from MyClassEditor.

...

MyClassEditor:

 SerializedProperty myScriptable = serializedObject.FindProperty("myScriptable");
 SerializedProperty myProperty = myScriptable.FindPropertyRelative("MyProperty"); // This is null 

This is my solution:

...

MyScriptableEditor:

 SerializedProperty MyProperty = myScriptable.FindProperty("MyProperty");

MyClassEditor:

 MyScriptableEditor myScriptableEditor = CreateEditor(MyScriptable) as MyScriptableEditor;
 SerializedProperty myProperty = MyScriptableEditor.myProperty;
 myProperty.serializedObject.ApplyModifiedProperties();

Warning: If you put CreateEditor in OnInspectorGUI, will cause a memory leak.

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

21 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

Related Questions

Select custom object from a list via PopUp in custom editor for ScriptableObject 0 Answers

Display Custom Inspectors for each class in a List<> 1 Answer

Null SerializedProperty SerializedObject upon Removal from list 1 Answer

How to get "name" member of a ScriptableObject, as a SerializedProperty 2 Answers

How do I associate my custom object for the serializedProperty objectReferenceValue 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