Search Unity

Relationship between ECS and ScriptableObject Discussion

Discussion in 'Entity Component System' started by ParadoxSolutions, Apr 2, 2018.

  1. ParadoxSolutions

    ParadoxSolutions

    Joined:
    Jul 27, 2015
    Posts:
    325
    Hello, so I'm looking for discussion about the relationship between ECS and ScriptableObject, I'm particularity interested in runtime/editor modification and serialization of Entities/Components.

    Personally I've used scriptable objects to hold lists of custom classes that define data, then through custom editors and/or UI at runtime modify the data in the ScriptableObjects. I could have a reference to the ScriptableObject in a MonoBehaviour on a GameObject instance or have multiple GameObjects use the data from one shared ScriptableObject. Overall I think this concept similar to ECS as I could use ScriptableObject assets to hold modifiable data without dependency on MonoBehavior aside from at least one GameObject that holds the reference.

    However it doesn't appear that Entities, structs, componentData are serializable in the editor at least within a ScriptableObject marked as serializable. But that doesn't mean the data isn't there, what I wonder is if I can visually modify serialized ScriptableObject properties in the inspector or though custom editors if the type isn't serializable and have some kind of instanced data structure why not be able modify entity components. I would love to see something like structs modifiable in the inspector so as to add data to entities by picking a Type and naming the variable and being able to save the component data, entity or whatever to a .asset or .cs file or some way do add/remove data other than hard coding even if it is just for visualization in the editor and not runtime.

    Other than that it will be interesting to see what people do with ECS + ScriptableObject + Editor scripting, if there is any point to connecting the systems at all, because if you are not dynamically changing anything in a ScriptableObject instance at runtime there doesn't seem to be much use for them outside of the editor if it is possible to modify a value of an entity component instance during runtime (I've not tried). I suppose it depends on your needs but I've been using SOs as runtime "Entities" for a while now.

    Maybe I just do unusually crazy things with ScripableObject or don't quite understand ECS yet, maybe I should make a code generator for entity components. Either way I'd like to hear people's thoughts on this.
     
    rakkarage likes this.
  2. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    Entity can't be directly serialized as long as it's not a real object and don't contain components, components are associated with it. At the moment i don't see any easy way to serialize it - here is my tread about it

    But there definitely must be an easy way to serialize/deserialize all data in all components of entity, both in editor and at run time, as well as possibility to construct/tweak entities stored as asset files kind of ScriptableObject
     
    ParadoxSolutions likes this.
  3. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    559
    if you know the archetype, you can define something like
    Code (CSharp):
    1. [Serializable] public struct MyBlueprintForArchetype {
    2.     public MyComponentData aComponent;
    3.     public MyOtherCompData anotherComponent;
    4.     // etc...
    5.  
    and use that for serialization. you can also have utility methods to generate the EntityArchetype from the struct definition and instantiate entities form that (like [Inject] does)

    if you don't, you can instantiate a zeroed component with Activator.CreateInstance(componentType) and fill it with JsonUtility.FromJsonOverwrite(json, obj). repeat for all components.
     
  4. ParadoxSolutions

    ParadoxSolutions

    Joined:
    Jul 27, 2015
    Posts:
    325
    Interesting I hadn't considered json, I've never tried it with structs but I suppose you would just have a class that inherits from a component data struct. I'll have to run a few tests with Json and XML.
     
  5. ParadoxSolutions

    ParadoxSolutions

    Joined:
    Jul 27, 2015
    Posts:
    325
    I found that you can serialize structs that inherit from IComponentData in a ScriptableObject or MonoBehaviour

    like this:
    Code (CSharp):
    1. [Serializable]
    2. public class SOTest : ScriptableObject
    3. {
    4.     public Test test;
    5. }
    6.  
    7. [Serializable]
    8. public struct Test : IComponentData
    9. {
    10.     public int testInt;
    11. }
    But not like this:
    Code (CSharp):
    1. [Serializable]
    2. public class SOTest : ScriptableObject
    3. {
    4.  
    5.     [Serializable]//SerializeField doesn't work either.
    6.     public struct Test : IComponentData
    7.     {
    8.         public int testInt;
    9.     }
    10. }
    11.  
    12.  
     
    hessex and Djayp like this.