Search Unity

ScriptableObject to drive Game Settings?

Discussion in 'Data Oriented Technology Stack' started by Maras, Feb 13, 2020 at 12:07 PM.

  1. Maras


    Dec 11, 2012
    I am thinking:

    If I would have a SO with some of the game settings data (for example different SO for test/easy/hard difficulty), I could add component data struct field to it if that ComponentData struct has SerializableAttribute.

    This way I could create authoring components for entities and pull that struct data from SO.

    So let's say I care about how much damage entity "Enemy" deals.

    Code (CSharp):
    1. [Serializable]
    2. struct DealsDamage: IComponentData
    3. {
    4.     public int Value;
    5. }
    DealsDamage would be just a field in a SO, Authoring component for Enemy would pull appropriate DealsDamage settings.

    This way I could have a single point where to set all data and easily change difficulty/test values.

    Are there any disadvantages to this approach (other than a bit more authoring code to write)?
    Last edited: Feb 13, 2020 at 1:33 PM
  2. JakHussain


    Oct 20, 2016
    Well, if you create an entity out of your SO data on start your enemies will each be assigned a copy of that deals damage value which is fine but a waste of memory if it's supposed to be a shared value across all enemies. instead, make the interface ISharedComponentData instead of IComponentData for better memory efficiency.

    Also, once your game settings entity it created, it looses it's connection to the SO authoring object so you can't change values on the fly. I would suggest writing an editor script which, during play mode, detects changes you make to values in the inspector of your SO, gets your world's entitymanager and updates the value in ECS land.

    I like what you're trying to do but to make it work you gotta write that extra code like you said.
    ippdev and Maras like this.
  3. ippdev


    Feb 7, 2010
    So, if I have SO for each element of say the Table of Chemical Elements and they all contain the same fields but of course different values like protonCount, paramagneticValue etc, I can set all of those as as an ISharedComponentData as all fields are the same but some fields values are different? My assumption was that it was used for components you wanted to change all at once from a single place like change mesh for all archetypes having the ISharedComponentData PlatonicSolidMeshComponent.
  4. JakHussain


    Oct 20, 2016
    Ah no for your example your assumption is correct. Its just that in the OP, their example was game settings like difficulty which is global / the same value for everything so I suggested shared component data.

    Though, for changing the value of a shared component data across all entities you will have performance problems because for each entity that gets its value changed, it gets physically moved over into a new 16kb chunk of memory for that specific value of your shared data. So updating all entities in a for each would move all those entities into a new chunk one by one. This is known as a structural change and its recommended that you do this sparingly.

    So if you need to change the difficulty of your game, probably don't do it while there 1 million enemy entities on screen. Do it from a menu scene then go back. Though that's just one way of going about it.