{"id":562,"date":"2016-10-23T20:17:45","date_gmt":"2016-10-23T20:17:45","guid":{"rendered":"http:\/\/magiteker.com\/?p=562"},"modified":"2016-12-11T22:21:08","modified_gmt":"2016-12-11T22:21:08","slug":"unity-design-patterns","status":"publish","type":"post","link":"https:\/\/magiteker.com\/index.php\/2016\/10\/23\/unity-design-patterns\/","title":{"rendered":"Unity Design Patterns: Scriptable Objects"},"content":{"rendered":"<p style=\"text-align: justify;\">An interesting use of Scriptable Objects within Unity as demonstrated at Unite 2016.<\/p>\n<p style=\"text-align: center;\"><iframe loading=\"lazy\" src=\"https:\/\/www.youtube.com\/embed\/VBA1QCoEAX4\" width=\"560\" height=\"315\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\">video<\/iframe><\/p>\n<h2 class=\"post-title\" style=\"text-align: center;\">Data Scriptable Object<\/h2>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nusing System;\r\nusing UnityEngine;\r\nusing System.Collections;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\n\r\n&#x5B;CreateAssetMenu]\r\npublic class DataScriptable : ScriptableObject {\r\n\r\n    public static string SavedSettingsPath\r\n    {\r\n        get\r\n        {\r\n            return System.IO.Path.Combine(Application.persistentDataPath, &quot;settings.json&quot;);\r\n        }\r\n    }\r\n\r\n    private static DataScriptable _instance;\r\n    public static DataScriptable Instance\r\n    {\r\n        get\r\n        {\r\n            if (!_instance)\r\n                _instance = Resources.FindObjectsOfTypeAll&lt;DataScriptable&gt;().FirstOrDefault();\r\n#if UNITY_EDITOR\r\n            if (!_instance)\r\n                InitializeFromDefault(UnityEditor.AssetDatabase.LoadAssetAtPath&lt;DataScriptable&gt;(&quot;Assets\/Test game settings.asset&quot;));\r\n#endif\r\n            return _instance;\r\n        }\r\n    }\r\n\r\n    \/\/\/\r\n\r\n\r\n&lt;summary&gt;\r\n    \/\/\/ Retrieves data from JSON format.\r\n    \/\/\/ &lt;\/summary&gt;\r\n\r\n\r\n\r\n    \/\/\/ &lt;param name=&quot;path&quot;&gt;&lt;\/param&gt;\r\n    public static void LoadFromJSON(string path)\r\n    {\r\n        if (!_instance)\r\n            DestroyImmediate(_instance);\r\n        JsonUtility.FromJsonOverwrite(System.IO.File.ReadAllText(path), _instance);\r\n        _instance.hideFlags = HideFlags.HideAndDontSave;\r\n    }\r\n\r\n    \/\/\/\r\n\r\n\r\n&lt;summary&gt;\r\n    \/\/\/ Object instance constructor.\r\n    \/\/\/ &lt;\/summary&gt;\r\n\r\n\r\n\r\n    \/\/\/ &lt;param name=&quot;settings&quot;&gt;&lt;\/param&gt;\r\n    public static void InitializeFromDefault(DataScriptable settings)\r\n    {\r\n        if (_instance) DestroyImmediate(_instance);\r\n        _instance = Instantiate(settings);\r\n        _instance.hideFlags = HideFlags.HideAndDontSave;\r\n    }\r\n\r\n    \/\/\/\r\n\r\n\r\n&lt;summary&gt;\r\n    \/\/\/ Store data to disk in JSON.\r\n    \/\/\/ &lt;\/summary&gt;\r\n\r\n\r\n\r\n    \/\/\/ &lt;param name=&quot;path&quot;&gt;&lt;\/param&gt;\r\n    public void SaveToJSON(string path)\r\n    {\r\n        Debug.LogFormat(&quot;Saving game settings to {0}&quot;, path);\r\n        System.IO.File.WriteAllText(path, JsonUtility.ToJson(this, true));\r\n    }\r\n\r\n    public static bool FileExists()\r\n    {\r\n        return System.IO.File.Exists(SavedSettingsPath);\r\n    }\r\n}\r\n\r\n<\/pre>\n<h2 class=\"post-title\" style=\"text-align: center;\">Data Scriptable Manager<\/h2>\n<p>&nbsp;<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nusing UnityEngine;\r\nusing System.Collections;\r\n\r\npublic class DataScriptableManager : MonoBehaviour {\r\n\r\n    public DataScriptable dataTemplate;\r\n\r\n    \/\/ Use this for initialization\r\n\tvoid Start () {\r\n\r\n        if (DataScriptable.FileExists())\r\n            DataScriptable.LoadFromJSON(DataScriptable.SavedSettingsPath);\r\n        else\r\n            DataScriptable.InitializeFromDefault(dataTemplate);\r\n\t}\r\n\t\r\n    public void Play()\r\n    {\r\n        DataScriptable.Instance.SaveToJSON(DataScriptable.SavedSettingsPath);\r\n        InstanceScriptable.CreateFromSettings(DataScriptable.Instance);\r\n\r\n    }\r\n}\r\n\r\n\r\n<\/pre>\n<hr \/>\n<h2 class=\"post-title\" style=\"text-align: center;\">Instanced Scriptable Object<\/h2>\n<p>&nbsp;<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Runtime.Remoting.Messaging;\r\nusing UnityEngine;\r\nusing UnityEngine.Assertions;\r\n\r\n&#x5B;CreateAssetMenu]\r\npublic class InstanceScriptable : ScriptableObject {\r\n\r\n    public static InstanceScriptable _instance;\r\n    public static InstanceScriptable Instance\r\n    {\r\n        get\r\n        {\r\n            if (!_instance)\r\n                _instance = Resources.FindObjectsOfTypeAll&lt;InstanceScriptable&gt;().FirstOrDefault();\r\n\r\n#if UNITY_EDITOR\r\n            if (!_instance)\r\n                CreateFromSettings(DataScriptable.Instance);\r\n#endif\r\n\r\n            return _instance;\r\n        }\r\n    }\r\n\r\n\r\n    \/\/\/\r\n\r\n\r\n&lt;summary&gt;\r\n    \/\/\/ Object instance constructor.\r\n    \/\/\/ &lt;\/summary&gt;\r\n\r\n\r\n\r\n    \/\/\/ &lt;param name=&quot;settings&quot;&gt;&lt;\/param&gt;\r\n    public static void CreateFromSettings(DataScriptable settings)\r\n    {\r\n        Assert.IsNotNull(settings);\r\n\r\n        _instance = CreateInstance&lt;InstanceScriptable&gt;();\r\n        _instance.hideFlags = HideFlags.HideAndDontSave;\r\n\r\n    }\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>An interesting use of Scriptable Objects within Unity as demonstrated at Unite 2016. video Data Scriptable Object using System; using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Linq; &#x5B;CreateAssetMenu] public class DataScriptable : ScriptableObject { public static string SavedSettingsPath { get { return System.IO.Path.Combine(Application.persistentDataPath, &quot;settings.json&quot;); } } private static DataScriptable _instance; public static DataScriptable Instance { [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":570,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[21,3,4,5],"tags":[],"class_list":["post-562","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-code","category-design_patterns","category-tools","category-tutorials"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/magiteker.com\/wp-content\/uploads\/2016\/10\/Unity_Pattern_Logo2.png?fit=1920%2C1080&ssl=1","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p6MIgq-94","jetpack-related-posts":[{"id":739,"url":"https:\/\/magiteker.com\/index.php\/2016\/12\/11\/unity-design-patterns-memory-management\/","url_meta":{"origin":562,"position":0},"title":"Unity Design Patterns: Optimization","author":"Frank O'Hanlon","date":"December 11, 2016","format":false,"excerpt":"Some low level optimizations present at Unite Los Angeles and Unite Europe 2016. Unite Los Angeles 2016 Move configuration data to Scriptable Objects. Utilize the new instantiate call when parenting an object. Don't needlessly parent objects in production. Batch changes to Transforms in order to save on transform change message\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/magiteker.com\/index.php\/category\/code\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/magiteker.com\/wp-content\/uploads\/2016\/10\/Unity_Pattern_Logo2.png?fit=1200%2C675&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/magiteker.com\/wp-content\/uploads\/2016\/10\/Unity_Pattern_Logo2.png?fit=1200%2C675&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/magiteker.com\/wp-content\/uploads\/2016\/10\/Unity_Pattern_Logo2.png?fit=1200%2C675&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/magiteker.com\/wp-content\/uploads\/2016\/10\/Unity_Pattern_Logo2.png?fit=1200%2C675&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/magiteker.com\/wp-content\/uploads\/2016\/10\/Unity_Pattern_Logo2.png?fit=1200%2C675&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":517,"url":"https:\/\/magiteker.com\/index.php\/2016\/09\/02\/unity-synthesizer\/","url_meta":{"origin":562,"position":1},"title":"Unity Audio Wave Tutorial","author":"Frank O'Hanlon","date":"September 2, 2016","format":false,"excerpt":"Games are dynamic systems responding on different types of data inputs to create interesting results for the player. One such source of data is Audio which can at its best help the player have an emotional connection to what's happening on screen. So with this in mind utilizing audio is\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/magiteker.com\/index.php\/category\/code\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/magiteker.com\/wp-content\/uploads\/2016\/09\/SynthEffect.png?fit=1154%2C418&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/magiteker.com\/wp-content\/uploads\/2016\/09\/SynthEffect.png?fit=1154%2C418&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/magiteker.com\/wp-content\/uploads\/2016\/09\/SynthEffect.png?fit=1154%2C418&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/magiteker.com\/wp-content\/uploads\/2016\/09\/SynthEffect.png?fit=1154%2C418&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/magiteker.com\/wp-content\/uploads\/2016\/09\/SynthEffect.png?fit=1154%2C418&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":355,"url":"https:\/\/magiteker.com\/index.php\/2015\/10\/23\/unity-shader-experiments\/","url_meta":{"origin":562,"position":2},"title":"Unity Shader Primer","author":"Frank O'Hanlon","date":"October 23, 2015","format":false,"excerpt":"Shaders are one of the more obscure technologies within the Unity game engine, and while the documentation covers most of the shader language and functions it fails to provide comprehensive techniques that would result in compelling graphics. They're core focus appears to be that of treating shaders as a black\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/magiteker.com\/index.php\/category\/code\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/magiteker.com\/wp-content\/uploads\/2015\/10\/shader_experiment.png?fit=822%2C463&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/magiteker.com\/wp-content\/uploads\/2015\/10\/shader_experiment.png?fit=822%2C463&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/magiteker.com\/wp-content\/uploads\/2015\/10\/shader_experiment.png?fit=822%2C463&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/magiteker.com\/wp-content\/uploads\/2015\/10\/shader_experiment.png?fit=822%2C463&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":1382,"url":"https:\/\/magiteker.com\/index.php\/2023\/06\/21\/resource-training-stable-diffusion-with-dreambooth\/","url_meta":{"origin":562,"position":3},"title":"Resource: Training Stable Diffusion with Dreambooth","author":"Frank O'Hanlon","date":"June 21, 2023","format":false,"excerpt":"-Blog Post This article describes experiments with different Learning Rates in training models using Dreambooth. FTA: Summary of Initial Results To get good results training Stable Diffusion with Dreambooth, it's important to tune the learning rate and training steps for your dataset. High learning rates and too many training steps\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/magiteker.com\/index.php\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1441,"url":"https:\/\/magiteker.com\/index.php\/2023\/07\/21\/retrieval-based-voice-conversion\/","url_meta":{"origin":562,"position":4},"title":"Retrieval Based Voice Conversion","author":"Frank O'Hanlon","date":"July 21, 2023","format":false,"excerpt":"-Github Retrieval Based Voice Conversion is a technique for analyzing speech recordings and training an AI model to emulate vocal patterns. Using this system it is possible to create text to speech models with more natural voices. These models can also be utilized to sing lyrics to songs or recite\u2026","rel":"","context":"In &quot;Stable Diffusion&quot;","block_context":{"text":"Stable Diffusion","link":"https:\/\/magiteker.com\/index.php\/category\/tutorials\/stablediffusionai\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":75,"url":"https:\/\/magiteker.com\/index.php\/2015\/09\/27\/fluid-simulation\/","url_meta":{"origin":562,"position":5},"title":"Fluid Simulation","author":"Frank O'Hanlon","date":"September 27, 2015","format":false,"excerpt":"Using cellular automata I implemented a simple fluid simulation into the Unity Engine. Each cell in this implementation represents a unit in space containing either fluid, air, or solid mass. For each frame of the simulation a calculation is made attempting to move all the fluid into a state of\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/magiteker.com\/index.php\/category\/code\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/magiteker.com\/wp-content\/uploads\/2015\/09\/fluid0.png?fit=513%2C321&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]}],"_links":{"self":[{"href":"https:\/\/magiteker.com\/index.php\/wp-json\/wp\/v2\/posts\/562","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/magiteker.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/magiteker.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/magiteker.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/magiteker.com\/index.php\/wp-json\/wp\/v2\/comments?post=562"}],"version-history":[{"count":20,"href":"https:\/\/magiteker.com\/index.php\/wp-json\/wp\/v2\/posts\/562\/revisions"}],"predecessor-version":[{"id":738,"href":"https:\/\/magiteker.com\/index.php\/wp-json\/wp\/v2\/posts\/562\/revisions\/738"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/magiteker.com\/index.php\/wp-json\/wp\/v2\/media\/570"}],"wp:attachment":[{"href":"https:\/\/magiteker.com\/index.php\/wp-json\/wp\/v2\/media?parent=562"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/magiteker.com\/index.php\/wp-json\/wp\/v2\/categories?post=562"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/magiteker.com\/index.php\/wp-json\/wp\/v2\/tags?post=562"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}