Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
4
Question by gewl · Dec 27, 2017 at 04:41 AM · serializationscriptableobjectjsonxmldata storage

What are the pros and cons of ScriptableObjects vs. JSON for data files?

I'm currently in the process of moving some data out of my MonoBehaviour classes into some data files, and I'm torn between using ScriptableObjects and just keeping JSON files that I deserialize at runtime. Could someone walk me through the use-cases for each, and whether I'm correctly understanding the benefits and drawbacks of each?


As a super broad example, say I'm using an entity-component-system. A PistolEnemy is a GameObject with a RangedAttackComponent, a MovementComponent, and a HealthComponent. A TurretEnemy is a GameObject with all the same stuff, but without a MovementComponent. A KnifeEnemy is a PistolEnemy with a MeleeAttackComponent instead of a RangedAttackComponent, etc.

I want all these entities (meaning the components that constitute them) to load data from their respective data files. In trying to think of whether to use ScriptableObjects vs JSON files, I came up with a few different approaches to what those data files actually are:


  1. Data files are ScriptableObjects containing classes that inherit from abstract data. EntityData implements 'health' and 'name', RangedMobileEntityData inherits from EntityData and implements 'range' and 'moveSpeed,' etc. Every entity has one serialized reference to its respective ScriptableObject, and components access that ScriptableObject for data. It seems like managing this inheritance could quickly get out of hand, though—if a TurretEnemy and a PistolEnemy have the same RangedAttack component, how will they know whether their data file is RangedMobileEntityData or a RangedStationaryEntityData?


  2. Much like the above, but composition over inheritance. Data classes are top-level classes that implement interfaces (like IEntity, IRangedEntity, IMobileEntity, etc.). Each component maintains its reference to its data file as an instance of whatever interface it needs. So, say that each entity has a DataReference component with a serialized reference to its ScriptableObject set in the inspector. The RangedAttackComponent retrieves this ScriptableObject and casts it to IRangedEntity for its own purposes. This solves the inheritance problem, but still seems a little wobbly to me: giving every component its own reference to the data file is a lot of redundant data, and managing all those interfaces might still be more of a headache than necessary. ThrowingKnifeComponent and RifleComponent probably have different needs—does IRangedEntity implement properties for each? Do they each get their own interface? Those concerns aren't the end of the world, but I'd rather be dedicating that energy to other parts of the project.


  3. JSON approach. EntityData is kept in a big file called EntityData.json with an entry for each individual entity. At runtime, this file is deserialized using JSONObject, and individual entities hold references to their respective data as a JSONObject, which each component then references whenever it needs to access its data. On the one hand, this is really straightforward in a way I appreciate—no messing with classes or interfaces, just plop information into a JSON Object and the components read it back. On the other hand, storing and accessing all those values via keys (i.e. strings) makes me a little nervous because of the dangers of hardcoding strings, plus having to deserialize a JSON object from a string for each entity in a scene seems much heavier than each entity having one reference to the same ScriptableObject.


Am I missing something obvious, or are these roughly the pros and cons of each approach?

Thank you!

Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image gdbjohnson3 · Apr 15, 2018 at 04:28 PM 0
Share

Another key point that trumps your questions above is about maintenance. What happens when you need to refactor your data? It seems to me that ScriptableObjects paints you in a very small corner there. 1) How does refactoring classnames work? 2) Can you change a field name or type easily? 3) What happens if you break the linkage, and accidentally save? Can you lose all the data entry you have done? In day 1 of your design, it's impossible to know how your data will evolve... how does ScriptableObjects accommodate that?

avatar image CraigGraff gdbjohnson3 · Apr 15, 2018 at 05:06 PM 0
Share

$$anonymous$$ost of your questions boil down to refactoring with Unity serialization. This is a (mostly) solved problem.

2 Replies

· Add your reply
  • Sort: 
avatar image
9
Best Answer

Answer by Firas4d · Apr 16, 2018 at 08:14 AM

Hi, ScriptableObjects are great at containing data that you want to access across the scenes at run-time, or even at edit-time without worrying about its life cycle, since they can be stored as assets in your project (they are basically the better version of the infamous singletons). They're also very useful if you want to test modifying some parameters at play mode from inspector only without losing your last changes after you exit play mode, I also use them as some sort of messaging system between MonoBehaviours. However, they fail big time at keeping the changes you make from your MonoBehaviours to the data they contain! they will reset to their original values as soon as you exit the currently open scene. Now here where JSON finds it's place! Serializing the ScriptableObject into a JSON file is mandatory if you want to use the changed values between sessions.

So In my opinion, if your goal is to only read some preset data without modifying it then go for ScriptableObjects, but if you want to read/write then use JSON serialization, optionally with a conjunction of ScriptableObjects.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image gdbjohnson3 · Apr 18, 2018 at 12:31 AM 0
Share

Ok, so I understand this better... when you want to patch the data you have in your SO hierarchy, you make the update to your SO Assets, and then serialize it to file so the data is persisted. And then on each session, you deserialize the data back into your SO when you need to use that data?

avatar image Firas4d gdbjohnson3 · Apr 18, 2018 at 06:38 AM 0
Share

Exactly, and by the way ScriptableObjects are supported bu Unity JsonUtility. Take a look at this https://youtu.be/6vmRwLYWNRo?t=1544

avatar image
8

Answer by Disastercake · Sep 27, 2018 at 04:03 PM

Recently had to decide how I wanted to store my game's enemy data. It came down to four potential options: 1. Hard coded directly into C# 2. Scriptable Objects 3. XML 4. JSON

(1) Hard coding is obviously too restrictive beyond prototyping, and (3) XML is much more bulky and slow than (4) JSON, so that left (2) ScriptableObjects and (4) JSON as alternatives. After an intrinsic analysis I concluded that JSON would be better than Scriptable Objects for my particular situation...

Re-usability Scriptable objects designed for direct use with Unity's interface and API. Trying to get their information out to other external tools requires extra steps (like serializing them to JSON). By just using JSON from the start you can easily load and save from a single file between different tools without creating conversion algorithms.

Refactoring Code If you change the name of a variable in Unity, its serialization doesn't handle this well. In most cases it will just drop all of the data that was renamed (though you can use FormallySerializedAs if you remember before the change, but that won't help if you're just trying to move that data to a different variable name and still keep the previous name). If you use something like JSON or XML, you can easily use a text editor to make immediate changes to every instance that is required.

Modding The easiest way to handle modding in games is to allow players access to your serialized, human-readable data so that they can make adjustments to it and then load it at runtime. This is not intuitively possible with Scriptable Objects without extra steps (again, like deserializing from XML or JSON).

Reliability I've not had good luck with Unity's serialization over the past 8 years of using it. I've had many issues arise during development where Unity's serialized data can become corrupted. Unity's default way to handle serialization errors is usually to drop previously corrupt serialization without error and then re-save on top of it. This means that important information can be lost. Using custom serializer plug-ins (like the late FullInspector or the recent OdinInspector) can complicate these situations further. For this reason, I approach any native serializing in Unity (like ScriptableObjects) with a great amount of caution and skepticism.

Summary My mantra is: "The best way to use Unity is to not use Unity." Meaning if you have the option to solve a problem without Unity (like by serializing your own JSON files), then that is probably the best option.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

81 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Best way to create runtime variables for Scriptable Objects?,What's the best way to create 'runtime values' for Scriptable Objects? 1 Answer

"Root Element Missing: XML Exception" when trying to load data from XML file 2 Answers

Serialize a list of scriptable objects to Json 0 Answers

PlayerPrefs v. XML File for Saving Data? 1 Answer

[SCREENSHOTS]Save scenes using XML/json descriptor 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges