Table of Contents
Have you ever found yourself wanting to add Components to ScriptableObjects?
Or maybe hold a polymorphic list, to hold all those cool abstract effects?
Or at the very least, have different data compositions without relaying on inheritance!
Schemas is here to help! a quick, plug-and-play way to add simple data structures to your objects.
Just inherit from SchemaObject instead of ScriptableObject, and that's it! you got yourself schemas.
public class SampleObject : SchemaObject
{
}
Schemas have no dependencies and no pre-requesities, just install and start to create right away! It's completely self-contained.
- You can also install via git url by adding this entry in your manifest.json
"com.scaffold.schemas": "https://https://github.com/ScaffoldLibrary/Schemas.git"
Schemas is based on 2 main classes, the SchemaObject
and the Schema
.
The SchemaObject
is pretty much a wrapper around ScriptableObject to hold and access whatever Schema you may want. All that is needed is for your ScriptableObjects
to start Inherting from SchemaObjects
and it's good to go!
public class SampleObject : SchemaObject
{
//nothing else needed!
}
The Schema
itself is just a base class, just like all your components inherit from MonoBehaviour
. It has basically no functionality other than providing a reference/base type for the system.
There is no rules for what type of data you will put in your schema, it really is just a data-holder.
The reason we have a empty Schema
class instead of a Interface is to avoid developers trying to put MonoBehaviours or SO's as schemas, As we are leveraging unity's SerializeReference which does not support reference to those types.
public class SampleSchema : Schema
{
//any variable can go in here
}
To create a Schema
all you REALLY need to do is inherit from Schema
. It will automatically appear on the dropdown options.
Your SchemaObject
holds the reference to any schema that you may have added to it! usage is very similar to what you would experience with MonoBehaviours
MonoBehaviours:
public void SomeMethod(GameObject myObj)
{
SampleComponent component = myObj.GetComponent<SampleComponent>();
if(component != null)
{
//do something with component
}
}
Schemas:
public void SomeMethod(SchemaObject myObj)
{
SampleSchema schema = myObj.GetSchema<SampleSchema>();
if(schema != null)
{
//do something with schema
}
}
To help customize your schemas, there are 3 utility attributes
SchemaDescriptionAttribute
: Will provide a tooltip description for your schema
[SchemaDescription("Add/Subtract values from player stats while equipped")]
public class Modifiers : CardTrait
{
}
SchemaMenuGroupAttribute
: Will group your schemas on the "Add Schema" dropdown
[SchemaMenuGroup("MyGroup")]
public class Breakable : Schema
{
}
SchemaCustomDrawerAttribute
: Mark a class to be used as a custom drawer for a schema
[SchemaCustomDrawer(typeof(Modifiers))]
public class ModifierSchemaDrawer : SchemaDrawer
{
}
SchemaObjects already use a custom drawer by default, when you inherit from SchemaObjects
it will first draw all the variables of your custom object, and only draw the Schemas
in the end.
a Overridable version of SchemaObjectEditor
is being tested and should be released soon.
Through the custom inspector of SchemaObjects
, Schemas
are not drawn as any Property with a PropertyDrawer, but with a custom Drawer leveraging unity's GUILayout
and EditorGUILayout
to create a custom drawer for a Schema, you can simply create a class inheriting from SchemaDrawer
and apply the attribute:
[SchemaMenuGroup("CardTrait")]
[SchemaDescription("Add/Subtract values from player stats while equipped")]
public class Modifiers : CardTrait
{
public List<StatModifier> changes = new List<StatModifier>();
[Serializable]
public class StatModifier
{
public Stats Stat;
public int Value;
}
}
[SchemaCustomDrawer(typeof(Modifiers))]
public class ModifierSchemaDrawer : SchemaDrawer
{
public ModifierSchemaDrawer(SerializedProperty property, SchemaObjectEditor editor) : base(property, editor)
{
}
private SerializedProperty modifiersProp;
public override void UpdateSerializedProperty(SerializedProperty property)
{
base.UpdateSerializedProperty(property);
modifiersProp = property.FindPropertyRelative("changes");
}
public override void DrawBody()
{
EditorGUILayout.Space(3);
for (int i = 0; i < modifiersProp.arraySize; i++)
{
var prop = modifiersProp.GetArrayElementAtIndex(i);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PropertyField(prop.FindPropertyRelative("Stat"), GUIContent.none);
EditorGUILayout.PropertyField(prop.FindPropertyRelative("Value"), GUIContent.none);
if (GUILayout.Button("X", GUILayout.Width(30)))
{
RemoveModifier(i);
}
EditorGUILayout.EndHorizontal();
}
if (GUILayout.Button("Add"))
{
AddModifier();
}
EditorGUILayout.Space(3);
}
private void AddModifier()
{
var index = modifiersProp.arraySize;
modifiersProp.InsertArrayElementAtIndex(index);
modifiersProp.GetArrayElementAtIndex(index).boxedValue = new Modifiers.StatModifier();
Editor.Refresh();
}
private void RemoveModifier(int propIndex)
{
modifiersProp.DeleteArrayElementAtIndex(propIndex);
Editor.Refresh();
}
}
SchemaDrawer
can override a few options like the Header and Body, to create custom views:
- Multi-Editing support
- expose non-generic public methods
- Support for custom SchemaObject editors
- Better dropdown for adding schemas
- Option to filter schema options on dropdown based on type
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Distributed under the MIT License. See LICENSE.txt
for more information.
Matheus Cohen - matheuscohen@hotmail.com
Project Link: https://github.com/MgCohen/Schemas