- Home /
Reflection: "Field items defined on type Inventory is not a field on the target object which is of type PartyManager"
I need to make use of dictionaries in the editor, so I made my own editable Dictionary class based on parallel lists, with it's own editor script. When I make us of this script on some string->int, string->bool, and string->string dictionaries in a component, it works fine.
However, I also have a component`PartyManager` which has a member parties
, which is a List<Party>
. Party
objects have a member inventory
, which is of type Inventory
, which wraps around a EditableDictionary<InventoryItem,int>
member called items
, where InventoryItem
is a ScriptableObject
.
When I inspect the PartyManager
object, I reciever the error "Field items defined on type Inventory is not a field on the target object which is of type PartyManager". The error points towards the function
private void InitDict(SerializedProperty dictionary) {
if (dict == null) {
dict = fieldInfo.GetValue(dictionary.serializedObject.targetObject) as EditableDictionary<TK, TV>;
}
}
dict
in this case is a member of the editor script that points to the underlying EditableDictionary
object.
How can I avoid this issue, and is there an explanation as to why this occurs only when the dictionary is under several layers of objects? My understanding is that fieldInfo
here points to the component and thus I need to find the holding object rather than the parent component.
Thanks in advance for any help.
Answer by lennardbeers · Nov 22, 2020 at 04:14 AM
@Nimja Hey, I have the exact same problem right now. Have you got anything new on this?
I also use a custom DictionaryDrawer class and have an EditorWindow that holds a reference to another Object that has a custom SerializableDictionary field, which uses the custom Drawer. If the EditorWindow tries to draw the Object containing the Dict, I get the same error, telling me that the Dictionary property wasn't found on my EditorWindow class. All of this Editor + Serialization stuff is blowing my head up right now...
If I understand correctly, we have to pass fieldInfo.GetValue() an instance of the Type of the class that contains the dictionary, which in my case would be the object stored inside of my EditorWindow class, not the window itself. The problem is, $$anonymous$$y custom Dictionary should work and draw correctly from anywhere and without drawing the whole Editor for the object containing it.
Wow, it's been a while since I last looked at this.
Basically, the solution is to make a specific editor class for Inventoryitem
keyed dictionaries, overriding InitDict()
; in this case:
internal override void InitDict(SerializedProperty dictionary) {
if (dict == null) {
Party$$anonymous$$anager party$$anonymous$$anager = dictionary.serializedObject.targetObject as Party$$anonymous$$anager;
Debug.Log(dictionary.propertyPath);
int idx = int.Parse(System.Text.RegularExpressions.Regex.$$anonymous$$atch(dictionary.propertyPath, @"\d+").Value);
Inventory holder = party$$anonymous$$anager.parties[idx].inventory;
dict = fieldInfo.GetValue(holder) as EditableDictionary<InventoryItem, int>;
}
}
Of course, this will fail if the dictionary is a member of anything that isn't a Party$$anonymous$$anager
.
Sorry that I can't be more helpful.