{"id":232,"date":"2024-10-30T12:00:00","date_gmt":"2024-10-30T12:00:00","guid":{"rendered":"https:\/\/unity3dperformance.com\/?p=232"},"modified":"2024-10-26T00:38:22","modified_gmt":"2024-10-26T00:38:22","slug":"json-vs-scriptableobjects","status":"publish","type":"post","link":"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/","title":{"rendered":"Loading Data in Unity: JSON vs ScriptableObject"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">When developing games in Unity, managing data efficiently is essential for a smooth gameplay experience. Two popular methods for handling game data are <a href=\"https:\/\/en.wikipedia.org\/wiki\/JSON\">JSON <\/a>files and <code><a href=\"https:\/\/docs.unity3d.com\/Manual\/class-ScriptableObject.html\">ScriptableObject<\/a><\/code>. In this blog post, we&#8217;ll look at the differences between these two methods, focusing on performance and ease of use. For our tests, we will load data from the <code>Resources<\/code> folder, simulating data loading at runtime.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Problem: Data Loading in Unity<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Loading data from JSON and <code>ScriptableObject<\/code> has different effects on performance. Loading data from JSON files can lead to performance spikes, especially if done frequently. In contrast, <code>ScriptableObject<\/code> is more integrated with Unity, which can improve performance and reduce overhead.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Loading Data from JSON<\/h2>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\"><strong>Implementation<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here\u2019s an example of how to load data from a JSON file in Unity:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2\"><span style=\"padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><\/span><span role=\"button\" data-code=\"using System.Collections.Generic;\nusing UnityEngine;\n\npublic class JsonDataLoader : MonoBehaviour\n{\n    private const string JSON_PATH = &quot;Jsons\/&quot;;\n    private List&lt;Data&gt; dataList = new List&lt;Data&gt;();\n\n    private TextAsset jsonFile;\n    private Data loadedData;\n\n    public void LoadJsonData()\n    {\n        for (int i = 1; i &lt;= 50; i++)\n        {\n            string path = JSON_PATH + $&quot;json {i}&quot;;\n            jsonFile = Resources.Load&lt;TextAsset&gt;(path);\n\n            if (jsonFile != null)\n            {\n                loadedData = JsonUtility.FromJson&lt;Data&gt;(jsonFile.text);\n                dataList.Add(loadedData);\n            }\n            else\n            {\n                Debug.LogWarning($&quot;JSON file not found: {path}&quot;);\n            }\n        }\n    }\n}\n\" style=\"color:#D4D4D4\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\"><code><span class=\"line\"><span style=\"color: #C586C0\">using<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">System<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Collections<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Generic<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">using<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">UnityEngine<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">class<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">JsonDataLoader<\/span><span style=\"color: #D4D4D4\"> : <\/span><span style=\"color: #4EC9B0\">MonoBehaviour<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">JSON_PATH<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&quot;Jsons\/&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">List<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">Data<\/span><span style=\"color: #D4D4D4\">&gt; <\/span><span style=\"color: #9CDCFE\">dataList<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">List<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">Data<\/span><span style=\"color: #D4D4D4\">&gt;();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">TextAsset<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">jsonFile<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Data<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">loadedData<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">void<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">LoadJsonData<\/span><span style=\"color: #D4D4D4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #569CD6\">int<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> &lt;= <\/span><span style=\"color: #B5CEA8\">50<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">++)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">path<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">JSON_PATH<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #CE9178\">$&quot;json {<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #CE9178\">}&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">jsonFile<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">Resources<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Load<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">TextAsset<\/span><span style=\"color: #D4D4D4\">&gt;(<\/span><span style=\"color: #9CDCFE\">path<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">jsonFile<\/span><span style=\"color: #D4D4D4\"> != <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">loadedData<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">JsonUtility<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">FromJson<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">Data<\/span><span style=\"color: #D4D4D4\">&gt;(<\/span><span style=\"color: #9CDCFE\">jsonFile<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">text<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">dataList<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Add<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">loadedData<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">else<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">Debug<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">LogWarning<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">$&quot;JSON file not found: {<\/span><span style=\"color: #9CDCFE\">path<\/span><span style=\"color: #CE9178\">}&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\"><strong>Profiling JSON Loading<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">While loading data from JSON, you may notice spikes in the profiler due to frequent memory allocations and parsing overhead. This can lead to frame drops if the loading process is not managed efficiently.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"538\" src=\"https:\/\/unity3dperformance.com\/wp-content\/uploads\/2024\/10\/obraz-1024x538.png\" alt=\"\" class=\"wp-image-233\" srcset=\"https:\/\/unity3dperformance.com\/wp-content\/uploads\/2024\/10\/obraz-1024x538.png 1024w, https:\/\/unity3dperformance.com\/wp-content\/uploads\/2024\/10\/obraz-300x158.png 300w, https:\/\/unity3dperformance.com\/wp-content\/uploads\/2024\/10\/obraz-768x403.png 768w, https:\/\/unity3dperformance.com\/wp-content\/uploads\/2024\/10\/obraz.png 1352w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Profiling data loading from JSON files on Honor 8 devices.<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Loading Data from ScriptableObject<\/h2>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\"><strong>Implementation<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In contrast, loading data using <code>ScriptableObject<\/code> can be done more efficiently:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2\"><span style=\"padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><\/span><span role=\"button\" data-code=\"using System.Collections.Generic;\nusing UnityEngine;\n\npublic class ScriptableObjectLoader : MonoBehaviour\n{\n    private const string SCRIPTABLE_OBJECT_DATA_PATH = &quot;ScriptableObjectData\/&quot;;\n    private List&lt;ScriptableObjectData&gt; scriptableObjectDataList = new List&lt;ScriptableObjectData&gt;();\n\n    public void LoadScriptableObjects()\n    {\n        for (int i = 1; i &lt;= 50; i++)\n        {\n            string path = SCRIPTABLE_OBJECT_DATA_PATH + $&quot;NewData {i}&quot;;\n            ScriptableObjectData loadedData = Resources.Load&lt;ScriptableObjectData&gt;(path);\n\n            if (loadedData != null)\n            {\n                scriptableObjectDataList.Add(loadedData);\n            }\n            else\n            {\n                Debug.LogWarning($&quot;ScriptableObject not found: {path}&quot;);\n            }\n        }\n    }\n}\n\" style=\"color:#D4D4D4\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\"><code><span class=\"line\"><span style=\"color: #C586C0\">using<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">System<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Collections<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Generic<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">using<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">UnityEngine<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">class<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">ScriptableObjectLoader<\/span><span style=\"color: #D4D4D4\"> : <\/span><span style=\"color: #4EC9B0\">MonoBehaviour<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">SCRIPTABLE_OBJECT_DATA_PATH<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&quot;ScriptableObjectData\/&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">List<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">ScriptableObjectData<\/span><span style=\"color: #D4D4D4\">&gt; <\/span><span style=\"color: #9CDCFE\">scriptableObjectDataList<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">List<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">ScriptableObjectData<\/span><span style=\"color: #D4D4D4\">&gt;();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">void<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">LoadScriptableObjects<\/span><span style=\"color: #D4D4D4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #569CD6\">int<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> &lt;= <\/span><span style=\"color: #B5CEA8\">50<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">++)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">path<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">SCRIPTABLE_OBJECT_DATA_PATH<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #CE9178\">$&quot;NewData {<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #CE9178\">}&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #4EC9B0\">ScriptableObjectData<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">loadedData<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">Resources<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Load<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">ScriptableObjectData<\/span><span style=\"color: #D4D4D4\">&gt;(<\/span><span style=\"color: #9CDCFE\">path<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">loadedData<\/span><span style=\"color: #D4D4D4\"> != <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">scriptableObjectDataList<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Add<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">loadedData<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">else<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">Debug<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">LogWarning<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">$&quot;ScriptableObject not found: {<\/span><span style=\"color: #9CDCFE\">path<\/span><span style=\"color: #CE9178\">}&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Profiling ScriptableObject Loading<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Loading data from ScriptableObject is faster and results in fewer garbage collection (GC) allocations, leading to smoother performance<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"538\" src=\"https:\/\/unity3dperformance.com\/wp-content\/uploads\/2024\/10\/obraz-1-1024x538.png\" alt=\"\" class=\"wp-image-234\" srcset=\"https:\/\/unity3dperformance.com\/wp-content\/uploads\/2024\/10\/obraz-1-1024x538.png 1024w, https:\/\/unity3dperformance.com\/wp-content\/uploads\/2024\/10\/obraz-1-300x158.png 300w, https:\/\/unity3dperformance.com\/wp-content\/uploads\/2024\/10\/obraz-1-768x403.png 768w, https:\/\/unity3dperformance.com\/wp-content\/uploads\/2024\/10\/obraz-1.png 1352w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Profiling data loading from ScriptableObjects on Honor 8 devices.<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Both JSON and <code>ScriptableObject<\/code> have their pros and cons when managing data in Unity. JSON offers flexibility but can create performance issues if not used carefully. In contrast, <code>ScriptableObject<\/code> integrates better with Unity and often leads to smoother performance.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For advanced data management, consider using <a href=\"https:\/\/protobuf.dev\/getting-started\/csharptutorial\/\">Protocol Buffers<\/a> (protobuf). This method provides a compact binary format for data, which can speed up loading times, especially for large datasets.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Additionally, you can package <code>ScriptableObject<\/code> into AssetBundles or addressables for efficient asset management in larger projects.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The inspiration for this blog post came from a real-world scenario where a game map created in Tiled was stored in JSON format. During testing, the map took a long time to load in WebGL builds and on mobile devices. Switching to <code>ScriptableObject<\/code> greatly improved loading times, demonstrating the benefits of this approach.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">By understanding the differences between these methods, developers can choose the best option for their projects, enhancing gameplay and user experience.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction When developing games in Unity, managing data efficiently is essential for a smooth gameplay experience. Two popular methods for handling game data are JSON files and ScriptableObject. In this blog post, we&#8217;ll look at the differences between these two methods, focusing on performance and ease of use. For our tests, we will load data [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[23,7,18],"class_list":["post-232","post","type-post","status-publish","format-standard","hentry","category-unity-optimization","tag-code-optimization","tag-memory-management","tag-unity-optimization"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v23.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Loading Data in Unity: JSON vs ScriptableObject - Unity3D Performance Blog<\/title>\n<meta name=\"description\" content=\"Meta Description: Explore the performance differences between loading data from JSON files and ScriptableObjects in Unity3D. Discover optimization techniques for better gameplay on mobile devices.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Loading Data in Unity: JSON vs ScriptableObject - Unity3D Performance Blog\" \/>\n<meta property=\"og:description\" content=\"Meta Description: Explore the performance differences between loading data from JSON files and ScriptableObjects in Unity3D. Discover optimization techniques for better gameplay on mobile devices.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/\" \/>\n<meta property=\"og:site_name\" content=\"Unity3D Performance Blog\" \/>\n<meta property=\"article:published_time\" content=\"2024-10-30T12:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-10-26T00:38:22+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/unity3dperformance.com\/wp-content\/uploads\/2024\/10\/obraz.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1352\" \/>\n\t<meta property=\"og:image:height\" content=\"710\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Rufi\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Rufi\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/\",\"url\":\"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/\",\"name\":\"Loading Data in Unity: JSON vs ScriptableObject - Unity3D Performance Blog\",\"isPartOf\":{\"@id\":\"https:\/\/unity3dperformance.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/unity3dperformance.com\/wp-content\/uploads\/2024\/10\/obraz-1024x538.png\",\"datePublished\":\"2024-10-30T12:00:00+00:00\",\"dateModified\":\"2024-10-26T00:38:22+00:00\",\"author\":{\"@id\":\"https:\/\/unity3dperformance.com\/#\/schema\/person\/1296fd7575f681c85a3afc18bf973b0c\"},\"description\":\"Meta Description: Explore the performance differences between loading data from JSON files and ScriptableObjects in Unity3D. Discover optimization techniques for better gameplay on mobile devices.\",\"breadcrumb\":{\"@id\":\"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/#primaryimage\",\"url\":\"https:\/\/unity3dperformance.com\/wp-content\/uploads\/2024\/10\/obraz.png\",\"contentUrl\":\"https:\/\/unity3dperformance.com\/wp-content\/uploads\/2024\/10\/obraz.png\",\"width\":1352,\"height\":710},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/unity3dperformance.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"JSON vs ScriptableObjects Performance Comparison\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/unity3dperformance.com\/#website\",\"url\":\"https:\/\/unity3dperformance.com\/\",\"name\":\"Unity3D Performance Blog\",\"description\":\"Discover tips and techniques to optimize your Unity3D projects for better performance and efficiency.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/unity3dperformance.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/unity3dperformance.com\/#\/schema\/person\/1296fd7575f681c85a3afc18bf973b0c\",\"name\":\"Rufi\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/unity3dperformance.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/3f1f6db23df2ef8fe5ff6875fbab10a67f1fcfef48afa45d5c00ed04d0ccf792?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/3f1f6db23df2ef8fe5ff6875fbab10a67f1fcfef48afa45d5c00ed04d0ccf792?s=96&d=mm&r=g\",\"caption\":\"Rufi\"},\"sameAs\":[\"http:\/\/unity3dperformance.com\"],\"url\":\"https:\/\/unity3dperformance.com\/index.php\/author\/admin2826\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Loading Data in Unity: JSON vs ScriptableObject - Unity3D Performance Blog","description":"Meta Description: Explore the performance differences between loading data from JSON files and ScriptableObjects in Unity3D. Discover optimization techniques for better gameplay on mobile devices.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/","og_locale":"en_US","og_type":"article","og_title":"Loading Data in Unity: JSON vs ScriptableObject - Unity3D Performance Blog","og_description":"Meta Description: Explore the performance differences between loading data from JSON files and ScriptableObjects in Unity3D. Discover optimization techniques for better gameplay on mobile devices.","og_url":"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/","og_site_name":"Unity3D Performance Blog","article_published_time":"2024-10-30T12:00:00+00:00","article_modified_time":"2024-10-26T00:38:22+00:00","og_image":[{"width":1352,"height":710,"url":"https:\/\/unity3dperformance.com\/wp-content\/uploads\/2024\/10\/obraz.png","type":"image\/png"}],"author":"Rufi","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Rufi","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/","url":"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/","name":"Loading Data in Unity: JSON vs ScriptableObject - Unity3D Performance Blog","isPartOf":{"@id":"https:\/\/unity3dperformance.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/#primaryimage"},"image":{"@id":"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/#primaryimage"},"thumbnailUrl":"https:\/\/unity3dperformance.com\/wp-content\/uploads\/2024\/10\/obraz-1024x538.png","datePublished":"2024-10-30T12:00:00+00:00","dateModified":"2024-10-26T00:38:22+00:00","author":{"@id":"https:\/\/unity3dperformance.com\/#\/schema\/person\/1296fd7575f681c85a3afc18bf973b0c"},"description":"Meta Description: Explore the performance differences between loading data from JSON files and ScriptableObjects in Unity3D. Discover optimization techniques for better gameplay on mobile devices.","breadcrumb":{"@id":"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/#primaryimage","url":"https:\/\/unity3dperformance.com\/wp-content\/uploads\/2024\/10\/obraz.png","contentUrl":"https:\/\/unity3dperformance.com\/wp-content\/uploads\/2024\/10\/obraz.png","width":1352,"height":710},{"@type":"BreadcrumbList","@id":"https:\/\/unity3dperformance.com\/index.php\/2024\/10\/30\/json-vs-scriptableobjects\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/unity3dperformance.com\/"},{"@type":"ListItem","position":2,"name":"JSON vs ScriptableObjects Performance Comparison"}]},{"@type":"WebSite","@id":"https:\/\/unity3dperformance.com\/#website","url":"https:\/\/unity3dperformance.com\/","name":"Unity3D Performance Blog","description":"Discover tips and techniques to optimize your Unity3D projects for better performance and efficiency.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/unity3dperformance.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/unity3dperformance.com\/#\/schema\/person\/1296fd7575f681c85a3afc18bf973b0c","name":"Rufi","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/unity3dperformance.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/3f1f6db23df2ef8fe5ff6875fbab10a67f1fcfef48afa45d5c00ed04d0ccf792?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/3f1f6db23df2ef8fe5ff6875fbab10a67f1fcfef48afa45d5c00ed04d0ccf792?s=96&d=mm&r=g","caption":"Rufi"},"sameAs":["http:\/\/unity3dperformance.com"],"url":"https:\/\/unity3dperformance.com\/index.php\/author\/admin2826\/"}]}},"_links":{"self":[{"href":"https:\/\/unity3dperformance.com\/index.php\/wp-json\/wp\/v2\/posts\/232","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unity3dperformance.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unity3dperformance.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unity3dperformance.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unity3dperformance.com\/index.php\/wp-json\/wp\/v2\/comments?post=232"}],"version-history":[{"count":5,"href":"https:\/\/unity3dperformance.com\/index.php\/wp-json\/wp\/v2\/posts\/232\/revisions"}],"predecessor-version":[{"id":239,"href":"https:\/\/unity3dperformance.com\/index.php\/wp-json\/wp\/v2\/posts\/232\/revisions\/239"}],"wp:attachment":[{"href":"https:\/\/unity3dperformance.com\/index.php\/wp-json\/wp\/v2\/media?parent=232"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unity3dperformance.com\/index.php\/wp-json\/wp\/v2\/categories?post=232"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unity3dperformance.com\/index.php\/wp-json\/wp\/v2\/tags?post=232"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}