Hey @vangojames ,
Thanks for dropping by, apologies for the confusion, but I didn’t have the time to explain/make a tutorial on the exact part you’re mentioning. It is very straight forward though:
public MyObjectDrawer<T> : ObjectDrawer<MyType<T>>
{
public override void OnGUI()
{
// ...
}
}
Basically, you just need to keep in mind, there are 2 types of drawers you could use: 1- Object Drawers, 2- Composite Drawers. Object drawers split to two types: ObjectDrawer and AttributeDrawer<TObject, TAttribute>
Object drawers define how an object is drawn, composite drawers just add decorations and they shouldn’t define/mess with how an object is represented. With Object drawers you get an OnGUI call to override, there, you write your GUI code. In Composite drawers however; you get OnLeftGUI, OnRightGUI, OnLowerGUI and OnUpperGUI that way you can selectively target which part of your object you want to decorate. See WhitespaceAttributeDrawer as an example.
1- If you have a certain Type T and you want to write a drawer for it such that wherever an object of that type is mentioned, your drawer will be used; you should use ObjectDrawer (ex DictionaryDrawer, ArrayDrawer, ListDrawer, etc)
2- If you have a certain Type TObject and you want to write a drawer for it such that wherever an object of that type is mentioned AND it is decorated with an attribute of type TAttribute, your drawer will be used; you should use AttributeDrawer (ex ShowTypeAttributeDrawer) (NOTE: TAttribute must inherit DrawnAttribute)
3- Now for composite drawers, you need to specify the type of object you’re targeting, and the type of attribute that way if you annotate where you shouldn’t, it just gets ignored and things won’t blow up. Say you wanted to write a composite drawer for strings, and for an attribute of type MyAttribute. (NOTE: MyAttribute should inherit CompositeAttribute)
public class MyAttributeDrawer : CompositeDrawer<string, MyAttribute>
{
// override whatever OnXXXGUI you want...
}
4- Last thing you need to keep in mind, when you use any type of drawer, you will get a strongly typed reference to what you’re targeting; that reference is dataMember; it’s basically a wrapper around fields/properties, it’s what lets you treat both equally so you don’t have to worry about whether you’re targeting a field/property (think of it as a clean SerializedProperty on steroids). dataMember.Value is the value of the object you’re targetting (strongly typed), you could just use dmValue for short. If you use CompoiteDrawer or AttributeDrawer, you also get a strongly typed reference to the attribute you’re targeting; that is “attribute”
Example usages of the drawing API is scattered all around the code base. Pretty much every drawer for every single attribute/object in the framework, uses this drawing API so if you just peek a little bit around you’ll get a decent understanding.
For serialization, it depends on what serializer you’re using, if you’re using BinaryFormatter you have to mark your type with [Serializable], if you’re using Protobuf you have to mark it with [ProtoContract] and each member you want to serialize with [ProtoMember(id)] etc. If you’re using FullSerializer you don’t need to do anything! I recommend you stick to FullSerializer, it’s the default serializer anyways. Watch the serialization video if you haven’t already, should cover most questions.
Let me know if you have more questions or if you get stuck somewhere