- Home /
FindRelativeProperty never worked for me? how does it even work?
Using serialized properties/objects is very beneficial - but I always ran away from them in editor code cause I was never able to get a non-null/legit value out of FindRelativeProperty
#-___-
Here's what I have:
FSMTrigger.cs
public class FSMTrigger : BaseTrigger, Interaction
{
public List<FSMTriggerState> states = new List<FSMTriggerState>();
// stuff...
}
FSMTriggerState.cs
public class FSMTriggerState : MonoBehaviour
{
public List<int> ints = new List<int>() { 1, 2, 3, 4, 5 }; // for testing
public List<FSMTriggerTransition> transitions = new List<FSMTriggerTransition>();
public FSMStateType stateType = FSMStateType.Other;
}
FSMTriggerTransition.cs
[ExecuteInEditMode]
public class FSMTriggerTransition : MonoBehaviour
{
[HideInInspector] public List<EventDelegate> onTransition = new List<EventDelegate>();
public FSMTriggerState toState;
// stuff...
}
For the sake of completeness:
public abstract class BaseTrigger : MonoBehaviour
{
// stuff...
}
public interface Interaction
{
void Interact(UnityEngine.GameObject actor);
}
Here's what I'm doing:
FSMTriggerEditor.cs
void Test()
{
var spStates = serializedObject.FindProperty("states");
for (int i = 0; i < spStates.arraySize; i++) {
Debug.Log("STATE TYPE: " + spStates.GetAt(i).GetValue<FSMTriggerState>().name); // <--- THIS WORKS
}
var ints = spStates.FindPropertyRelative("ints");
for (int i = 0; i < ints.arraySize; i++) {
Debug.Log("Numbers: " + ints.GetAt(i).GetValue<int>()); // THIS DOESN'T
}
var spTransitions = spStates.FindPropertyRelative("transitions");
for (int i = 0; i < spTransitions.arraySize; i++) {
Debug.Log("Transitions: " + ints.GetAt(i).GetValue<FSMTriggerTransition>().name); // NOR THIS
}
}
I wanted to make sure that the problem is NOT with the state class itself, so I went ahead and:
FSMTriggerStateEditor.cs
private void test()
{
var spTransitions = serializedObject.FindProperty("transitions");
for (int i = 0; i < spTransitions.arraySize; i++) {
Debug.Log("Transitions names: " + spTransitions.GetAt(i).GetValue<FSMTriggerTransition>().name); // THIS WORKED! SO AS THE INTS OF COURSE
}
}
So it's pretty obvious that FindRelativeProperty
isn't working right - maybe I just don't know how to use it - but I've seen a lot of scripts just reference the thing like I did - there's no special path - just the name of the variable I want to fetch. Yet it's not working with me - I get null reference exceptions. Even if I try the simplest of examples :(
Any help would be greatly appreciated - thank you very much in advance.
EDIT: There was a mistake in the test script using FindRelativeProperty
- although I fixed that, it's still giving me a null ref:
var spStates = serializedObject.FindProperty("states");
for (int i = 0; i < spStates.arraySize; i++) {
var state = spStates.GetAt(i);
Debug.Log("STATE TYPE: " + state.GetValue<FSMTriggerState>().name); // WORKS
var ints = state.FindPropertyRelative("ints");
for (int j = 0; j < ints.arraySize; j++) { // BREAKS HERE - MEANING INTS IS NULL
Debug.Log("Numbers: " + ints.GetAt(j).GetValue<int>());
}
}
EDIT:
Answer by Roland1234 · Feb 02, 2014 at 07:41 AM
Hey vexe!
I always run into issues with Unity's serialization when working on editor code. In my experience the SerializedProperty.FindPropertyRelative method is not meant to be used when the SerializedProperty is referring to a MonoBehaviour-derived object (like your FSMTriggerState object is), I've only had success using it when the object being referred to is a regular class decorated with the [Serializable] attribute.
For SerializedProperties that reference MonoBehaviours you could new up an instance of a SerializedObject passing in SerializedProperty.objectReferenceValue (if it isn't null) to the constructor, then do a regular FindProperty off of that. But in your case you're actually dealing with a List of MonoBehaviours, so you'd have to do that for each element (or else pass in the entire array, but I think that'll have unintended consequences) and may want to consider a different approach altogether. It's possible that your FSMTriggerState class shouldn't be a MonoBehaviour at all - and if it should, then you'll probably have to accomplish what you want in its own editor instead of trying to access it from another.
I hope that helps - Unity editor details really can be a pain sometimes, and the documentation really isn't as clear as it should be. Good luck though!
Thanks a lot for responding and answering me - Your approach seems to be the way to go - I haven't thought of that actually, I'll give it a go and let you know.
Holy! - IT WOR$$anonymous$$ED! newing up a SerializedObject is the solution! - THAN$$anonymous$$ YOU! +1000000000000000000000000
Wow thank you, making a new SerializedObject fixed my issue with ScriptableObjects too. http://answers.unity3d.com/questions/1188088/inspector-cant-find-field-of-scriptableobject.html#answer-1188103
$$anonymous$$aking a new SerializedObject is not the solution for my particular situation. The scriptable objects im working with have nested properties that are expandable. Creating a new instance detaches the connection of those properties from the original serializedobject meaning the expandable properties isExpand will always return false ins$$anonymous$$d of maintaining their state. Its really frustrating actually. I do feel like this is a bug. The docs have a terrible explaination of FindPropertyRelative's intention.
Answer by winxalex · Apr 06, 2016 at 07:48 AM
Same as @vexe I've list of serializedProperties in reorderable list. So If I want subproperty of those property I need private void DrawConditionsElement (Rect rect, int index, bool selected, bool focused) {
SerializedProperty eventConditionSerializedProperty = this.m_ConditionList.serializedProperty.GetArrayElementAtIndex (index);
SerializedProperty eventFieldSP=new SerializedObject(eventConditionSerializedProperty.objectReferenceValue).FindProperty("eventField");
}
public class EventCondition:ScriptableObject{
public UnityEvent eventField;
}
So not just in MonoBehavours but also in ScriptableObject FindPropertyRelative is useless. What bother me is that now I need to keep array of eventFieldSP, keep track of add remove, not to do newing every draw.
Your answer
![](https://koobas.hobune.stream/wayback/20220613132245im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Changing Inspector's Serialized Property Label (With Code Sample) 1 Answer
Change the fields on a object bound to a SerializedProperty via custom inspector? 1 Answer
Calling a method on a serialized property (Custom Editor with Reorderable List) 0 Answers
Serialized Property being uneditable in certain cases 0 Answers
Incrementing a SerializedProperty on a per-object basis 1 Answer