- Home /
Storing pointers to interfaces to get around Unity Serialization Depth warning
I haven't implemented a save game system yet, so this might come back to bite me later (?), but i've been able to store pointers to parents in children (where those parents also have pointers to those children) by:
1) creating an Interface that amounts to "HasThisTypeOfChild"
2) making the parent use that interface
3) declaring in the interface any properties/methods I need access to in the child.
4) Then I store the parent as a "HasThisTYpeOfChild" interface in the child.
Can anyone smarter than me see a problem with this approach? (Also this is for NON-UnityEngine.Object derived classes)
(in some ways I guess this is a lazy way to get around having to send events up the hierarchy, but it seems so much simpler to for children of a one-to-one relationship to just call functions on their parents when needed. And in many cases I am just using this to access identification fields I can use when tracing out logs so I have a sense of where the child is, but occasionally its to have the child ask the parent to do actual work)
Answer by lgarczyn · Dec 28, 2019 at 08:39 PM
The best way to do this is to not serialize looping references, and to restore them on deserialization.
This is also the solution for arbitrary-depth trees, serialize them as arrays with the id of the children, and restore the tree later.
Right. A good example might be my ResourceDB system which essentially stores the file information of all assets in all resources folders including their relative path information in a scriptableobject. Since folder paths could potentially nest quite deep I actually create a linear list of resource items and just store their path as string. Each item does have a parent reference to the parent resource item, but that's not serialized. This reference is recovered from the path string during deseriaization. The ISerializationCallbackReceiver interface is quite handy for doing pre-serialization / post-deserialization logic automatically. Of course ins$$anonymous$$d of a path string you could use an int value which encodes the index of the parent item in the linear list. This requires a second step after the linear list is created during serialization to ensure all items already have an index.
That said I should point out that you can not store actual references / pointers with Unity's serialization system. The only exception are objects derived from UnityEngine.Object which are serialized as standalone assets and can be referenced. Custom serializable classes are always serialized inline like structs. No support for polymorphism! I would highly recommend to read the script serialization documentation page carefully
Way to reformulate my comment with much better information! I was indeed talking about ISerializationCallbackReceiver. But yeah, I'm not sure what kind of answer you're hoping here, since serialization and pointers don't usually match, any serialization not based on dumping RA$$anonymous$$ on the disk will have issues with complex data structures, and will require further abstraction.
There are alternatives to an index or path approach though. JSON and X$$anonymous$$L both have infinite theoretical max depth, and you could always store your data by hand. You could also serialize key-value pairs with unique ids for every nodes.
There is actually some support for polymorphism. A public/serialized var can be an interface, and you can drop prefabs/unity objects with a component implementing such interface on that var, but it's a very specific situation.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Instantiating an object from its interface 3 Answers
C# inheritance advice 2 Answers
How can I call a function of a class array from another function of a class 1 Answer