<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Unity on Huy Minh Ha</title><link>https://minhhh.github.io/tags/unity/</link><description>Recent content in Unity on Huy Minh Ha</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Mon, 08 Jan 2018 00:00:00 +0700</lastBuildDate><atom:link href="https://minhhh.github.io/tags/unity/index.xml" rel="self" type="application/rss+xml"/><item><title>Webview with schema</title><link>https://minhhh.github.io/posts/unity-webview-with-schema/</link><pubDate>Mon, 08 Jan 2018 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-webview-with-schema/</guid><description>&lt;p&gt;The &lt;a class="link" href="https://github.com/gree/unity-webview" target="_blank" rel="noopener"
 &gt;unity-webview&lt;/a&gt; plugin is nice, but one thing is you have to call &lt;code&gt;Unity.call&lt;/code&gt; from Javascript. This is not very convenient for those who design the HTML to quickly assign action related to Unity in hyperlinks.&lt;/p&gt;
&lt;p&gt;So I added support for calling Unity function using normal links in HTML using the schema &lt;code&gt;unity://&lt;/code&gt;. For example, we can put the link: &lt;code&gt;unity://scene?param1=value1&amp;amp;param2=value2&lt;/code&gt;. When clicking this link, the string &lt;code&gt;scene?param1=value1&amp;amp;param2=value2&lt;/code&gt; will be passed to Unity, then we can use &lt;code&gt;WebViewHelper&lt;/code&gt; to parse it furthur into &lt;code&gt;scene&lt;/code&gt;, &lt;code&gt;param&lt;/code&gt;, &lt;code&gt;value1&lt;/code&gt;, &lt;code&gt;param2&lt;/code&gt;, &lt;code&gt;value2&lt;/code&gt; and so on.&lt;/p&gt;</description></item><item><title>Colored Project Folder</title><link>https://minhhh.github.io/posts/unity-colored-project-folders/</link><pubDate>Mon, 27 Nov 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-colored-project-folders/</guid><description>&lt;p&gt;&lt;a class="link" href="https://github.com/minhhh/ColoredProjectFolders" target="_blank" rel="noopener"
 &gt;ColoredProjectFolders&lt;/a&gt; is a simple plugin that color some special folders in the Project View so that you can find them more easily. It is inspired by &lt;a class="link" href="https://www.assetstore.unity3d.com/en/#!/content/50668" target="_blank" rel="noopener"
 &gt;Rainbow Folders&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s only 1 script &lt;code&gt;Assets/ColoredProjectFolder/Editor/ColoredProjectFolder.cs&lt;/code&gt;. You can modify it to add more hard-coded folder names. You can add or modify folder icons in the same folders. This could be made into a customizable setting, but I feel the usage is the same as just modifying the script directly.&lt;/p&gt;
&lt;p&gt;&lt;img alt="screenshot" class="gallery-image" data-flex-basis="311px" data-flex-grow="129" height="234" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://raw.githubusercontent.com/minhhh/ColoredProjectFolders/master/imgs/screenshot.png" width="304"&gt;&lt;/p&gt;</description></item><item><title>Test AssetBundle in Unity 2017</title><link>https://minhhh.github.io/posts/unity-test-assetbundle2017/</link><pubDate>Tue, 14 Nov 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-test-assetbundle2017/</guid><description>&lt;p&gt;With Unity 2017, we can use 2 tools to build Asset Bundle: &lt;a class="link" href="https://github.com/Unity-Technologies/AssetBundles-Browser" target="_blank" rel="noopener"
 &gt;AssetBundles-Browser&lt;/a&gt; and &lt;a class="link" href="https://github.com/unity3d-jp/AssetGraph" target="_blank" rel="noopener"
 &gt;AssetGraph&lt;/a&gt;. I&amp;rsquo;ve created a test project &lt;a class="link" href="https://github.com/minhhh/unity-test2017-assetbundle" target="_blank" rel="noopener"
 &gt;here&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="general-flow"&gt;General flow
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;Setup &lt;code&gt;Asset Bundle Graph&lt;/code&gt; to build AssetBundles&lt;/li&gt;
&lt;li&gt;Check AssetBundles with AssetBundleBrowser&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Setup Asset Bundle Graph&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The most basic setup consists of 4 nodes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Load From Directory&lt;/li&gt;
&lt;li&gt;Group By File Path&lt;/li&gt;
&lt;li&gt;Configure Bundle From Group&lt;/li&gt;
&lt;li&gt;Build Asset Bundles&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In step 1, we create a folder that represents all resources related to an entity in our system, this could be a character or an enemy NPC. In step 2 we want to create one AssetBundle for each of the sub-folders in the parent folder. Each AssetBundle represents an aspect of the entity, such as by resource types: textures, materials, animations, or by enemy types: fast, slow. Step 3 applies naming convention to the AssetBundle&amp;rsquo;s name. Step 4 is obvious, building the final asset bundles.&lt;/p&gt;
&lt;p&gt;There are 2 examples of Asset Bundle Graph (ABG) in &lt;code&gt;Assets/Tests&lt;/code&gt;: &lt;code&gt;ABG_with_regex&lt;/code&gt; and &lt;code&gt;ABG_with_wildcard&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In the &lt;code&gt;ABG_with_regex&lt;/code&gt; example, we used the pattern &lt;code&gt;/Missile\/(.*)/&lt;/code&gt;. There are several issues with this approach:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It&amp;rsquo;s not real regex since we cannot use &lt;code&gt;(.+)&lt;/code&gt; and we are forced to use &lt;code&gt;(.*)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It creates group for sub-sub-folder. For example, it creates a group named &lt;code&gt;Object/Materials&lt;/code&gt; instead of just putting it inside group &lt;code&gt;Object&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The main blocker issue is the error &lt;code&gt;Moving file failed&lt;/code&gt; when building AssetBundles&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In the &lt;code&gt;ABG_with_wildcard&lt;/code&gt; example, the group is created correctly for each of the sub-folders. There is still some issues:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We cannot have &lt;code&gt;.&lt;/code&gt; in the group name because if we do then the part after &lt;code&gt;.&lt;/code&gt; will be considered variant.&lt;/li&gt;
&lt;li&gt;We cannot have variants of sub-folder, we have to use the folder name itself as variant&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is just a rough test and obviously we require much more for an usable workflow.&lt;/p&gt;</description></item><item><title>Unity plugin USplitAlpha</title><link>https://minhhh.github.io/posts/usplitalpha/</link><pubDate>Thu, 26 Oct 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/usplitalpha/</guid><description>&lt;p&gt;Last time I discussed about Unity texture compression I&amp;rsquo;ve mentioned that using &lt;code&gt;ETC1&lt;/code&gt; + Alpha channel is the best format because it provides the best build size and memory footprint in most cases. However, Unity does not support split alpha channel for iOS. Recently I had sometime to revisit this and wrote a simple plugin to support split alpha channel on both Android and iOS devices. The plugin is called &lt;a class="link" href="https://github.com/minhhh/USplitAlpha" target="_blank" rel="noopener"
 &gt;USplitAlpha&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Apparently, the split alpha mechanism is very straightforward so different team will have different workflows that suit them best. For reference, there are some other solutions on github:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/DragonBones/DragonBoneToUnity/blob/2609886dff00bb503c1795a01aeda7481e28cbd3/Assets/Demo/_Script/Editor/SplitAlpha.cs" target="_blank" rel="noopener"
 &gt;https://github.com/DragonBones/DragonBoneToUnity/blob/2609886dff00bb503c1795a01aeda7481e28cbd3/Assets/Demo/_Script/Editor/SplitAlpha.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/TalosGame/BetterFramework/blob/3eda3261ccc582041aa5e3eaced9089dd4440f75/Assets/Editor/Compression/TextureCompression.cs" target="_blank" rel="noopener"
 &gt;https://github.com/TalosGame/BetterFramework/blob/3eda3261ccc582041aa5e3eaced9089dd4440f75/Assets/Editor/Compression/TextureCompression.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/WakakaYixixi/Unity_extension/blob/c0ba7936f96e0da77a4138249275fc1d89cdebed/Assets/Utils/Editor/SplitAlpha.cs" target="_blank" rel="noopener"
 &gt;https://github.com/WakakaYixixi/Unity_extension/blob/c0ba7936f96e0da77a4138249275fc1d89cdebed/Assets/Utils/Editor/SplitAlpha.cs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Loading Sprites dynamically in Unity</title><link>https://minhhh.github.io/posts/loading-sprites-dynamically-in-unity/</link><pubDate>Sun, 06 Aug 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/loading-sprites-dynamically-in-unity/</guid><description>&lt;p&gt;Loading sprites dynamically from code is one of the most basic tasks that we have to do. However, it seems that there&amp;rsquo;s not a standard way to to this in Unity. This guide will look at several cases of loading sprites dynamically and their solutions&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Loading a separate sprite&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Imagine you have 4 attribute icons: fire, water, earth and wind. You will have to load the correct icon for the correct character. The easiest way to do this is to put 4 icon images: fire.png, water.png, earth.png and wind.png inside a folder in &lt;code&gt;Resources&lt;/code&gt;, such as &lt;code&gt;Resources/attribute_icons/&lt;/code&gt;. Then loading a sprite is as simple as this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Sprite sprite = Resources.Load (&amp;#34;attribute_icons/fire&amp;#34;, typeof(Sprite)) as Sprite;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;In reality, we almost never do this. The reason is we need to batch drawcall, so we cannot afford to have separate drawcall for each of these small icon images. But if you put the sprites inside the &lt;code&gt;Resources&lt;/code&gt; folder, you cannot pack them with Unity&amp;rsquo;s Sprite Packer. If you put them outside of the &lt;code&gt;Resources&lt;/code&gt; folder, you cannot load them dynamically with Resources.Load. This leads to the next solutions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Packing spritesheet with external tools&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Unity has a Sprite import mode called &lt;code&gt;Multiple&lt;/code&gt;, where you can slice a Sprite atlas or Spritesheet into multiple sprites. The sprites can then be load dynamically like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;// suppose the texturesheet is in Resources/attributeicons.png
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Sprite[] sprites = Resources.LoadAll &amp;lt;Sprite&amp;gt; (&amp;#34;attributeicons&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;// Find the correct sprite to use by Sprite.name
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Obviously, you would not want to create the Sprite atlas and slice sprites by hand in a real game (not a tutorial). Therefore, you will use an external tools to create the Sprite atlas. There are several solutions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Write your own texture packer (or use an existing one you can easily find in github). Remember to export the UVs information to text, or json and copy it to Unity. In Unity, you have to write an Editor extension to slice the Sprite atlas using the Uvs information in the text/json file. I have a tool and Unity code for this but I cannot publish them due to copyright. They&amp;rsquo;re super easy to create though.&lt;/li&gt;
&lt;li&gt;Use a full solution inside Unity. You will have the original textures in Unity, then the Sprite atlas will be created inside Unity easily by dragging, dropping sprites to the tools, or some other similar method. You can try the asset &lt;a class="link" href="https://www.assetstore.unity3d.com/en/#!/content/23276" target="_blank" rel="noopener"
 &gt;SimpleSpritePacker&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;a class="link" href="https://www.codeandweb.com/texturepacker" target="_blank" rel="noopener"
 &gt;TexturePacker&lt;/a&gt;. This is the best solution since it creates much more optimized sprites. But it costs 40 dollars.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;3. Packing sprites using Unity Sprite Packer&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One big disadvantage with using external tools is that you cannot move sprites easily. If you move a sprite from one path to another, you will have to update the path in all objects that use that sprite. Using Unity sprite packer, you can do it like so:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Mark a Sprite with a packing tag&lt;/li&gt;
&lt;li&gt;Use the sprite in a GameObject or Prefab freely&lt;/li&gt;
&lt;li&gt;A spritesheet will be created by Unity automatically. The sprite will be loaded automatically from that sprite sheet.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So this is perfect, but you cannot load sprite dynamically anymore? There&amp;rsquo;re 2 solution for this problem.&lt;/p&gt;
&lt;p&gt;First, you can add all the needed sprites to whatever objects using them, then enable/disable the correct ones by code. This solution works for small projects but it does not scale.&lt;/p&gt;
&lt;p&gt;The second solution is to use a tool that automatically load all the sprites into a prefab that can be loaded dynamically in runtime. A sample of this solution is &lt;a class="link" href="https://github.com/minhhh/UBootstrap.SpriteCollection" target="_blank" rel="noopener"
 &gt;https://github.com/minhhh/UBootstrap.SpriteCollection&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="Spritecollection example" class="gallery-image" data-flex-basis="481px" data-flex-grow="200" height="422" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://raw.githubusercontent.com/minhhh/UBootstrap.SpriteCollection/master/imgs/img1.png" srcset="https://minhhh.github.io/img1_2731768920278158246_hu_dc620919e03e69d3.png 800w, https://raw.githubusercontent.com/minhhh/UBootstrap.SpriteCollection/master/imgs/img1.png 846w" width="846"&gt;&lt;/p&gt;
&lt;p&gt;Note that sometimes this option is not possible. For instance, you have to use a special material and shader, then the material might not work with Unity Sprite Packer. In one project that I worked on, we have custom SplitAlpha shaders that do not work with Unity Sprite Packer and SpriteRenderer. In those cases, you have to use solution 2.&lt;/p&gt;</description></item><item><title>Unity Asset Reference Finder and Missing Script Finder</title><link>https://minhhh.github.io/posts/unity-asset-reference-finder/</link><pubDate>Mon, 10 Jul 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-asset-reference-finder/</guid><description>&lt;p&gt;When using Unity, you often have to check which GameObject or Prefabs are using a certain image or other types of assets. There&amp;rsquo;s a convenient tool for you to check which objects are using a certain asset: &lt;a class="link" href="https://github.com/minhhh/UBootstrap.Core/blob/master/Assets/UBootstrap.Core/Plugins/EditorExtension/Editor/AssetReferencerFinder.cs" target="_blank" rel="noopener"
 &gt;AssetReferenceFinder&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Another tool called &lt;a class="link" href="https://github.com/minhhh/UBootstrap.Core/blob/master/Assets/UBootstrap.Core/Plugins/EditorExtension/Editor/MissingScriptFinder.cs" target="_blank" rel="noopener"
 &gt;MissingScriptFinder&lt;/a&gt; helps you find missing scripts in scene due to refactoring&lt;/p&gt;</description></item><item><title>Unity Prefab Best Practices</title><link>https://minhhh.github.io/posts/unity-prefabs-best-practices/</link><pubDate>Thu, 06 Jul 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-prefabs-best-practices/</guid><description>&lt;p&gt;&lt;strong&gt;Link prefabs to prefabs; do not link instances to instances&lt;/strong&gt; This is from &lt;a class="link" href="http://devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/" target="_blank" rel="noopener"
 &gt;50 Tips for Working with Unity&lt;/a&gt;
&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Use GameObject.Find to establish links between instances&lt;/strong&gt; if you have to. It&amp;rsquo;s best to not having to establish links between instances and use prebabs instead. &lt;strong&gt;Don&amp;rsquo;t&lt;/strong&gt; link instance to instance like this article suggests (&lt;a class="link" href="https://akbiggs.silvrback.com/please-stop-using-gameobject-find" target="_blank" rel="noopener"
 &gt;https://akbiggs.silvrback.com/please-stop-using-gameobject-find&lt;/a&gt;)
&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Apart from UI component, refrain from using GameObject.Find&lt;/strong&gt; because there are many better alternatives such as using interfaces, dependency injection, design patterns and so on.
&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Use Editor script to warn you of missing links in the Editor&lt;/strong&gt; like this one: &lt;a class="link" href="https://github.com/redbluegames/unity-notnullattribute" target="_blank" rel="noopener"
 &gt;https://github.com/redbluegames/unity-notnullattribute&lt;/a&gt;. However, it will not work when you use the same prefab for multiple gameplay modes, each with its own set of required component. In that case, you will have to use inheritance or duplicate code in a new component.
&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Remove prefab links from scene object&lt;/strong&gt; (&lt;a class="link" href="https://github.com/minhhh/unity-tips/blob/master/README.md#tips-using-editors" target="_blank" rel="noopener"
 &gt;https://github.com/minhhh/unity-tips/blob/master/README.md#tips-using-editors&lt;/a&gt;)
&lt;br/&gt;&lt;/p&gt;
&lt;h2 id="references"&gt;References
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="http://devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/" target="_blank" rel="noopener"
 &gt;50 Tips for Working with Unity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://akbiggs.silvrback.com/please-stop-using-gameobject-find" target="_blank" rel="noopener"
 &gt;Unity Devs, stop using GameObject.Find!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Introducing UAsync</title><link>https://minhhh.github.io/posts/uasync/</link><pubDate>Mon, 08 May 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/uasync/</guid><description>&lt;p&gt;Nowadays, if you want to use a structured way for your flow control in Unity, you basically have 4 options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Write your own &lt;code&gt;Task&lt;/code&gt; library (which might use coroutines)&lt;/li&gt;
&lt;li&gt;Use coroutines. This means that you &lt;code&gt;StartCoroutine&lt;/code&gt; in a lot of places and insert try catch code when errors occur. This works for small games. For larger games, not being able to catch nested exception is a big NO NO.&lt;/li&gt;
&lt;li&gt;Use &lt;a class="link" href="https://github.com/Real-Serious-Games/C-Sharp-Promise" target="_blank" rel="noopener"
 &gt;C-Sharp-Promise&lt;/a&gt;. If you&amp;rsquo;re familiar with JS promises, this comes natural to you. It handles exceptions pretty well. You can try combining this with coroutine, but the API is probably verbose.&lt;/li&gt;
&lt;li&gt;Use &lt;a class="link" href="https://github.com/neuecc/UniRx" target="_blank" rel="noopener"
 &gt;UniRx&lt;/a&gt;. This is simply the best choice because it supports control flow, exception handling, progress report and coroutine.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So we should always use &lt;code&gt;UniRx&lt;/code&gt;, right? Unfortunately, sometimes the efforts to use &lt;code&gt;UniRx&lt;/code&gt; is just too much that we can&amp;rsquo;t afford. In that case, it&amp;rsquo;s better to use existing solution, but with more robust code. (&lt;code&gt;C-Sharp-Promise&lt;/code&gt; is ofcourse another option, but it is not compatible with coroutine and existing coroutine code without some custom modifications).&lt;/p&gt;
&lt;p&gt;&lt;code&gt;UAsync&lt;/code&gt; &lt;a class="link" href="https://github.com/minhhh/UAsync" target="_blank" rel="noopener"
 &gt;Unity Async&lt;/a&gt; is a library that helps you write Unity code using callback style of &lt;code&gt;Node.js&lt;/code&gt; and &lt;code&gt;async&lt;/code&gt; library. The &lt;code&gt;TaskRunner&lt;/code&gt; part is taken from &lt;a class="link" href="https://github.com/sebas77/Svelto.Tasks" target="_blank" rel="noopener"
 &gt;Svelto.Tasks&lt;/a&gt; with some modifications to make it support catching exceptions and returning errors. The &lt;code&gt;UAsync&lt;/code&gt; class adds several functions on top of &lt;code&gt;TaskRunner&lt;/code&gt; to support execution of tasks in parallel or serial with returned results at the end of the execution. For the moment, it does not support &lt;code&gt;Thread&lt;/code&gt; because it focuses on control flow, not enhancing performance by distributing work to multiple cores.&lt;/p&gt;
&lt;p&gt;To include UAsync into your project, you can use &lt;code&gt;npm&lt;/code&gt; method of unity package management described &lt;a class="link" href="https://github.com/minhhh/UBootstrap" target="_blank" rel="noopener"
 &gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="usage"&gt;Usage
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;TaskRunner&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;First of all, it&amp;rsquo;s quite well-known that 2 main disadvantages of coroutine are: 1) it cannot return value and 2) it cannot handle nested exception. There&amp;rsquo;s a simple way to wrap coroutine so we can support those 2 features, as detailed in &lt;a class="link" href="http://www.zingweb.com/blog/2013/02/05/unity-coroutine-wrapper" target="_blank" rel="noopener"
 &gt;this article&lt;/a&gt;. &lt;code&gt;TaskRunner&lt;/code&gt; also supports returning value and catching exceptions using callback style. You use it like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;using UAsync;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;TaskRunner.Instance.Run (task, onComplete);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;// public TaskRoutine Run (IEnumerator task, CallbackDelegate onComplete = null)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;In the code above, &lt;code&gt;task&lt;/code&gt; is a &lt;code&gt;IEnumerator&lt;/code&gt; and &lt;code&gt;onComplete&lt;/code&gt; is a delegate of type &lt;code&gt;CallbackDelegate (object err = null, object res = null)&lt;/code&gt;. Any exceptions occur will be passed via &lt;code&gt;err&lt;/code&gt;. The last &lt;code&gt;yield&lt;/code&gt; in &lt;code&gt;task&lt;/code&gt; will be passed to &lt;code&gt;res&lt;/code&gt;. You might want to use &lt;code&gt;TaskRunner.Instance.Run&lt;/code&gt; when you have a sequence of actions to be performed in a fixed order.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UAsync&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;UAsync&lt;/code&gt; is a port of Node&amp;rsquo;s &lt;code&gt;async&lt;/code&gt; module to Unity environment. It can be used to turn a set of synchronous functions or coroutine to run sequentially or concurrently. Even though you can already run a set of tasks sequentially using coroutine, passing values between these tasks are proven to be difficult. You have to use external variables to hold the return values which creates coupling between functions, and it&amp;rsquo;s not convenient. &lt;code&gt;UAsync&lt;/code&gt; can solve this problem by allowing coroutine to return value, as well as catching exceptions if any.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s look at an example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;series&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;UAsync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Async&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Series&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SeriesFunc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FromAction&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;one&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SeriesFunc1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SeriesFunc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FromEnumerator&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;two&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SeriesFunc2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SeriesFunc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FromAction&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;three&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SeriesFunc3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;UAsyncFinalFunc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;From&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ne"&gt;Dictionary&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Debug&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Finish &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Debug&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;res &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;one&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;two&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;three&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;void&lt;/span&gt; &lt;span class="n"&gt;SeriesFunc1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CallbackDelegate&lt;/span&gt; &lt;span class="n"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ne"&gt;Dictionary&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;cb&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;IEnumerator&lt;/span&gt; &lt;span class="n"&gt;SeriesFunc2&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CallbackDelegate&lt;/span&gt; &lt;span class="n"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ne"&gt;Dictionary&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;WaitForSeconds&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;cb&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;void&lt;/span&gt; &lt;span class="n"&gt;SeriesFunc3&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CallbackDelegate&lt;/span&gt; &lt;span class="n"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ne"&gt;Dictionary&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;cb&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Here, &lt;code&gt;SeriesFunc.FromAction&lt;/code&gt; and &lt;code&gt;SeriesFunc.FromEnumerator&lt;/code&gt; are just convenient functions to wrap synchronous functions and coroutines. Each of the functions &lt;code&gt;SeriesFunc1&lt;/code&gt;, &lt;code&gt;SeriesFunc2&lt;/code&gt; and &lt;code&gt;SeriesFunc3&lt;/code&gt; will receive a callback parameter and a &lt;code&gt;res&lt;/code&gt; parameter. To complete the execution of each function, you must call &lt;code&gt;cb&lt;/code&gt; with 2 parameters: &lt;code&gt;err&lt;/code&gt; representing the error, and &lt;code&gt;result&lt;/code&gt; representing the returned value. In the code above, there is no error. If any of the code in those function throws exception, cb will also be called automatically with the exception as the first parameter.&lt;/p&gt;
&lt;p&gt;The second parameter passed to each of the functions &lt;code&gt;SeriesFunc1&lt;/code&gt;, &lt;code&gt;SeriesFunc2&lt;/code&gt; and &lt;code&gt;SeriesFunc3&lt;/code&gt; is quite important. It is a dicionary which contains all the results from previous functions, so &lt;code&gt;SeriesFunc2&lt;/code&gt; will receive result from &lt;code&gt;SeriesFunc1&lt;/code&gt;, &lt;code&gt;SeriesFunc3&lt;/code&gt; will receive results from &lt;code&gt;SeriesFunc1&lt;/code&gt; and &lt;code&gt;SeriesFunc2&lt;/code&gt;. The key of the dictionary are declared when creating the series, e.g. SeriesFunc.FromAction (&amp;ldquo;one&amp;rdquo;, SeriesFunc1) means the result of SeriesFunc1 will have key &amp;ldquo;one&amp;rdquo;. This is a powerful way to pass results between functions without creating high coupling between them.&lt;/p&gt;
&lt;p&gt;After all the functions have been executed, there is a final function &lt;code&gt;UAsyncFinalFunc&lt;/code&gt; which will receive all the results and execute some logic accordingly. If any of the functions above throws exceptions or calls callback with a &lt;code&gt;err&lt;/code&gt; parameter, the error will be passed to the final function to deal with.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;UAsync.Async.Parallel&lt;/code&gt; function is similar to the &lt;code&gt;Series&lt;/code&gt; function, except that there will be no results from previous functions since they&amp;rsquo;re executed concurrently.&lt;/p&gt;
&lt;p&gt;Finally, you can cancel a running sequence once it&amp;rsquo;s started. This is not obvious with coroutine because even though you can call &lt;code&gt;MonoBehaviour.StopCoroutine&lt;/code&gt;&lt;/p&gt;</description></item><item><title>Using Unity Assert</title><link>https://minhhh.github.io/posts/unity-assert/</link><pubDate>Tue, 25 Apr 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-assert/</guid><description>&lt;p&gt;Even though Unity&amp;rsquo;s &lt;a class="link" href="http://blog.theknightsofunity.com/unity-5-1-assertion-library/" target="_blank" rel="noopener"
 &gt;UnityEngine.Assertions&lt;/a&gt; is great, it has two major disadvantages&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We cannot extend it&lt;/li&gt;
&lt;li&gt;It does not have the concept of error code. Using error code, we can force developers to explicitly think about how they will categorize the error so it&amp;rsquo;s easier to analyze the error when the game crashes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Therefore I put together a simple script to do assertion here: &lt;a class="link" href="https://github.com/minhhh/UBootstrap.Assert" target="_blank" rel="noopener"
 &gt;https://github.com/minhhh/UBootstrap.Assert&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Our &lt;code&gt;CUSTOM_ASSERT&lt;/code&gt; class provides the almost the same interface as &lt;code&gt;UnityEngine.Assertions.Assert&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;IsTrue (bool condition, int errorCode, string message = &amp;quot;&amp;quot;, params object[] args)&lt;/code&gt; - Asserts that the condition is true.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IsFalse (bool condition, int errorCode, string message = &amp;quot;&amp;quot;, params object[] args)&lt;/code&gt; - Assert that condition is false&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IsNull (object value, int errorCode, string message = &amp;quot;&amp;quot;, params object[] args)&lt;/code&gt; - Assert that value is null.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IsNotNull (object value, int errorCode, string message = &amp;quot;&amp;quot;, params object[] args)&lt;/code&gt; - Assert that value is not null.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AreEqual&amp;lt;T&amp;gt; (T expected, T actual, int errorCode, string message = &amp;quot;&amp;quot;, params object[] args)&lt;/code&gt; - Assert that the values are equal.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AreNotEqual&amp;lt;T&amp;gt; (T expected, T actual, int errorCode, string message = &amp;quot;&amp;quot;, params object[] args)&lt;/code&gt; - Assert that the values are not equal.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AreApproximatelyEqual (float expected, float actual, int errorCode, float tolerance, string message = &amp;quot;&amp;quot;, params object[] args)&lt;/code&gt; - Asserts that the values are approximately equal. An absolute error check is used for approximate equality check (|a-b| &amp;lt; tolerance). Default tolerance is 0.00001f.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AreNotApproximatelyEqual (float expected, float actual, int errorCode, float tolerance, string message = &amp;quot;&amp;quot;, params object[] args)&lt;/code&gt; - Asserts that the values are approximately not equal. An absolute error check is used for approximate equality check (|a-b| &amp;lt; tolerance). Default tolerance is 0.00001f.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Fail (int errorCode, string message = &amp;quot;&amp;quot;, params object[] args)&lt;/code&gt; - Just fail the assertion.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The reason it&amp;rsquo;s named &lt;code&gt;CUSTOM_ASSERT&lt;/code&gt; is to make it look like a macro definition. In fact, you have to define a macro named &lt;code&gt;CUSTOM_ASSERT&lt;/code&gt; to include it in your build, similarly to the macro &lt;code&gt;UNITY_ASSERTIONS&lt;/code&gt; from Unity.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;CUSTOM_ASSERT&lt;/code&gt; class is defined as a partial class. It is expected that you define your part of the partial class, so that you can provide some default error code for common functions. You can find an example in &lt;code&gt;Assets/MY_ASSERT.cs&lt;/code&gt;. It is also recommended that you define your own sets of error codes.&lt;/p&gt;
&lt;p&gt;There is no way to include the assertion without throwing exception, because it does not make sense to assert something that does not crash the build if its not true. Those set of errors belong to a logger, not an assert utility.&lt;/p&gt;</description></item><item><title>Unity Jelly Physics</title><link>https://minhhh.github.io/posts/unity-jellyphysics/</link><pubDate>Tue, 14 Mar 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-jellyphysics/</guid><description>&lt;p&gt;There are several plugins to help creating a jelly like physics in Unity:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.assetstore.unity3d.com/en/#!/content/13327" target="_blank" rel="noopener"
 &gt;Jelly Sprites&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.assetstore.unity3d.com/en/#!/content/15685" target="_blank" rel="noopener"
 &gt;Jelly Mesh&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.assetstore.unity3d.com/en/#!/content/68777" target="_blank" rel="noopener"
 &gt;2D Soft Body&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/kwanchangnim/Jello-Physics" target="_blank" rel="noopener"
 &gt;Jello Physics&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Unity Mesh Morphing</title><link>https://minhhh.github.io/posts/unity-meshmorphing/</link><pubDate>Thu, 09 Mar 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-meshmorphing/</guid><description>&lt;p&gt;There are several ways to do mesh morphing in Unity.&lt;/p&gt;
&lt;p&gt;One way is to use a commercial plugins like &lt;a class="link" href="https://www.assetstore.unity3d.com/en/#!/content/3428" target="_blank" rel="noopener"
 &gt;Megafier&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can use a simple script to do mesh morphing as well: &lt;a class="link" href="https://github.com/minhhh/unity-meshmorphing" target="_blank" rel="noopener"
 &gt;https://github.com/minhhh/unity-meshmorphing&lt;/a&gt;. Remember to make all your mesh have the same number of vertices.&lt;/p&gt;</description></item><item><title>Unity Object Pooling</title><link>https://minhhh.github.io/posts/unity-objectpooling/</link><pubDate>Fri, 24 Feb 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-objectpooling/</guid><description>&lt;p&gt;An object pool provides an efficient way to reuse objects, and thus keep the memory foot print of all dynamically created objects within fixed bounds. This is crucial for maintianing consistent framerates in realtime games (especially on mobile), as frequent garbage collection spikes would likley lead to inconsistent performance.&lt;/p&gt;
&lt;p&gt;Implementing object pool is quite straight forward. There are several open-source solutions already so don&amp;rsquo;t bother looking into AssetStore.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/minhhh/unity-leanpool" target="_blank" rel="noopener"
 &gt;Leanpool&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/thefuntastic/unity-object-pool" target="_blank" rel="noopener"
 &gt;Unity Object Pool&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/prime31/RecyclerKit" target="_blank" rel="noopener"
 &gt;RecyclerKit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Unity Unit testing</title><link>https://minhhh.github.io/posts/unity-unittesting/</link><pubDate>Tue, 21 Feb 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-unittesting/</guid><description>&lt;p&gt;&lt;a class="link" href="https://bitbucket.org/Unity-Technologies/unitytesttools/wiki/IntegrationTestsRunner" target="_blank" rel="noopener"
 &gt;How to use the Integration Test Framework&lt;/a&gt; is the guide from offical repo&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;&lt;a class="link" href="http://ilkinulas.github.io/programming/unity/2016/03/12/integration-tests-unity3d.html" target="_blank" rel="noopener"
 &gt;Writing Integration Tests For Unity3D Projects&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Suggests writing dynamic integration test on real game scene. This might be hard to maintain if you don&amp;rsquo;t have discipline.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Property Backing Field Drawer</title><link>https://minhhh.github.io/posts/unity-property-backing-field-drawer/</link><pubDate>Tue, 14 Feb 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-property-backing-field-drawer/</guid><description>&lt;p&gt;Property is not supported by Unity Editor by default, fortunately, there is a free plugin called &lt;a class="link" href="https://www.assetstore.unity3d.com/en/#!/content/18253" target="_blank" rel="noopener"
 &gt;Property Backing Field Drawer&lt;/a&gt; that supports drawing custom editor for properties. The plugin&amp;rsquo;s code is extracted &lt;a class="link" href="https://github.com/minhhh/property-backing-field-drawer" target="_blank" rel="noopener"
 &gt;here&lt;/a&gt; for easy inclusion in your project.&lt;/p&gt;</description></item><item><title>Better Unity workflow with command line</title><link>https://minhhh.github.io/posts/unity-command-line/</link><pubDate>Thu, 02 Feb 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-command-line/</guid><description>&lt;p&gt;To do certain tasks for our game workflow, we will need to use other external tools that can only called from the command line. One way to do this is to switch back and forth between Unity and the command line, obviously this is not the best way. Our goal is to use only 1 click, or one action to execute a series of tasks in Unity and in the command line.&lt;/p&gt;
&lt;p&gt;There are 2 ways to achieve this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create an editor script and call the command line, along with other Editor scripts. This is good if you want to stay in Unity all the time.&lt;/li&gt;
&lt;li&gt;Create a command line script that call other command line scripts and some Unity scripts. This is good for continuous integration.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To launch Unity from the command line, look at these references:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://effectiveunity.com/articles/making-most-of-unitys-command-line.html" target="_blank" rel="noopener"
 &gt;Making most of Unity&amp;rsquo;s command line&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.unity3d.com/Manual/CommandLineArguments.html" target="_blank" rel="noopener"
 &gt;Command line arguments&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To run command line scripts from Unity, look at these references:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://web.archive.org/web/20170202150301/https://effectiveunity.com/articles/making-most-of-unitys-command-line.html" target="_blank" rel="noopener"
 &gt;Running command line action through C# script&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Best Practices in Persisting Player Data on Mobile</title><link>https://minhhh.github.io/posts/best-practices-in-persisting-playerdata-on-mobile/</link><pubDate>Wed, 01 Feb 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/best-practices-in-persisting-playerdata-on-mobile/</guid><description>&lt;p&gt;Original talk: &lt;a class="link" href="https://www.youtube.com/watch?v=_hAzWgQupms" target="_blank" rel="noopener"
 &gt;Unite 2016 - Best Practices in Persisting Player Data on Mobile&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Using Webp texture format in Unity</title><link>https://minhhh.github.io/posts/unity-webp/</link><pubDate>Wed, 18 Jan 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-webp/</guid><description>&lt;p&gt;Webp is a very optimized image format. It will produce smaller image size with almost the same quality as other compression format such as: &lt;code&gt;ETC2&lt;/code&gt;, &lt;code&gt;DXT5&lt;/code&gt;, &lt;code&gt;ETC1&lt;/code&gt;, &lt;code&gt;PVRTC&lt;/code&gt;. Below is some comparison between &lt;code&gt;Webp&lt;/code&gt; and popular compression format in Unity&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;512x512 Image&lt;/th&gt;
					&lt;th style="text-align: right"&gt;Size in KB&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Original&lt;/td&gt;
					&lt;td style="text-align: right"&gt;480&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;ETC1 4bits&lt;/td&gt;
					&lt;td style="text-align: right"&gt;128&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;ETC2 8bits&lt;/td&gt;
					&lt;td style="text-align: right"&gt;256&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Dxt5 Crunched&lt;/td&gt;
					&lt;td style="text-align: right"&gt;64&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;PVRTC 2 bit&lt;/td&gt;
					&lt;td style="text-align: right"&gt;64&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;PVRTC 4 bit&lt;/td&gt;
					&lt;td style="text-align: right"&gt;128&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Webp Lossless&lt;/td&gt;
					&lt;td style="text-align: right"&gt;287&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Webp Lossy 80&lt;/td&gt;
					&lt;td style="text-align: right"&gt;23&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;1024x1024 Image&lt;/th&gt;
					&lt;th style="text-align: right"&gt;Size in KB&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Original&lt;/td&gt;
					&lt;td style="text-align: right"&gt;1800&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;ETC1 4bits&lt;/td&gt;
					&lt;td style="text-align: right"&gt;512&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;ETC2 8bits&lt;/td&gt;
					&lt;td style="text-align: right"&gt;1000&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Dxt5 Crunched&lt;/td&gt;
					&lt;td style="text-align: right"&gt;183&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;PVRTC 2 bit&lt;/td&gt;
					&lt;td style="text-align: right"&gt;256&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;PVRTC 4 bit&lt;/td&gt;
					&lt;td style="text-align: right"&gt;512&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Webp Lossless&lt;/td&gt;
					&lt;td style="text-align: right"&gt;1200&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Webp Lossy 80&lt;/td&gt;
					&lt;td style="text-align: right"&gt;113&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;I&amp;rsquo;ve written a simple plugin to include Webp textures into your Unity game here: &lt;a class="link" href="https://github.com/minhhh/UBootstrap.Webp" target="_blank" rel="noopener"
 &gt;https://github.com/minhhh/UBootstrap.Webp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ref: &lt;a class="link" href="https://www.andrewmunsell.com/blog/png-vs-webp/" target="_blank" rel="noopener"
 &gt;png vs webp&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Unity package management</title><link>https://minhhh.github.io/posts/unity-package-manage/</link><pubDate>Mon, 09 Jan 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-package-manage/</guid><description>&lt;p&gt;A robust package management system is quite important when developing in Unity. People have been asking for one in the Unity &lt;a class="link" href="https://forum.unity3d.com/threads/any-robust-package-dependency-management-systems-for-unity.276329/" target="_blank" rel="noopener"
 &gt;forum&lt;/a&gt;. The following survey will list some popular options.&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://github.com/modesttree/Projeny" target="_blank" rel="noopener"
 &gt;Projeny&lt;/a&gt; The purpose of Projeny is to allow your Unity3D project to easily scale in size without heavily impacting development time. Only available in Windows&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Share any Unity assets (code, scenes, prefabs, etc.) across multiple different Unity projects without copy and pasting&lt;/li&gt;
&lt;li&gt;Instantly switch between platforms&lt;/li&gt;
&lt;li&gt;Easily upgrade or downgrade installed asset store packages&lt;/li&gt;
&lt;li&gt;Optimize compile time of your project by getting Unity to only recompile the code that changes most often&lt;/li&gt;
&lt;li&gt;Split up your project into discrete packages, so that you can manage the dependencies between each, instead of having one giant Unity project of inter-related files&lt;/li&gt;
&lt;li&gt;Declare dependencies between packages, so that you always get the packages that you need without needing to hunt down missing libraries or broken links&lt;/li&gt;
&lt;li&gt;Generate a more intelligent Visual Studio solution than the Unity default, using package dependencies to create csproj dependencies&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;a class="link" href="https://github.com/shadowmint/unity-package-template/blob/master/docs/npm.md" target="_blank" rel="noopener"
 &gt;NPM can be used to manage packages and their dependencies&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It&amp;rsquo;s very easy to use and install.&lt;/li&gt;
&lt;li&gt;Can be used with private repo&lt;/li&gt;
&lt;li&gt;Cannot distribute &lt;code&gt;.unitypackage&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;However, without using private registry, it cannot force resolve to the latest versions of all dependencies. This issue can be resolved using &lt;code&gt;yarn install --flat&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;Some people suggests &lt;a class="link" href="http://mymobiledevelopment.blogspot.com/2015/03/unity3d-package-manager.html" target="_blank" rel="noopener"
 &gt;using NuGet&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Seems can download packages correctly&lt;/li&gt;
&lt;li&gt;Have to install a central server to make it work&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;a class="link" href="http://wooga.github.io/Paket.Unity3D/" target="_blank" rel="noopener"
 &gt;Paket.Unity3D&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Same problem as nuget&lt;/li&gt;
&lt;li&gt;Seems to work better in Windows&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;a class="link" href="https://github.com/Unity-Technologies/kaizen" target="_blank" rel="noopener"
 &gt;Unity Kaizen&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Deliver packages via a central repository and zip&lt;/li&gt;
&lt;li&gt;Require more work from package maintainer&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;a class="link" href="https://bitbucket.org/Zeroto/upm" target="_blank" rel="noopener"
 &gt;UPM&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;UPM is a package manager designed to work with the Unity game engine. It allows rapid install of unity extension and assets using a command line interface. Packages support dependencies, which will be auto-downloaded when installing a package.&lt;/li&gt;
&lt;li&gt;Seems to be unmaintained&lt;/li&gt;
&lt;li&gt;No MacOS binary&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="link" href="https://github.com/appetizermonster/unity-packman" target="_blank" rel="noopener"
 &gt;unity-packman&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A command-line client to manage Unity package&lt;/li&gt;
&lt;li&gt;Does not support version and nested versions&lt;/li&gt;
&lt;li&gt;Can only export 1 directory, which is really limited&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Dither Unity textures to save memory</title><link>https://minhhh.github.io/posts/unity-dithering/</link><pubDate>Thu, 05 Jan 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-dithering/</guid><description>&lt;p&gt;The project code is here: &lt;a class="link" href="https://github.com/minhhh/unity-texture-dither" target="_blank" rel="noopener"
 &gt;https://github.com/minhhh/unity-texture-dither&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In many cases, we want to dither textures so that we can use more compact texture import format to save memory. This project aims to provide a workflow for dithering imported texture automatically, based on settings that can be swapped easily. Note that this has nothing to do with using dithering to achieve some artistic goal or the real time dithering effect to solve color banding problem.&lt;/p&gt;
&lt;p&gt;The algorithms are explained in a &lt;a class="link" href="http://www.tannerhelland.com/4660/dithering-eleven-algorithms-source-code/" target="_blank" rel="noopener"
 &gt;blog post&lt;/a&gt; by Tanner Helland and the reference implementations are taken from &lt;a class="link" href="https://github.com/mcraiha/Dithering-Unity3d" target="_blank" rel="noopener"
 &gt;https://github.com/mcraiha/Dithering-Unity3d&lt;/a&gt; with some slight modification.&lt;/p&gt;
&lt;h2 id="usage"&gt;Usage
&lt;/h2&gt;&lt;p&gt;To dither images, put them in a folder whose name ended with &lt;code&gt;Dither&lt;/code&gt;. Then click on the folder and &lt;code&gt;Reimport&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The dither setting, i.e. algorithm and output color space is defined in ScriptableObjects &lt;code&gt;DitheringAlgorithmSetting&lt;/code&gt;. You can find them in the &lt;code&gt;Assets&lt;/code&gt; folder. To change dither setting, select &lt;code&gt;Settings &amp;gt; TextureDitherSetting&lt;/code&gt; and change the field &lt;code&gt;Dither Algorithm Setting&lt;/code&gt; accordingly.&lt;/p&gt;
&lt;p&gt;Supported algorithms are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Atkinson&lt;/li&gt;
&lt;li&gt;Burkes&lt;/li&gt;
&lt;li&gt;FloydSteinberg&lt;/li&gt;
&lt;li&gt;JarvisJudiceNinke&lt;/li&gt;
&lt;li&gt;Sierra&lt;/li&gt;
&lt;li&gt;SierraLite&lt;/li&gt;
&lt;li&gt;SierraTwoRow&lt;/li&gt;
&lt;li&gt;Stucki&lt;/li&gt;
&lt;li&gt;No Dithering (for testing purpose)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Supported color spaces are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;RGBA4444&lt;/li&gt;
&lt;li&gt;Websafe&lt;/li&gt;
&lt;li&gt;TrueColor (for testing purpose)&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Using Unity Mecanim animation system</title><link>https://minhhh.github.io/posts/unity-mecanim/</link><pubDate>Mon, 02 Jan 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-mecanim/</guid><description>&lt;p&gt;See &lt;a class="link" href="https://github.com/minhhh/unity-mecanim.git" target="_blank" rel="noopener"
 &gt;unity-mecanim&lt;/a&gt; for sample code of this article&lt;/p&gt;
&lt;h2 id="mechanim-basics"&gt;Mechanim basics
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.youtube.com/watch?v=wdOk5QXYC6Y" target="_blank" rel="noopener"
 &gt;Unity 5 Tutorial - Animation Control&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.youtube.com/watch?v=7-OUZecgXv0" target="_blank" rel="noopener"
 &gt;Unity Third Person Control: Mecanim Nodes - Tutorial 5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://community.mixamo.com/hc/en-us/articles/203879268" target="_blank" rel="noopener"
 &gt;Unity: Mecanim Animation Basics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://docs.unity3d.com/Manual/animeditor-UsingAnimationEditor.html" target="_blank" rel="noopener"
 &gt;Animation Editor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://docs.unity3d.com/Manual/AnimationSoloMute.html" target="_blank" rel="noopener"
 &gt;Solo and mute&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="animation-parameters"&gt;&lt;a class="link" href="http://docs.unity3d.com/Manual/AnimationParameters.html" target="_blank" rel="noopener"
 &gt;animation parameters&lt;/a&gt;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;Animation Parameters are variables that are defined within an Animator Controller that can be accessed and assigned values from scripts. This is how a script can control or affect the flow of the state machine.&lt;/li&gt;
&lt;li&gt;Parameters can be assigned values from a script using functions in the Animator class: SetFloat, SetInt, SetBool, SetTrigger and ResetTrigger&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://answers.unity3d.com/questions/600268/mecanim-animation-parameter-types-boolean-vs-trigg.html" target="_blank" rel="noopener"
 &gt;Mecanim Animation Parameter Types: Boolean vs. Trigger&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Parameters can also be controlled in animation using Curve and read in script
&lt;ul&gt;
&lt;li&gt;You cannot control an Animation parameter from both Curve and Script, so you have to structure your code correspondingly.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="root-motion-blend-tree"&gt;Root motion, Blend Tree
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.youtube.com/watch?v=k12w-rEbuXI&amp;amp;index=1&amp;amp;list=PL_eGgISVYZkeD-q83hLtPESTB-lPKnfjH" target="_blank" rel="noopener"
 &gt;RPG Character Controller 001 - Unity 5 Root Motion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="layer-layer-mask"&gt;Layer, Layer Mask
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;Layer Usages (&lt;a class="link" href="https://unity3d.com/learn/tutorials/topics/animation/animator-controller-layers" target="_blank" rel="noopener"
 &gt;Animator Controller Layers&lt;/a&gt;)
&lt;ul&gt;
&lt;li&gt;Additional layer for handling different body parts while the base layer handles the base movement, such as: wave hand while moving&lt;/li&gt;
&lt;li&gt;Blending mode can be: Override or Additive. Normally &lt;code&gt;Override&lt;/code&gt; will be used because using &lt;code&gt;Additive&lt;/code&gt; can be highly unpredictable unless you&amp;rsquo;re an advanced animator. (&lt;a class="link" href="https://community.mixamo.com/hc/en-us/articles/204581427-Unity-Mecanim-Advanced-Animation" target="_blank" rel="noopener"
 &gt;advanced animation&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Blend additional movement based on character state such as: heavy breathing when tired&lt;/li&gt;
&lt;li&gt;Sync layer when you have a set of animation for when the character state changes such as: wounded animations&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Avatar Mask(&lt;a class="link" href="https://unity3d.com/learn/tutorials/topics/animation/avatar-masks" target="_blank" rel="noopener"
 &gt;Avatar Masks&lt;/a&gt;)
&lt;ul&gt;
&lt;li&gt;Could be set in animation to see the effect of Masking only part of the body&lt;/li&gt;
&lt;li&gt;Normally apply to layer which controls part of the body (&lt;a class="link" href="https://community.mixamo.com/hc/en-us/articles/204581427-Unity-Mecanim-Advanced-Animation" target="_blank" rel="noopener"
 &gt;advanced animation&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="equip-weapon"&gt;Equip weapon
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;Equip immediately without animation
&lt;ul&gt;
&lt;li&gt;For models created in Unity
&lt;ul&gt;
&lt;li&gt;Create weapon holder node&lt;/li&gt;
&lt;li&gt;Attach the weapons to it&lt;/li&gt;
&lt;li&gt;Hide/Unhide the correct weapon when switching weapon&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;For models created outside Unity
&lt;ul&gt;
&lt;li&gt;Find the correct node in the model OR create a weapon holder node like before&lt;/li&gt;
&lt;li&gt;Attach the weapons to it&lt;/li&gt;
&lt;li&gt;Hide/Unhide the correct weapon when switching weapon&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Equip with equip/unequip animations. All weapons are treated the same when equipped (&lt;a class="link" href="https://www.youtube.com/watch?v=7gsl43thTsk" target="_blank" rel="noopener"
 &gt;Sword equipping&lt;/a&gt;)
&lt;ul&gt;
&lt;li&gt;Create equip/unequip animation for each weapons&lt;/li&gt;
&lt;li&gt;Using layer/layer mask to blend the equip/unequip animations, masking only the necessary parts of the body, such as the arm movement&lt;/li&gt;
&lt;li&gt;Using Animation Event to set value to flags such as: sword_equipped, sword_unequipped&lt;/li&gt;
&lt;li&gt;Attach the corresponding weapon using Animation Event calling functions and/or flags&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Weapons affect whole animation when equiped (&lt;a class="link" href="https://www.youtube.com/watch?v=Is9C4i4XyXk" target="_blank" rel="noopener"
 &gt;Applied Mecanim : Character Animation and Combat State Machines&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="using-mechanim-as-state-machine"&gt;Using mechanim as state machine
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="http://forum.unity3d.com/threads/mecanim-as-generic-state-machine.311201/" target="_blank" rel="noopener"
 &gt;Mecanim as generic state machine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://pekalicious.com/blog/unity3d-reusing-animator-controllers-with-animatoroverridecontroller/" target="_blank" rel="noopener"
 &gt;Reusing animator controllers with AnimatorOverrideController&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.youtube.com/watch?v=Is9C4i4XyXk" target="_blank" rel="noopener"
 &gt;Applied Mecanim : Character Animation and Combat State Machines&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;A character with
&lt;ul&gt;
&lt;li&gt;8 weapon types
&lt;ul&gt;
&lt;li&gt;9-12 ground attacks&lt;/li&gt;
&lt;li&gt;5 aerial attacks&lt;/li&gt;
&lt;li&gt;3 defensive maneuvers&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;4 throwable items&lt;/li&gt;
&lt;li&gt;6 classes of magic each with 3-6 abilities&lt;/li&gt;
&lt;li&gt;Basic locomotion, jump, hit react, death&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;One way is to use SubStateMachine, with several depth layers&lt;/li&gt;
&lt;li&gt;An alternative organization is to use BaseLayer with Overrides Layer and Additive Layer&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.youtube.com/watch?v=HOURak6BpSo" target="_blank" rel="noopener"
 &gt;Leveraging Unity 5.2&amp;rsquo;s Advanced Animation Features&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;You can manage all transitions between attacks manually&lt;/li&gt;
&lt;li&gt;Or you can use a blend tree. This is slightly better. One problem is if you change the Blend parameter while playing animation, it will change the animation immediately.&lt;/li&gt;
&lt;li&gt;Solution in Unity 5: StateMachineBehaviour on a State. This way you can have code that run at the Start or End of your blendtree.&lt;/li&gt;
&lt;li&gt;You could also have StateMachineBehaviour on a StateMachine. Then you can override &lt;code&gt;OnStateMachineEnter&lt;/code&gt; and &lt;code&gt;OnStateMachineExit&lt;/code&gt; functions&lt;/li&gt;
&lt;li&gt;When the SubStateMachine is a sequence of animations, you can have code on &lt;code&gt;OnStateMachineEnter&lt;/code&gt; to equip weapon&lt;/li&gt;
&lt;li&gt;Can also check for Input in &lt;code&gt;StateMachineBehaviour&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="best-practices"&gt;Best Practices
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class="link" href="http://answers.unity3d.com/questions/806949/animation-events-not-firing.html" target="_blank" rel="noopener"
 &gt;Animation events not firing&lt;/a&gt; when the event is near the endframe, so either use a third party event dispatcher, or use &lt;code&gt;StateMachineBehaviour&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use custom class to cache animation event&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You might catch animation events using a general event handler function such as &lt;code&gt;OnAnimationEvent (AnimationEvent)&lt;/code&gt;, however this might not be the best solution since you will have to do a switch case in your main logic class. This will make the main logic class (e.g. Enemy, Player) knows too much about the flow to handle animation event. Also you might not be able to reuse common code.&lt;/li&gt;
&lt;li&gt;A better way is to have a generic custom class to handle animation event, e.g. &lt;code&gt;AnimatorHandler&lt;/code&gt;. This class will have most common function such as &lt;code&gt;OnAnimationStart&lt;/code&gt;, &lt;code&gt;OnAnimationEnd&lt;/code&gt;, &lt;code&gt;OnAnimationUpdate&lt;/code&gt;. You can pass custom handle functions in as callback if you need to. This class also has common utility function such as getting current state name, check if any animation is playing etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When importing animations, make sure to &lt;code&gt;Bake into pose&lt;/code&gt; the part where you don&amp;rsquo;t want to move by Root motion. Also use &lt;code&gt;Offset&lt;/code&gt; to fix Average velocity not zero problems, e.g. walking animation that has a X speed&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Change the animation speed of specific layer&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There&amp;rsquo;s no way to change the animation speed of specific layer. The current best way is to Use blend tree to control the speed of a particular layer based on parameter. See &lt;a class="link" href="http://forum.unity3d.com/threads/mecanim-change-animation-speed-of-specific-animation-or-layers.160395/" target="_blank" rel="noopener"
 &gt;Mecanim - Change animation speed of specific animation or layers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;You can also change the speed of particular state in Editor and via script&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use int parameter instead of boolean or trigger. This way you can use AnyState to transition using condition such as &lt;code&gt;skill=1&lt;/code&gt;, then when entering the mecanim state we set it to another number immediately &lt;a class="link" href="https://www.youtube.com/watch?v=Is9C4i4XyXk" target="_blank" rel="noopener"
 &gt;Applied Mecanim : Character Animation and Combat State Machines&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use substate to simplify your state machine. However, becareful when constructing AnyState transition to deeper substate, since AnyState is global. In this way, we can ignore the immediate substate and only care about the final subtate. We use the most specific condition, such as &lt;code&gt;skill=1 and subskill=2&lt;/code&gt; to trigger the final substate from AnyState. This way we don&amp;rsquo;t have to configure transition to immediate substate and only care about the final state&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use SMB: &lt;a class="link" href="https://www.youtube.com/watch?v=Is9C4i4XyXk" target="_blank" rel="noopener"
 &gt;Applied Mecanim : Character Animation and Combat State Machines&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SMB&lt;/code&gt; makes sure that &lt;code&gt;OnStateMachineExit&lt;/code&gt; is called when exiting a state. Putting a animation event at the end of an animation cannot ensure that for 2 reasons: The animation might be forced to switch in the middle or the animation event might not fire because the animation is played too quickly&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class="link" href="http://answers.unity3d.com/questions/685968/running-an-animation-completely-before-transitioni.html" target="_blank" rel="noopener"
 &gt;Running an animation completely before transitioning back&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Make sure Exit time is 1.00, with FixedDuration unchecked.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;How to Run the death animation then destroy GameObject&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use a timer. This is quite a robust solution but maybe not visually correct in some cases, i.e. the animation might be stopped too soon.&lt;/li&gt;
&lt;li&gt;Use animation event. Add an Exit event to the animation at the last frame. This is not very robust, since Unity might skip Animation event&lt;/li&gt;
&lt;li&gt;Use auto transition to a fake after death state. Then use StateMachineBehaviour to detect when we exit the Death state. This is also a robust solution, but requires you to modify the structure of the Animator.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;How to transition out of a substate machine (&lt;a class="link" href="https://www.youtube.com/watch?v=lpekqN4_4xg" target="_blank" rel="noopener"
 &gt;Using substate machine&lt;/a&gt;)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Using Up node: Transition to state or StateMachine&lt;/li&gt;
&lt;li&gt;Using Entry/Exit nodes: Transition to/from StateMachine. This facilitates better reusability&lt;/li&gt;
&lt;li&gt;Try to only use one way&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Finite state machine for Unity</title><link>https://minhhh.github.io/posts/unity-custom-fsm/</link><pubDate>Wed, 28 Dec 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-custom-fsm/</guid><description>&lt;p&gt;Finite State Machine (FSM) is an important technique in game programming. Most games that have some sort of battle will have to design an FSM for its entities. FSM can be applied in UI as well. For example, instead of using flags to enable/disable certain UI elements, we can use a full FSM for all possible states of the targetted UI and its interactions with user inputs.&lt;/p&gt;
&lt;p&gt;The main elements of a FSM include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A representation of a state&lt;/li&gt;
&lt;li&gt;A representation of a transition between 2 state&lt;/li&gt;
&lt;li&gt;A central system that hosts the states and facilitates their transitions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="link" href="https://unity3d.com/learn/tutorials/topics/scripting/using-interfaces-make-state-machine-ai" target="_blank" rel="noopener"
 &gt;Using Interfaces to Make a State Machine for AI&lt;/a&gt; has a simplest implementation of FSM. A state is represented like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;public interface IEnemyState
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; void UpdateState();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; void OnTriggerEnter (Collider other);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; void ToPatrolState();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; void ToAlertState();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; void ToChaseState();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This implementation hardcodes all state transitions in the interface, thus it&amp;rsquo;s a bad example and should not be used in a serious game.&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="http://www.voidinspace.com/2013/05/a-simple-finite-state-machine-with-c-delegates-in-unity/" target="_blank" rel="noopener"
 &gt;A simple finite state machine with C# delegates in Unity&lt;/a&gt; provides a slightly better implementation. Instead of hardcoding, it calls a single delegate function when making a transition. Still, it does not separate actions to be executed upon entering and exiting states, so it&amp;rsquo;s not very useful for serious purpose.&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="http://wiki.unity3d.com/index.php?title=Finite_State_Machine" target="_blank" rel="noopener"
 &gt;Finite State Machine&lt;/a&gt; by Unity Wiki does provide overridable functions to be executed when entering and exiting states. However, we also need to perform actions in &lt;code&gt;Update&lt;/code&gt;, &lt;code&gt;FixedUpdate&lt;/code&gt; and similar functions for entities that have time-based changes such as a player, enemies, NPC and so on. So this implementation is not sufficient.&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://github.com/thefuntastic/Unity3d-Finite-State-Machine" target="_blank" rel="noopener"
 &gt;Unity3D Finite State Machine&lt;/a&gt; satisfies functionality requirements. It provides on enter/exit functions as well as &lt;code&gt;Update&lt;/code&gt;, &lt;code&gt;FixedUpdate&lt;/code&gt;, &lt;code&gt;LateUpdate&lt;/code&gt;. It does not use separate &lt;code&gt;State&lt;/code&gt; class, instead, it uses reflection to call the correct function in the main Component for each state. Therefore, all functions of all states must be defined in the main Component, for instance, &lt;code&gt;Play_Enter&lt;/code&gt;, &lt;code&gt;Play_Exit&lt;/code&gt;, &lt;code&gt;Init_Enter&lt;/code&gt;, &lt;code&gt;Init_Exit&lt;/code&gt;, &lt;code&gt;Move_Enter&lt;/code&gt;, &lt;code&gt;Move_Exit&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;My own implementation of &lt;a class="link" href="https://github.com/minhhh/unity-fsm" target="_blank" rel="noopener"
 &gt;Finite State Machine&lt;/a&gt; is similar to the above method, except that I don&amp;rsquo;t want to use generics, since it will make it harder to refer to the &lt;code&gt;FSM&lt;/code&gt; using code.&lt;/p&gt;
&lt;p&gt;Another way to implement FSM is to make each state a separate MonoBehaviour. In this way, you can separate the functions for each state in its own file. In addition, you can examine the states in the Editor easily, like other MonoBehaviour. One issue which needs to be solved is how to access the members of the main Component. So you have to pass in the main Component to the state via constructor and make the members public. An alternative way is to write generic singletons which can be accessed from anywhere.&lt;/p&gt;
&lt;h2 id="references"&gt;References
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/thefuntastic/Unity3d-Finite-State-Machine" target="_blank" rel="noopener"
 &gt;Unity3D Finite State Machine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://wiki.unity3d.com/index.php?title=Finite_State_Machine" target="_blank" rel="noopener"
 &gt;Finite State Machine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://www.voidinspace.com/2013/05/a-simple-finite-state-machine-with-c-delegates-in-unity/" target="_blank" rel="noopener"
 &gt;A simple finite state machine with C# delegates in Unity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://unity3d.com/learn/tutorials/topics/scripting/using-interfaces-make-state-machine-ai" target="_blank" rel="noopener"
 &gt;Using Interfaces to Make a State Machine for AI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Understanding Unity Editor Extensions</title><link>https://minhhh.github.io/posts/understanding-unity-editorextensions/</link><pubDate>Thu, 22 Dec 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/understanding-unity-editorextensions/</guid><description>&lt;p&gt;Unity Editor offers many ways for extending its functionality to suit your project&amp;rsquo;s specific needs and workflow. Have a look at &lt;a class="link" href="https://github.com/minhhh/unity-editorextension-manual" target="_blank" rel="noopener"
 &gt;unity-editorextension-manual&lt;/a&gt; for a complete list of ways you can extend the Unity Editor.&lt;/p&gt;</description></item><item><title>Understanding Unity ScriptableObject</title><link>https://minhhh.github.io/posts/unity-scriptable-object/</link><pubDate>Thu, 15 Dec 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-scriptable-object/</guid><description>&lt;p&gt;In the &lt;a class="link" href="https://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/scriptable-objects" target="_blank" rel="noopener"
 &gt;Introduction to Scriptable Objects&lt;/a&gt; tutorial, they claim that &lt;code&gt;Scriptable Objects are amazing data containers&lt;/code&gt;. However, it&amp;rsquo;s not clear how useful Scriptable Objects really is, and what problems they&amp;rsquo;re trying to solve. In this article we will look at all usecases of Scriptable Objects, what issues they&amp;rsquo;re trying to solve, what the original solutions are, and what the pros and cons of each approach are.&lt;/p&gt;
&lt;h2 id="overall"&gt;Overall
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;What is a Scriptable Object&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Data Container&lt;/li&gt;
&lt;li&gt;Can NOT be attached to GameObject/Prefab&lt;/li&gt;
&lt;li&gt;Can be serialized and inspected like MonoBehaviour&lt;/li&gt;
&lt;li&gt;Can be put into .asset file&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Built into Unity&lt;/li&gt;
&lt;li&gt;Can be saved as assets&lt;/li&gt;
&lt;li&gt;Can save during runtime&lt;/li&gt;
&lt;li&gt;Can be referenced instead of copied like MonoBehaviour&lt;/li&gt;
&lt;li&gt;Internal solution (no files/parsing). Performance is quite fast.&lt;/li&gt;
&lt;li&gt;Add to structure as you go. No need to go through a large file/multiple files to replace schema.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Requires Editor Scripting&lt;/li&gt;
&lt;li&gt;Can&amp;rsquo;t edit outside Unity&lt;/li&gt;
&lt;li&gt;Can&amp;rsquo;t save once deployed&lt;/li&gt;
&lt;li&gt;Cannot optimize loading speed since this is Unity code&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="use-case-1-global-game-settings"&gt;Use case 1: Global Game Settings
&lt;/h2&gt;&lt;p&gt;Every game has global settings for various aspects such as: Sounds, Video, Game play. There are some options to store these settings:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Scattered throughout the code, or maybe centralized into one source file.
&lt;ol&gt;
&lt;li&gt;Pros: Easy to code&lt;/li&gt;
&lt;li&gt;Cons: Designers cannot find these settings easily. Change cannot persist if you quit &lt;code&gt;Play&lt;/code&gt; mode&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Stored in config files: text/binary.
&lt;ol&gt;
&lt;li&gt;Pros: Easy to code. Designers can look at them if they&amp;rsquo;re text files.&lt;/li&gt;
&lt;li&gt;Cons: Cannot change settings while playing. Might be hard for designers to understand and change the settings files since there&amp;rsquo;s no validation method.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Stored in Prefabs
&lt;ol&gt;
&lt;li&gt;Pros: Prefab can be stored as assets&lt;/li&gt;
&lt;li&gt;Cons: It might be too heavy for pure data purpose. Duplicate memory if you create instance.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;ScriptableObject can be used to store global settings in &lt;code&gt;.asset&lt;/code&gt; files.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pros
&lt;ol&gt;
&lt;li&gt;Easy to find them in Unity&lt;/li&gt;
&lt;li&gt;Easy to change and test&lt;/li&gt;
&lt;li&gt;Can change while playing. Changes persist after quitting play mode&lt;/li&gt;
&lt;li&gt;Can have custom editor so it&amp;rsquo;s easy to note the meaning of each field&lt;/li&gt;
&lt;li&gt;Can be validated using custom editor code.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Implementation&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a base class for all the global game Settings. It will have a static property &lt;code&gt;Instance&lt;/code&gt;, which provides a way to create a singleton instance in a fixed location. This location will be customized on a project basis.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;public class Setting&amp;lt;T&amp;gt; : ScriptableObject where T : Setting&amp;lt;T&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ol start="2"&gt;
&lt;li&gt;Create subclass the &lt;code&gt;Setting&lt;/code&gt; class. Provide a MenuItem for accessing it.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[MenuItem (&amp;#34;Settings/TextureSetting&amp;#34;)]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;public static void Edit ()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Selection.activeObject = Instance;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="use-case-2-swappable-global-game-settings-or-scene-settings"&gt;Use case 2: Swappable Global Game Settings or Scene Settings
&lt;/h2&gt;&lt;p&gt;Sometimes we don&amp;rsquo;t want to have to change some global settings back and forth between a set of parameters since it&amp;rsquo;s very time-consuming. So we might want to store several pre-defined settings and swap between them quickly.&lt;/p&gt;
&lt;p&gt;Another case is scene settings. These settings only affect the scene, not the whole game, and they usually change between scene reload, for instance, game mode settings: Easy, Medium, Difficult.&lt;/p&gt;
&lt;p&gt;ScriptableObject can deal with this situation:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;To be able to swap setting, create a wrapper setting which references the specific setting&lt;/li&gt;
&lt;li&gt;To swap scene setting, simply load the specific setting in &lt;code&gt;Assets&lt;/code&gt; then assign it to specific field in a &lt;code&gt;MonoBehaviour&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Implementation&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create multiple settings&lt;/li&gt;
&lt;li&gt;Define a field in &lt;code&gt;MonoBehaviour&lt;/code&gt; or parent ScriptableObject, referring to the settings ScriptableObject&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="use-case-3-scriptable-objects-as-masterdata-or-item-database"&gt;Use case 3: Scriptable Objects as MasterData or Item Database
&lt;/h2&gt;&lt;p&gt;For any sufficiently large game, the game data will be so big that you have to separate them from the code, and they will be referred to as &lt;code&gt;MasterData&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Popular solutions for storing &lt;code&gt;MasterData&lt;/code&gt; include:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Text/Binary files. E.g &lt;a class="link" href="https://www.youtube.com/watch?v=nYWlB7HRNSE" target="_blank" rel="noopener"
 &gt;Unity XML Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Database&lt;/li&gt;
&lt;li&gt;Network&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;One common disadvantage with these approach is you will need an external viewer to be able to see and modify &lt;code&gt;masterdata&lt;/code&gt; conveniently.&lt;/li&gt;
&lt;li&gt;You will have to replicate the schema in code&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;ScriptableObject can offer a way to create and edit &lt;code&gt;masterdata&lt;/code&gt; inside Unity Editor.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ScriptableObject Pros&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Can have references to Resources&lt;/li&gt;
&lt;li&gt;View, Add, Delete and Edit entities/items conveniently in Unity Editor&lt;/li&gt;
&lt;li&gt;Use ScriptableObject directly in &lt;code&gt;MonoBehaviour&lt;/code&gt; instead of having to create an additional layer of MonoBehaviour&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Implementation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/scriptable-objects" target="_blank" rel="noopener"
 &gt;Introduction to Scriptable Objects&lt;/a&gt; shows how you use Scriptable Object to create and edit Inventory Lists.&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://www.youtube.com/watch?v=ItZbTYO0Mnw" target="_blank" rel="noopener"
 &gt;Saving Data in Unity: ScriptableObjects&lt;/a&gt; shows how you can create multiple &lt;code&gt;Enemy&lt;/code&gt; ScriptableObject and use them in the &lt;code&gt;EnemyMove&lt;/code&gt; MonoBehaviour.&lt;/p&gt;
&lt;h2 id="use-case-4-scriptable-objects-as-dynamic-behaviour"&gt;Use case 4: Scriptable Objects as Dynamic Behaviour
&lt;/h2&gt;&lt;p&gt;Another usecase of ScriptableObject is using them as game behaviour which has data that can be modified by designer. They have some instance functions, like &lt;code&gt;MonoBehaviour&lt;/code&gt;, but unlike &lt;code&gt;MonoBehaviour&lt;/code&gt; which cannot be saved independently without prefabs, ScriptableObject can be saved as if they&amp;rsquo;re just pure data. Game programmers can change the code of the behaviour without affecting game designers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Implementation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;These ScriptableObjects are similar to the ones in Usecase 3, but they have functions which can act arbitrarily on &lt;code&gt;GameObject&lt;/code&gt;, &lt;code&gt;MonoBehaviour&lt;/code&gt; and so on.&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://unity3d.com/learn/tutorials/topics/scripting/ability-system-scriptable-objects?playlist=17117" target="_blank" rel="noopener"
 &gt;Ability System with Scriptable Objects&lt;/a&gt; shows how you implement an Ability System, where &lt;code&gt;Ability&lt;/code&gt; is ScriptableObject with its own behaviour functions.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Ability&lt;/code&gt; class contains data and abstracts methods which act on &lt;code&gt;GameObject&lt;/code&gt; based on those data.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;public abstract class Ability : ScriptableObject
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public string aName = &amp;#34;New Ability&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public Sprite aSprite;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public AudioClip aSound;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public float aBaseCoolDown = 1f;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public abstract void Initialize (GameObject obj);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public abstract void TriggerAbility ();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The &lt;code&gt;ProjectileAbility&lt;/code&gt; is a concrete &lt;code&gt;Ability&lt;/code&gt; subclass, which modifies the target &lt;code&gt;GameObject&lt;/code&gt; as needed and trigger the projectile action.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;using UnityEngine;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;using System.Collections;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[CreateAssetMenu (menuName = &amp;#34;Abilities/ProjectileAbility&amp;#34;)]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;public class ProjectileAbility : Ability
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public float projectileForce = 500f;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public Rigidbody projectile;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; private ProjectileShootTriggerable launcher;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public override void Initialize (GameObject obj)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; launcher = obj.GetComponent&amp;lt;ProjectileShootTriggerable&amp;gt; ();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; launcher.projectileForce = projectileForce;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; launcher.projectile = projectile;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public override void TriggerAbility ()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; launcher.Launch ();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;a class="link" href="https://bitbucket.org/richardfine/scriptableobjectdemo" target="_blank" rel="noopener"
 &gt;ScriptableObjectDemo&lt;/a&gt; is a more comprehensive demo.&lt;/p&gt;
&lt;h2 id="other-notes"&gt;Other notes
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;MasterData can include global settings, constants and any kind of game data. This really depends on the developers/designers to choose.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ScriptableObjects can help you to load some specific items in an Item Database quickly, if the items are stored as individual assets. Refactoring multiple ScriptableObject assets into a collection is simple.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Other Methods to store data&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;From source code
&lt;ol&gt;
&lt;li&gt;A lot of code for storing data&lt;/li&gt;
&lt;li&gt;Large binary size&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;From GameObject
&lt;ol&gt;
&lt;li&gt;We can store data in &lt;code&gt;Component&lt;/code&gt; inside Prefabs, or in Scene.&lt;/li&gt;
&lt;li&gt;This way is mostly heavier than ScriptableObject&lt;/li&gt;
&lt;li&gt;However, you can pack multiple &lt;code&gt;Component&lt;/code&gt; arbitrarily so it might be helpful.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;From XML, JSON, CSV, Excel
&lt;ol&gt;
&lt;li&gt;Cannot have resources reference&lt;/li&gt;
&lt;li&gt;Might be good to have a workflow to convert into ScriptableObject&lt;/li&gt;
&lt;li&gt;To update data in saved data, text/binary are more suitable than ScriptableObject, which cannot be saved once deployed.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;PlayerPrefs
&lt;ol&gt;
&lt;li&gt;Can be used to save data&lt;/li&gt;
&lt;li&gt;Not suitable for very large amount of data&lt;/li&gt;
&lt;li&gt;Cannot control the save process easily&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;From embedded DB
&lt;ol&gt;
&lt;li&gt;Cannot have resources reference&lt;/li&gt;
&lt;li&gt;Might be good to have a workflow to convert into ScriptableObject&lt;/li&gt;
&lt;li&gt;To update data in saved data, database is very convenient. But we must care about performance.&lt;/li&gt;
&lt;li&gt;We must be aware of encryption capabilities of the DB.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;From Network
&lt;ol&gt;
&lt;li&gt;Cannot have resources reference&lt;/li&gt;
&lt;li&gt;Usually used in combination with a text/binary persisted in local storage&lt;/li&gt;
&lt;li&gt;To update data via Network with ScriptableObject, AssetBundle is needed. So the general-purpose text/binary format might be better.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="references"&gt;References
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class="link" href="https://medium.com/@mormo_music/game-settings-with-scriptable-objects-in-unity3d-6f753fe508fd#.tb9ahxiej" target="_blank" rel="noopener"
 &gt;Game Settings with Scriptable Objects in Unity3D&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class="link" href="https://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/scriptable-objects" target="_blank" rel="noopener"
 &gt;Introduction to Scriptable Objects&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class="link" href="https://unity3d.com/learn/tutorials/topics/scripting/ability-system-scriptable-objects?playlist=17117" target="_blank" rel="noopener"
 &gt;Ability System with Scriptable Objects&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class="link" href="https://www.youtube.com/watch?v=ItZbTYO0Mnw" target="_blank" rel="noopener"
 &gt;Saving Data in Unity: ScriptableObjects&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class="link" href="https://www.youtube.com/watch?v=VBA1QCoEAX4" target="_blank" rel="noopener"
 &gt;Overthrowing the MonoBehaviour tyranny in a glorious ScriptableObject revolution&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class="link" href="http://tsubakit1.hateblo.jp/entry/2014/07/24/030607" target="_blank" rel="noopener"
 &gt;Scriptable Object&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class="link" href="https://bitbucket.org/richardfine/scriptableobjectdemo" target="_blank" rel="noopener"
 &gt;ScriptableObjectDemo&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class="link" href="http://ivanozanchetta.com/gamedev/unity3d/unity-serialization-behind-scriptableobject/" target="_blank" rel="noopener"
 &gt;Unity Serialization… behind the mistery of ScriptableObject&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Unity Texture compression and optimization</title><link>https://minhhh.github.io/posts/unity-texture-compression/</link><pubDate>Sat, 03 Dec 2016 00:01:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-texture-compression/</guid><description>&lt;p&gt;A common question when building Unity games is which texture compression format will be the best. The criteria are: size on disk, memory footprint, performance.&lt;/p&gt;
&lt;p&gt;We have many options in the Unity Engine: ETC1, ETC2, DXT3, DXT5, and so on. How do we choose? Let&amp;rsquo;s look at some optimization tricks to see how others choose their formats.&lt;/p&gt;
&lt;p&gt;First you need to understand &lt;a class="link" href="http://gamedev.stackexchange.com/questions/5171/how-much-memory-does-a-texture-take-up-on-the-gpu" target="_blank" rel="noopener"
 &gt;How much memory does a texture take up on the GPU?&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;many modern engines opt to store the same format on disk as they do in memory, leading to files that are the same size as the texture&amp;rsquo;s memory requirements&lt;/li&gt;
&lt;li&gt;Uncompresed image of 256x256 is 256KB. A DXT1 image of 256x256 is 32KB. And DXT3 or DXT5 is 64KB&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://mainroach.blogspot.com/2014/03/the-png-vs-gpu-battle-on-android.html" target="_blank" rel="noopener"
 &gt;http://mainroach.blogspot.com/2014/03/the-png-vs-gpu-battle-on-android.html&lt;/a&gt; also explains why you don&amp;rsquo;t want to use plain &lt;code&gt;png&lt;/code&gt; textures. Instead, export them to &lt;code&gt;DXT1&lt;/code&gt;, &lt;code&gt;PVR&lt;/code&gt; or &lt;code&gt;ETC&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="link" href="https://web.archive.org/web/20160826092252/http://android-developers.blogspot.com/2015/01/efficient-game-textures-with-hardware.html" target="_blank" rel="noopener"
 &gt;Efficient Game Textures with Hardware Compression&lt;/a&gt; examines preferable compression formats which are supported on the GPU to help you reduce .apk size and loading times of your game:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As you can see, with higher OpenGL support you gain access to better formats. There are proprietary formats to replace ETC1, delivering higher quality and alpha channel support. These are shown in the following table:
&lt;ul&gt;
&lt;li&gt;ATC	Available with Adreno GPU.&lt;/li&gt;
&lt;li&gt;PVRTC	Available with a PowerVR GPU.&lt;/li&gt;
&lt;li&gt;DXT1	S3 DXT1 texture compression. Supported on devices running Nvidia Tegra platform.&lt;/li&gt;
&lt;li&gt;S3TC	S3 texture compression, nonspecific to DXT variant. Supported on devices running Nvidia Tegra platform.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Using hardware accelerated textures in your games will help you reduce the size of your .apk, runtime memory use as well as loading times.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="link" href="https://web.archive.org/web/20160507141202/http://biobeasts.artix.com/unity-2d-texture-optimization/" target="_blank" rel="noopener"
 &gt;Unity 2D Texture Optimization&lt;/a&gt; explains how they group textures by type instead of logical groups to save memory:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2048x2048 sprite sheet above, even with compression applied, took up 4mb in Texture2D memory&lt;/li&gt;
&lt;li&gt;assets fail to render and appear like black shapes&lt;/li&gt;
&lt;li&gt;organize sprite sheets into three compression types: Solids, Fades, and Alpha Punchouts.&lt;/li&gt;
&lt;li&gt;Solids are any rectangular assets with NO alpha. Here we can get a major savings by selecting a 4-bit compression that doesn&amp;rsquo;t support alpha.&lt;/li&gt;
&lt;li&gt;Alpha Punchouts are any other shapes that use binary alpha, meaning the area of the image is either 100% or 0% alpha. Here we select a 5-bit compression&lt;/li&gt;
&lt;li&gt;Fades are reserved for our most complex objects that contain variable degrees of alpha. We use these sparingly and compress them using a minimum of 8-bit RGBA to look best.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="link" href="https://web.archive.org/web/20160513225925/http://forum.unity3d.com/threads/etc1-vs-etc2-texture-compression.219842/" target="_blank" rel="noopener"
 &gt;ETC1 vs ETC2 vs DXT5&lt;/a&gt; discuss which is the best texture format&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ETC2 only for devices supporting ES 3.0&lt;/li&gt;
&lt;li&gt;But if your targeting all devices&amp;hellip; which u should consider doing in 2015, then it doesnt matter if you pick ETC2 or DXT5 Crunched because theyre both getting decompressed. Which makes sense for ARGB. And then for RGB just ETC1&lt;/li&gt;
&lt;li&gt;Most devices support ETC1 &lt;a class="link" href="http://developer.android.com/guide/topics/graphics/opengl.html#textures" target="_blank" rel="noopener"
 &gt;http://developer.android.com/guide/topics/graphics/opengl.html#textures&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;I was able to remove 25% of my file size this weekend, thanks to switching to ETC1 + DXT5 Crunched&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="link" href="https://web.archive.org/web/20150610061237/https://software.intel.com/en-us/articles/android-texture-compression-a-comparison-study-with-code-sample" target="_blank" rel="noopener"
 &gt;Android Texture Compression - a comparison study with code sample&lt;/a&gt; compares the quality and sizes of different formats on Android devices including: &lt;code&gt;png, etc, etc2, pvrtc and s3tc&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://web.archive.org/web/20160513225136/http://forum.unity3d.com/threads/etc2-as-default-texture-compression-on-android.348582/" target="_blank" rel="noopener"
 &gt;ETC2 as default texture compression on Android&lt;/a&gt; discuss usage of ETC2 format&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We use DXT5 on our sprites to save space on apk file. When the device does not support your texture type, Unity uses software decompression on load and your textures become 32bit RGBA.&lt;/li&gt;
&lt;li&gt;Use ETC2 to save memory. It might be bad for some low-spec device if they don&amp;rsquo;t support ETC2. Also one more reason to pack your own sheets instead of using Unity packer, since you can do dithering yourself&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some texture optimization recommendations&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Don&amp;rsquo;t use mipmap for 2D &lt;a class="link" href="https://web.archive.org/web/20160422114629/http://forum.unity3d.com/threads/is-it-possible-to-turn-on-mip-maps-for-a-sprite.219054/" target="_blank" rel="noopener"
 &gt;Is it possible to turn on Mip Maps for a sprite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Compress your textures to DXT1 or DXT5 &lt;a class="link" href="https://web.archive.org/web/20160428065248/http://forum.unity3d.com/threads/tips-and-tricks-make-sure-to-profile-your-phone-apps-memory-usage.202952/" target="_blank" rel="noopener"
 &gt;Memory optimization tricks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://web.archive.org/web/20160520084556/http://forum.unity3d.com/threads/what-resolution-should-i-be-painting-sprites-in.225845/" target="_blank" rel="noopener"
 &gt;What Resolution should I be painting sprites in?&lt;/a&gt; 2048x2048 seems a bit big already on mobile device&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="link" href="https://support.unity3d.com/hc/en-us/articles/207051116-How-can-I-add-Alpha-to-ETC1-Compression-" target="_blank" rel="noopener"
 &gt;How Can I Add Alpha To ETC1 Compression?&lt;/a&gt; attempts to answer the question about ETC1 + Alpha channel&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sprites placed on some atlas by specifying them with a packing tag&lt;/li&gt;
&lt;li&gt;Make sure to mark the Override for Android checkbox as well as the Compress using ETC1 checkbox. Unity will split the resulting atlas into two textures, each without Alpha and then combine them in the final parts of the RenderPipeline.&lt;/li&gt;
&lt;li&gt;The UI shaders in Unity 5.3.0 and earlier do not support ETC1 + Alpha&lt;/li&gt;
&lt;li&gt;Yes. The UI elements do not work well with ETC1. We have a bug on it. (&lt;a class="link" href="http://forum.unity3d.com/threads/etc1-alpha-feature.350184/" target="_blank" rel="noopener"
 &gt;http://forum.unity3d.com/threads/etc1-alpha-feature.350184/&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="link" href="https://web.archive.org/web/20160726041743/http://developers.mobage.jp/blog/texture-compression" target="_blank" rel="noopener"
 &gt;Unity mobile Splitalpha&lt;/a&gt;. This blogs has solved the issue with ETC1 + Alpha and provided a solution for both Android and iOS devices.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ETC1 with Alpha channel splitalpha
&lt;ul&gt;
&lt;li&gt;Split Alpha texture&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 合計サイズ (MiB) RGBA 16bit 比のサイズ削減率 (%)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;RGBA 16bit	 879	 0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;RGBA PVRTC 4bit	 229	 74
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;RGBA ETC2 8bit	 431	 51
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Split Alpha (Android)	249	 72
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Split Alpha (iOS)	 272	 69
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;br/&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/keijiro/unity-alphamask" target="_blank" rel="noopener"
 &gt;https://github.com/keijiro/unity-alphamask&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In conclusion, use ETC + Alpha channel whenever you can because it provides the best build size and memory footprint in most cases, at reasonable quality.&lt;/p&gt;</description></item><item><title>Unity geometry distortion on child object</title><link>https://minhhh.github.io/posts/geometry-distortion-on-child-object/</link><pubDate>Sat, 03 Dec 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/geometry-distortion-on-child-object/</guid><description>&lt;p&gt;In Unity there is a geometry issue with the child object of non-uniformly scaled parent. When the parent object does not have (1,1,1) scale, then the child object will be skewed weirdly when they rotate. This issue has been mentioned in the below references:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="http://answers.unity3d.com/questions/197739/object-skewing-on-rotation.html" target="_blank" rel="noopener"
 &gt;http://answers.unity3d.com/questions/197739/object-skewing-on-rotation.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://answers.unity3d.com/questions/21645/geometry-distortion-on-child-objects.html" target="_blank" rel="noopener"
 &gt;http://answers.unity3d.com/questions/21645/geometry-distortion-on-child-objects.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The solution is to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Make the parent uniform, OR&lt;/li&gt;
&lt;li&gt;Child the objects to another uniformly scaled parent&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>Scale Shuriken Particle System</title><link>https://minhhh.github.io/posts/unity-scale-particles/</link><pubDate>Tue, 29 Nov 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-scale-particles/</guid><description>&lt;p&gt;Unity does not provide a way to scale Shuriken particle system in Editor. The process to scale each particle system manually is very inconvenient.&lt;/p&gt;
&lt;p&gt;There are some plugins on the Asset Store which can help you with this tasks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.assetstore.unity3d.com/en/#!/content/9703" target="_blank" rel="noopener"
 &gt;Simple Particle Scaler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.assetstore.unity3d.com/en/#!/content/4400" target="_blank" rel="noopener"
 &gt;Particle Scaler&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;rsquo;ve also written a tool to scale Shuriken Particles in the Editor: &lt;a class="link" href="https://github.com/minhhh/unity-particle-scaler" target="_blank" rel="noopener"
 &gt;unity-particle-scaler&lt;/a&gt;. It&amp;rsquo;s very convenient and simple to use.&lt;/p&gt;</description></item><item><title>Unity Asset Bundle</title><link>https://minhhh.github.io/posts/unity-asset-bundle/</link><pubDate>Tue, 29 Nov 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-asset-bundle/</guid><description>&lt;p&gt;Asset Bundle is a big topic in Unity. Initially, you want to grasp the basic setup and make something work. As your games get bigger, you might want to do more customization to make sure you have full control of the lifecycle. Here are some documents I&amp;rsquo;ve studied while learning about asset bundle. Ultimately, my goal is to make a full asset bundle workflow for big online game, so this blog will be a work in progress until I can transfer it into a working repository.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Asset bundle and AssetBundleManager&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://unity3d.com/learn/tutorials/topics/scripting/assetbundles-and-assetbundle-manager" target="_blank" rel="noopener"
 &gt;AssetBundles and the AssetBundle Manager&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;AssetBundles are downloaded and cached in their entirety.&lt;/li&gt;
&lt;li&gt;AssetBundles do not need to be loaded in their entirety.&lt;/li&gt;
&lt;li&gt;Assets in AssetBundles can have dependencies on other assets.&lt;/li&gt;
&lt;li&gt;Assets in AssetBundles can share dependencies with other assets.&lt;/li&gt;
&lt;li&gt;Each AssetBundle has some technical overhead, both in the size of the file and the need to manage that file.&lt;/li&gt;
&lt;li&gt;AssetBundles should be built for each target platform.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The steps of working with AssetBundles in the editor fall roughly into these steps:
&lt;ul&gt;
&lt;li&gt;Organizing &amp;amp; Setting-up AssetBundles in the editor.&lt;/li&gt;
&lt;li&gt;Building AssetBundles.&lt;/li&gt;
&lt;li&gt;Uploading AssetBundles to external storage.&lt;/li&gt;
&lt;li&gt;Downloading AssetBundles at run-time.&lt;/li&gt;
&lt;li&gt;Loading objects from AssetBundles.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Using Asset Variants to support different resolution
&lt;ul&gt;
&lt;li&gt;Create Variants folder&lt;/li&gt;
&lt;li&gt;Create corresponding SD and HD folder (must be same structure)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Pack sprites into AssetBundle
&lt;ul&gt;
&lt;li&gt;Use packing tag normally. Remember to set Sprite Mode: Single. Then set the AssetBundle&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Load sprite sheet from Asset Bundle
&lt;ul&gt;
&lt;li&gt;Can load Sprite or Texture2D, but it can&amp;rsquo;t load Sprite from a SpriteSheet directly&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://forum.unity3d.com/threads/packing-a-texture-sprite-sheet-in-an-asset-bundle-with-already-sliced-subtextures-possible.313186/" target="_blank" rel="noopener"
 &gt;http://forum.unity3d.com/threads/packing-a-texture-sprite-sheet-in-an-asset-bundle-with-already-sliced-subtextures-possible.313186/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Basically use LoadAssetWithSubAssets&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Issues
&lt;ul&gt;
&lt;li&gt;No subfolder inside AssetBundle&lt;/li&gt;
&lt;li&gt;Clear cache in &lt;code&gt;~/Library/Caches/Unity/&lt;/code&gt; &lt;a class="link" href="http://www.leandro.co.uk/unity/caching-assetbundles-in-unity/" target="_blank" rel="noopener"
 &gt;http://www.leandro.co.uk/unity/caching-assetbundles-in-unity/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Loading prefabs with script references from assetbundle
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="http://answers.unity3d.com/questions/1032495/loading-prefabs-with-script-references-from-assetb.html" target="_blank" rel="noopener"
 &gt;http://answers.unity3d.com/questions/1032495/loading-prefabs-with-script-references-from-assetb.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Variants with prefab
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="http://forum.unity3d.com/threads/official-how-did-asset-bundle-variant-fail-to-satisfy-your-hd-sd-use-case.375716/" target="_blank" rel="noopener"
 &gt;http://forum.unity3d.com/threads/official-how-did-asset-bundle-variant-fail-to-satisfy-your-hd-sd-use-case.375716/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Bundles have to be updated across unity version: &lt;a class="link" href="http://forum.unity3d.com/threads/end-of-the-resources-folder.363800/" target="_blank" rel="noopener"
 &gt;http://forum.unity3d.com/threads/end-of-the-resources-folder.363800/&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Or force player to update their client&lt;/li&gt;
&lt;li&gt;Client has to update and redownload ALL bundles&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="https://unity3d.com/learn/tutorials/topics/best-practices/assetbundle-usage-patterns" target="_blank" rel="noopener"
 &gt;AssetBundle usage patterns&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If an AssetBundle is unloaded improperly, it can cause Object duplication in memory&lt;/li&gt;
&lt;li&gt;Most projects should use AssetBundle.Unload(true) and adopt a method to ensure that Objects are not duplicated&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://unity3d.com/ru/learn/tutorials/topics/best-practices/assetbundle-fundamentals#Loading_Asset_Bundles" target="_blank" rel="noopener"
 &gt;AssetBundle.CreateFromMemory&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;loads an AssetBundle from a managed-code byte array (byte[] in C#)&lt;/li&gt;
&lt;li&gt;If the AssetBundle is LZMA compressed, it will decompress the AssetBundle while copying&lt;/li&gt;
&lt;li&gt;Uncompressed and LZ4-compressed AssetBundles will be copied verbatim&lt;/li&gt;
&lt;li&gt;The peak amount of memory consumed by this API will be at least twice the size of the AssetBundle: one copy in native memory created by the API, and one copy in the managed byte array passed to the API&lt;/li&gt;
&lt;li&gt;Assets loaded from an AssetBundle created via this API will therefore be duplicated three times in memory&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://unity3d.com/ru/learn/tutorials/topics/best-practices/assetbundle-fundamentals#Loading_Asset_Bundles" target="_blank" rel="noopener"
 &gt;AssetBundle.CreateFromFile&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;If the AssetBundles are uncompressed or LZ4
&lt;ul&gt;
&lt;li&gt;On device: only load the AssetBundle&amp;rsquo;s header. Objects are loaded on-demand. No excess memory will be consumed.&lt;/li&gt;
&lt;li&gt;On Editor: load the entire AssetBundle into memory&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Calls to AssetBundle.LoadFromFile will always fail for LZMA-compressed AssetBundles.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://unity3d.com/ru/learn/tutorials/topics/best-practices/assetbundle-fundamentals#Loading_Asset_Bundles" target="_blank" rel="noopener"
 &gt;WWW.LoadFromCacheOrDownload&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;WWW object will keep a full copy of the AssetBundle&amp;rsquo;s bytes in native memory&lt;/li&gt;
&lt;li&gt;3 ways to avoid
&lt;ul&gt;
&lt;li&gt;Keep AssetBundles small&lt;/li&gt;
&lt;li&gt;If using Unity 5.3 or newer, switch to using the new UnityWebRequest API&amp;rsquo;s DownloadHandlerAssetBundle, which does not cause memory spikes during downloads.&lt;/li&gt;
&lt;li&gt;Write a custom downloader. For more information, see the Custom downloaders section.&lt;/li&gt;
&lt;li&gt;Write a custom downloader&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://unity3d.com/ru/learn/tutorials/topics/best-practices/assetbundle-fundamentals#Loading_Asset_Bundles" target="_blank" rel="noopener"
 &gt;AssetBundleDownloadHandler&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;LZMA-compressed AssetBundles will be decompressed during download and cached uncompressed.&lt;/li&gt;
&lt;li&gt;does not keep a native-code copy of all downloaded bytes&lt;/li&gt;
&lt;li&gt;supports caching in a manner identical to WWW.LoadFromCacheOrDownload&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Examples of situations which may prevent the use of UnityWebRequest or WWW.LoadFromCacheOrDownload:
&lt;ul&gt;
&lt;li&gt;When fine-grained control over the AssetBundle cache is required&lt;/li&gt;
&lt;li&gt;When a project needs to implement a custom compression strategy&lt;/li&gt;
&lt;li&gt;When a project wishes to use platform-specific APIs to satisfy certain requirements, such as the need to stream data while inactive. Example: Using iOS&amp;rsquo; Background Tasks API to download data while in the background.&lt;/li&gt;
&lt;li&gt;When AssetBundles must be delivered over SSL on platforms where Unity does not have proper SSL support (such as PC).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AssetBundles in the caching system are identified only by their file names&lt;/li&gt;
&lt;li&gt;LZ4 decompress individual Objects without needing to decompress the entire AssetBundle&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="https://docs.unity3d.com/Manual/AssetBundleCompression.html" target="_blank" rel="noopener"
 &gt;Asset Bundle Compression&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="https://matome.naver.jp/odai/2139114084705385001" target="_blank" rel="noopener"
 &gt;Unity AssetBundle summary&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[Unite Japan 2013] Scene / Memory / Asset Bundle
&lt;ul&gt;
&lt;li&gt;【process】
&lt;ul&gt;
&lt;li&gt;① Build the asset bundle (A).&lt;/li&gt;
&lt;li&gt;② Download the asset bundle (A).&lt;/li&gt;
&lt;li&gt;③ Load the asset bundle (A).&lt;/li&gt;
&lt;li&gt;④ Load the asset (B) from the asset bundle.&lt;/li&gt;
&lt;li&gt;⑤ Generate an instance (C) of the asset.&lt;/li&gt;
&lt;li&gt;⑥ Unload the asset bundle (A).&lt;/li&gt;
&lt;li&gt;(Note that unloaded assets can not depend on other assets)&lt;/li&gt;
&lt;li&gt;⑦ Discard instance (C).&lt;/li&gt;
&lt;li&gt;⑧ Unload asset (B).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AssetBundle placement place】
&lt;ul&gt;
&lt;li&gt;① Server&lt;/li&gt;
&lt;li&gt;② In the StreemingAsset folder&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Minimize size of AssetBundle】
&lt;ul&gt;
&lt;li&gt;① It does not depend on others (Include all referenced assets in AssetBundle.)&lt;/li&gt;
&lt;li&gt;② It depends on in-app scripts and basic components.&lt;/li&gt;
&lt;li&gt;③ It depends on another AssetBundle.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;【Correspondence by Platform】
&lt;ul&gt;
&lt;li&gt;① Editor (If you are looking at bundled assets bundle, it will be difficult to test, so let&amp;rsquo;s do something.)&lt;/li&gt;
&lt;li&gt;② Android&lt;/li&gt;
&lt;li&gt;③ IOS&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;【How to Load Asset Bundle】
&lt;ul&gt;
&lt;li&gt;① Use the cache. &amp;lsquo;WWW.LoadFromCacheOrDownload&amp;rsquo;&lt;/li&gt;
&lt;li&gt;(Note: 150 days deletion and caching can not be deleted.)&lt;/li&gt;
&lt;li&gt;② One time only &amp;ldquo;WWW (&amp;rdquo; http: // &amp;hellip; &amp;ldquo;), WWW (&amp;rdquo; file: // &amp;hellip; &amp;ldquo;)&amp;rdquo;&lt;/li&gt;
&lt;li&gt;③ Save locally and do not use cache. &amp;ldquo;AssetBundle.CreateFromFile, AssetBundle.CreateFromMemory&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Supplement 1: How to summarize asset bundles
&lt;ul&gt;
&lt;li&gt;① Compressed or uncompressed&lt;/li&gt;
&lt;li&gt;② Individual or large quantity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Supplement 2
&lt;ul&gt;
&lt;li&gt;① Individual synchronous load&lt;/li&gt;
&lt;li&gt;② Individual asynchronous load&lt;/li&gt;
&lt;li&gt;③ bulk synchronous load&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;【Efficient Build】
&lt;ul&gt;
&lt;li&gt;① Automation&lt;/li&gt;
&lt;li&gt;② Folder structure&lt;/li&gt;
&lt;li&gt;③ Adjustment of property at build time · · ·&lt;/li&gt;
&lt;li&gt;(Side street: property adjustment at asset import)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;【Correspondence at the time of version up】 · · · I do not use it so I omit it
&lt;ul&gt;
&lt;li&gt;① Cash on the URL&lt;/li&gt;
&lt;li&gt;② Compatibility&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;【Others】 · · · I do not use it so I omit it
&lt;ul&gt;
&lt;li&gt;① To use binary data.&lt;/li&gt;
&lt;li&gt;② Include the script in the asset bundle. (It is impossible in IOS, so it is omitted)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Writing Unity iOS plugin</title><link>https://minhhh.github.io/posts/unity-ios-plugin/</link><pubDate>Fri, 25 Nov 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-ios-plugin/</guid><description>&lt;p&gt;&lt;a class="link" href="https://docs.unity3d.com/Manual/PluginsForIOS.html" target="_blank" rel="noopener"
 &gt;Building Plugins for iOS&lt;/a&gt; is a guide from Unity.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Two approaches&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Approach 1: Put plugin source code &lt;code&gt;.mm,.c,.cpp&lt;/code&gt; files in &lt;code&gt;Assets/Plugins/iOS&lt;/code&gt; folder.&lt;/li&gt;
&lt;li&gt;Approach 2: Build plugin library to &lt;code&gt;.a&lt;/code&gt; file then put it in &lt;code&gt;Assets/Plugins/iOS&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="link" href="http://stackoverflow.com/questions/14834626/how-to-build-unity3d-plugin-for-ios" target="_blank" rel="noopener"
 &gt;How to build Unity3d Plugin for iOS&lt;/a&gt; experience from a developer&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="http://blogs.shephertz.com/2013/08/23/bridging-the-gap-plugin-for-unity-and-ios/" target="_blank" rel="noopener"
 &gt;Plugin for Unity and iOS&lt;/a&gt; iOS plugin with source code inside Asset folder&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="http://www.slideshare.net/kaijungchen/unity3-d-plugins-development-guide-29659247" target="_blank" rel="noopener"
 &gt;Unity3D Plugins Development Guide&lt;/a&gt;&lt;/p&gt;</description></item><item><title>How to do blur effect in Unity</title><link>https://minhhh.github.io/posts/unity-how-to-do-blur/</link><pubDate>Thu, 24 Nov 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-how-to-do-blur/</guid><description>&lt;p&gt;&lt;strong&gt;Image Blur&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;can use a camera which render to a rendered texture&lt;/li&gt;
&lt;li&gt;add the images to be rendered to a second canvas, which uses the new camera with screenspace-camera&lt;/li&gt;
&lt;li&gt;Add blur shader to the Camera, or a parent object which contains all images&lt;/li&gt;
&lt;li&gt;Add the rendered texture to anywhere you like in the first camera&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Dynamic Background Blur&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="http://answers.unity3d.com/questions/21699/unity-blur-behind-window.html" target="_blank" rel="noopener"
 &gt;Blur Behind Window&lt;/a&gt; Use Camera post effect&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://forum.unity3d.com/threads/solved-dynamic-blurred-background-on-ui.345083/" target="_blank" rel="noopener"
 &gt;Dynamic Blurred Background on UI&lt;/a&gt; Use Grabpass&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://blog.ivank.net/fastest-gaussian-blur.html" target="_blank" rel="noopener"
 &gt;http://blog.ivank.net/fastest-gaussian-blur.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Unity local network multiplayer</title><link>https://minhhh.github.io/posts/unity-localnetwork-multiplayer/</link><pubDate>Mon, 21 Nov 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-localnetwork-multiplayer/</guid><description>&lt;p&gt;iOS device can connect to iOS device via Bluetooth using:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.assetstore.unity3d.com/en/#!/content/2739" target="_blank" rel="noopener"
 &gt;MultiPeer Local Multiplayer Plugin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://prime31.com/docs#iosGCMP" target="_blank" rel="noopener"
 &gt;GameCenter Multiplayer plugin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;U3DXT&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Android device can connect to Android device via Bluetooth using:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Android Bluetooth Multiplayer (Pro)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="link" href="https://github.com/DarkRay/Unity3D-bluetooth" target="_blank" rel="noopener"
 &gt;https://github.com/DarkRay/Unity3D-bluetooth&lt;/a&gt; A low level bluetooth library.&lt;/p&gt;
&lt;p&gt;Android and iOS cannot connect to each other via iOS as mentioned &lt;a class="link" href="http://stackoverflow.com/questions/18884705/transfer-data-between-ios-and-android-via-bluetooth" target="_blank" rel="noopener"
 &gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="http://stackoverflow.com/questions/13032540/unity3d-for-ios-and-android-multiplayer-bluetooth-connection" target="_blank" rel="noopener"
 &gt;Unity3D for iOS and Android: Multiplayer&lt;/a&gt;. Options for multiplayer game&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;via Bluetooth (using Prime31 plugin)
&lt;ul&gt;
&lt;li&gt;iOS&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;via LAN (using Unity RPC) The players can start combats in a Local Area Network with any of above devices: iOS vs iOS, iOS vs Android, Android vs Mac, and so on.
&lt;ul&gt;
&lt;li&gt;iOS&lt;/li&gt;
&lt;li&gt;Android&lt;/li&gt;
&lt;li&gt;Mac&lt;/li&gt;
&lt;li&gt;Web (Kongregate)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;via Game Center (using Prime31 plugin): Uses the Game Center multiplayer to match combats.
&lt;ul&gt;
&lt;li&gt;iOS&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;via Global Server (an in-house solution): The players can start combats around the world with any of above devices: iOS vs iOS, iOS vs Android, Android vs Mac, and so on.
&lt;ul&gt;
&lt;li&gt;iOS&lt;/li&gt;
&lt;li&gt;Android&lt;/li&gt;
&lt;li&gt;Mac&lt;/li&gt;
&lt;li&gt;Web (Kongregate)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="link" href="https://docs.unity3d.com/Manual/UNetOverview.html" target="_blank" rel="noopener"
 &gt;UNET&lt;/a&gt; the new Unity Networking library.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://forum.unity3d.com/threads/unet-sample-projects.331978/" target="_blank" rel="noopener"
 &gt;Unet sample projects&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://unity3d.com/learn/tutorials/topics/multiplayer-networking/introduction-simple-multiplayer-example?playlist=29690" target="_blank" rel="noopener"
 &gt;Multiplayer Networking Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://forum.unity3d.com/threads/unity-5-unet-multiplayer-tutorials-making-a-basic-survival-co-op.325692/" target="_blank" rel="noopener"
 &gt;Unity 5 UNET Multiplayer Tutorials&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="link" href="http://www.tasharen.com/?page_id=4518" target="_blank" rel="noopener"
 &gt;TNET&lt;/a&gt; Another option which uses UDP for multiplayer game.&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://allseenalliance.org/framework" target="_blank" rel="noopener"
 &gt;Alljoyn&lt;/a&gt; makes it easy for devices to communicate. Unfortunately it does not support Unity.&lt;/p&gt;</description></item><item><title>Setting sorting layer and order in layer of Mesh Renderer</title><link>https://minhhh.github.io/posts/unity-sortinglayer-setter/</link><pubDate>Sun, 30 Oct 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-sortinglayer-setter/</guid><description>&lt;p&gt;Unity 5.x exposes the sorting layer and order in layer of &lt;code&gt;SpriterRenderer&lt;/code&gt;, but not &lt;code&gt;MeshRenderer&lt;/code&gt;. Fortunately, it&amp;rsquo;s very easy setting these property of the &lt;code&gt;MeshRenderer&lt;/code&gt; in code. I&amp;rsquo;ve created a simple solution for setting sorting layer and order in layer of any &lt;code&gt;Renderer&lt;/code&gt; component using a simple component called &lt;a class="link" href="https://github.com/minhhh/unity-sortinglayer-setter" target="_blank" rel="noopener"
 &gt;SortingLayerSetter&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It looks like this in the Editor&lt;/p&gt;
&lt;p&gt;&lt;img alt="example 1" class="gallery-image" data-flex-basis="310px" data-flex-grow="129" height="448" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://raw.githubusercontent.com/minhhh/unity-sortinglayer-setter/master/images/example1.png" width="580"&gt;&lt;/p&gt;</description></item><item><title>When to use Script Execution Order</title><link>https://minhhh.github.io/posts/when-to-use-scriptexecutionorder/</link><pubDate>Fri, 28 Oct 2016 00:01:00 +0700</pubDate><guid>https://minhhh.github.io/posts/when-to-use-scriptexecutionorder/</guid><description>&lt;p&gt;Normally we don&amp;rsquo;t control the execution order of &lt;code&gt;MonoBehaviour&lt;/code&gt; scripts, and we should not. However, there are cases where we do want some scripts to be executed before others. Some usecases include:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A &lt;code&gt;Controller&lt;/code&gt; script that should be executed as the entry point to the scene&lt;/li&gt;
&lt;li&gt;Scripts which use &lt;code&gt;LateUpdate&lt;/code&gt; and must be executed in specific order&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For these cases, we will assign an integer number to those scripts in &lt;code&gt;Edit &amp;gt; Project Settings &amp;gt; Script Execution Order&lt;/code&gt;. It&amp;rsquo;s best practice to use large and discrete number such as &lt;code&gt;100&lt;/code&gt;, &lt;code&gt;200&lt;/code&gt;, &lt;code&gt;-100&lt;/code&gt; instead of &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt;, &lt;code&gt;3&lt;/code&gt; because it would make it easier to insert something in between them when we need to.&lt;/p&gt;
&lt;p&gt;One inconvenience with Unity Editor GUI for &lt;code&gt;Script Execution Order&lt;/code&gt; is that it&amp;rsquo;s a bit hard to find your classes when there are a lot of them. The solution for this is to add &lt;code&gt;Script Execution Order&lt;/code&gt; as meta information to the class using attribute. There&amp;rsquo;s already an implementation for this: &lt;a class="link" href="https://github.com/kwnetzwelt/ugb-source/blob/UGB-3.0/UnityGameBase/Core/Editor/GameScriptExecutionOrder.cs" target="_blank" rel="noopener"
 &gt;https://github.com/kwnetzwelt/ugb-source/blob/UGB-3.0/UnityGameBase/Core/Editor/GameScriptExecutionOrder.cs&lt;/a&gt; and &lt;a class="link" href="https://github.com/kwnetzwelt/ugb-source/blob/UGB-3.0/UnityGameBase/ScriptExecutionOrderAttribute.cs" target="_blank" rel="noopener"
 &gt;https://github.com/kwnetzwelt/ugb-source/blob/UGB-3.0/UnityGameBase/ScriptExecutionOrderAttribute.cs&lt;/a&gt;. Using these 2 classes, now we can add &lt;code&gt;Script Execution Order&lt;/code&gt; to any class as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[ScriptExecutionOrder(-1000)]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;public abstract class Game : MonoBehaviour
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Run specific code when Editor starts</title><link>https://minhhh.github.io/posts/run-code-when-editor-starts/</link><pubDate>Fri, 28 Oct 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/run-code-when-editor-starts/</guid><description>&lt;p&gt;Sometimes we want to execute code whenever we hit &lt;code&gt;Play&lt;/code&gt; button in Unity Editor. The reason for this usually is that we want to enforce some workflow automatically such as getting specific environment information (e.g. git hash, date) and fill it in a prefab or something. We could do these things by creating a Custom Window with a button somewhere, but it feels too manual.&lt;/p&gt;
&lt;p&gt;Fortunately, Unity has offered a simple way to do this, that is &lt;code&gt;InitializeOnLoadAttribute&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://web.archive.org/web/20160515043658/http://blog.andreimarks.com/2012/08/16/unity-how-to-run-specific-code-only-when-building-out-a-project" target="_blank" rel="noopener"
 &gt;http://blog.andreimarks.com/2012/08/16/unity-how-to-run-specific-code-only-when-building-out-a-project/&lt;/a&gt; shows an usecase of &lt;code&gt;InitializeOnLoadAttribute&lt;/code&gt;: to generate a tracking tag of the build with the build date.&lt;/p&gt;
&lt;p&gt;Beware of a potential problem &lt;a class="link" href="https://web.archive.org/web/20161015115941/http://www.createdbyx.com/post/2013/02/17/Unity-Tip-101-55-%E2%80%93-InitializeOnLoad-ResourcesLoad-gotcha%E2%80%99s.aspx" target="_blank" rel="noopener"
 &gt;here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An awesome review of other ways to execute code on startup are listed here &lt;a class="link" href="http://www.codingjargames.com/blog/2015/08/04/unity-and-initialization-order/" target="_blank" rel="noopener"
 &gt;http://www.codingjargames.com/blog/2015/08/04/unity-and-initialization-order/&lt;/a&gt;&lt;/p&gt;</description></item><item><title>MVC in Unity</title><link>https://minhhh.github.io/posts/unity-mvc-like-frameworks/</link><pubDate>Thu, 27 Oct 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-mvc-like-frameworks/</guid><description>&lt;h1 id="some-mvc-like-frameworks-in-unity"&gt;Some MVC like frameworks in Unity
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="https://forum.unity3d.com/threads/3usd-key-value-observing-lightweight-implementation-of-kvo-for-c.330319/" target="_blank" rel="noopener"
 &gt;Key Value Observing&lt;/a&gt;&lt;/strong&gt; This is a simple implementation of MVC according to his own understandings&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="https://github.com/cgarciae/karma" target="_blank" rel="noopener"
 &gt;Karma&lt;/a&gt;&lt;/strong&gt; Lightweight MVC framework using Zenject DI container. It is inspired from &lt;a class="link" href="http://engineering.socialpoint.es/MVC-pattern-unity3d-ui.html" target="_blank" rel="noopener"
 &gt;MODEL VIEW CONTROLLER PATTERN FOR UNITY3D USER INTERFACES&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="https://www.assetstore.unity3d.com/en/#!/content/37466" target="_blank" rel="noopener"
 &gt;Marklight&lt;/a&gt;&lt;/strong&gt; Looks nice. It offers XUML and external editor which might be good for view management, but it also feels too restrictive because you have to follow their way.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="http://chromealex.github.io/Unity3d.UI.Windows/" target="_blank" rel="noopener"
 &gt;Unity3d.UI.Windows&lt;/a&gt;&lt;/strong&gt; Uses a Window system to create UI and layout elements. Try doing too many things: Audio, Tweening&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="https://github.com/strangeioc/strangeioc" target="_blank" rel="noopener"
 &gt;strangeioc&lt;/a&gt;&lt;/strong&gt; Obsolete and not maintained&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="https://www.assetstore.unity3d.com/en/#!/content/14381" target="_blank" rel="noopener"
 &gt;uFrame MVVM&lt;/a&gt;&lt;/strong&gt; It&amp;rsquo;s trying to do too much by offering a graphing/diagramming engine and code generation. I really don&amp;rsquo;t like code generation&lt;/p&gt;
&lt;h1 id="discussion"&gt;Discussion
&lt;/h1&gt;&lt;p&gt;It looks like the main advantages of using these MVC frameworks are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Some of them can support theme change&lt;/li&gt;
&lt;li&gt;They have some existing controls so you don&amp;rsquo;t have to implement yourself.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, there are several disadvantages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you don&amp;rsquo;t need to change theme then definitely you don&amp;rsquo;t need to separate View and ViewModel or Presenter.&lt;/li&gt;
&lt;li&gt;UI usually consists of a big container and a lot of smaller views. Testing small views is easy so you don&amp;rsquo;t need to create separate View class for each. Testing the container is complicated, you want to do it with a test scene in Unity anyway, thus there&amp;rsquo;s no need to try to make an ViewModel interface for testing.&lt;/li&gt;
&lt;li&gt;The examples of Unity MVC implementation in some blogs are usually naive and contrived. As such, they don&amp;rsquo;t scale when you have really complex UI. In addition, they usually confuse between UI and gameplay, so they take example such as hitting enemies or updating their HP bar. MVC is suitable for UIs and maybe some turn-based gameplay, but extending it to a fighting gameplay requires much more than some optimistic guesswork.&lt;/li&gt;
&lt;li&gt;Controller needs to behave according to states, that makes the ViewPresenter or ViewModel also have to replicate those states fully or partly. It&amp;rsquo;s quite difficult to know which should be the common behaviour. A simpler way is to just merge Controller and View/ViewPresenter/ViewModel.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Unity singleton</title><link>https://minhhh.github.io/posts/unity-singleton/</link><pubDate>Thu, 29 Sep 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-singleton/</guid><description>&lt;p&gt;First of all, please remember that Singletons are generally not recommended due to various obvious disadvantages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hard to reason about code&lt;/li&gt;
&lt;li&gt;Encourage coupling&lt;/li&gt;
&lt;li&gt;Potential concurrency issue&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, in game development it&amp;rsquo;s super useful to have singleton for many types of global system, including but not limited to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sound system&lt;/li&gt;
&lt;li&gt;Time manager&lt;/li&gt;
&lt;li&gt;Localization&lt;/li&gt;
&lt;li&gt;Tutorial&lt;/li&gt;
&lt;li&gt;Login&lt;/li&gt;
&lt;li&gt;Global Notifier&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this article we will look at some options of Singleton implementation we have in Unity to see what problems they&amp;rsquo;re trying to solve and what assumptions they made.&lt;/p&gt;
&lt;h2 id="requirements"&gt;Requirements
&lt;/h2&gt;&lt;p&gt;Let&amp;rsquo;s first review some requirements for a useful singleton system in Unity.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Singleton class types&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MonoBehavior based: These types of singletons extends MonoBehavior and shows themselves in the scene hierarchy so that you can look at their exposed members. Another reason is you want them to have an &lt;code&gt;Update&lt;/code&gt; function to do something useful in it.&lt;/li&gt;
&lt;li&gt;Non MonoBehavior based: Traditional singletons in any OO languages. These singletons don&amp;rsquo;t need to be inspected in the scene nor do they need &lt;code&gt;Update&lt;/code&gt;. We will not focus on these types of singletons.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Singleton lifecycle types&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Has dependencies: These singletons depend on other system or singletons to exist before they can start&lt;/li&gt;
&lt;li&gt;No dependencies: These singletons can be created anytime without waiting for any other entities.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Singleton configurability types&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Has customized parameters: This is a bit overlap with &lt;code&gt;Has dependencies&lt;/code&gt; singletons. These singletons might: 1. Depend on parameters provided by another system, such as the FileSystem to load certian parameters from disk. OR 2. Need customized parameters or linked prefab. They might be in a prefab themselves such as a LevelManager.&lt;/li&gt;
&lt;li&gt;No customized parameters: These singletons behave the same all the time.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="solutions"&gt;Solutions
&lt;/h2&gt;&lt;p&gt;Fortunately there&amp;rsquo;re already some solutions written in &lt;a class="link" href="http://wiki.unity3d.com" target="_blank" rel="noopener"
 &gt;unity3d&lt;/a&gt; so we can review and improve them as we wish.&lt;/p&gt;
&lt;h3 id="amanagerclass"&gt;AManagerClass
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="http://wiki.unity3d.com/index.php/AManagerClass" target="_blank" rel="noopener"
 &gt;AManagerClass&lt;/a&gt; is a standard implementation which supports MonoBehavior-based singletons. In the code, we refer to the singleton like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; AManager.instance.Foo ();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The &lt;code&gt;instance&lt;/code&gt; function implementation is as below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public static AManager instance {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; get {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if (s_Instance == null) {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; // This is where the magic happens.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; // FindObjectOfType(...) returns the first AManager object in the scene.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; s_Instance = FindObjectOfType(typeof (AManager)) as AManager;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; // If it is still null, create a new instance
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if (s_Instance == null) {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; GameObject obj = new GameObject(&amp;#34;AManager&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; s_Instance = obj.AddComponent(typeof (AManager)) as AManager;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Debug.Log (&amp;#34;Could not locate an AManager object. \ AManager was Generated Automaticly.&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return s_Instance;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;There are several problems with &lt;code&gt;AManager&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We have to duplicate it for all singleton class&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s slow due to the 2 checks&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Surely we can do better!&lt;/p&gt;
&lt;h3 id="autosingletonmanager"&gt;AutoSingletonManager
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="http://wiki.unity3d.com/index.php/AutoSingletonManager" target="_blank" rel="noopener"
 &gt;AutoSingletonManager&lt;/a&gt; solves the code duplication problem of &lt;code&gt;AManager&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&amp;rsquo;s the main code&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;span class="lnt"&gt;50
&lt;/span&gt;&lt;span class="lnt"&gt;51
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;public abstract class AutoSingletonManager : MonoBehaviour { }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;public abstract class AutoSingletonManager&amp;lt;T&amp;gt; : AutoSingletonManager where T : AutoSingletonManager
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; private static bool Compare&amp;lt;T&amp;gt;(T x, T y) where T : class
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return x == y;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; #region Singleton
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; private static T _instance = default(T);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public static T Instance
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; get
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if (!Compare&amp;lt;T&amp;gt;(default(T), _instance)) return _instance;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; InitInstance(true);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return _instance;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; #endregion
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public void Awake()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; InitInstance(false);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public static void InitInstance(bool shouldInitManager)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Type thisType = typeof (T);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; _instance = FindObjectOfType&amp;lt;T&amp;gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if (Compare&amp;lt;T&amp;gt;(default(T), _instance))
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; _instance = new GameObject(thisType.Name).AddComponent&amp;lt;T&amp;gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; //Won&amp;#39;t call InitManager from Awake
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if (shouldInitManager)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; (_instance as AutoSingletonManager&amp;lt;T&amp;gt;).InitManager();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public virtual void InitManager() { }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The code uses recursive generic definition. This allow us to reuse code by inheriting from the singleton class as well as from &lt;code&gt;MonoBehaviour&lt;/code&gt;. Note that we don&amp;rsquo;t have to make &lt;code&gt;AutoSingletonManager&amp;lt;T&amp;gt;&lt;/code&gt; inherits from &lt;code&gt; AutoSingletonManager&lt;/code&gt;, instead we can make it inherit from our own class which in turn inherits from MonoBehavior.&lt;/p&gt;
&lt;p&gt;It supports initializing the instance from &lt;code&gt;Awake&lt;/code&gt; so maybe it can be used by adding directly it to an object in the scene. However, &lt;code&gt;InitManager&lt;/code&gt; is not called in &lt;code&gt;Awake&lt;/code&gt; so if you call &lt;code&gt;AutoSingletonManager.Instance&lt;/code&gt; after it already awakes then InitManager will never be called.&lt;/p&gt;
&lt;p&gt;Another more subtle draw back is it uses an unnecessary comparison &lt;code&gt;if (!Compare&amp;lt;T&amp;gt;(default(T), _instance)) return _instance;&lt;/code&gt; in the &lt;code&gt;Instance&lt;/code&gt; property, so it&amp;rsquo;s not optimal if you call &lt;code&gt;Instance&lt;/code&gt; in a &lt;code&gt;Update&lt;/code&gt; loop or something similar.&lt;/p&gt;
&lt;p&gt;Surely we can do better than this.&lt;/p&gt;
&lt;h3 id="secure-unitysingleton"&gt;Secure UnitySingleton
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="http://wiki.unity3d.com/index.php/Secure_UnitySingleton" target="_blank" rel="noopener"
 &gt;SecureUnitySingleton&lt;/a&gt; is the last one of the three singleton implementation in &lt;a class="link" href="http://wiki.unity3d.com" target="_blank" rel="noopener"
 &gt;unity3d&lt;/a&gt;. It has a very clear idea about the usecases of singletons. There are 3 main supported usecases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Exists In Scene: Searches the current scene for an object with the singleton component attached to it.&lt;/li&gt;
&lt;li&gt;Loaded From Resources: This type creates an instance of a prefab with the singleton component attached to it from a Resources folder.&lt;/li&gt;
&lt;li&gt;Create on New GameObject: This type creates a new GameObject and attaches a new instance of the singleton component to it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are several issues with approach:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Even though the code is quite functional, it still suffers the performance penalty from checking too many things in the &lt;code&gt;Instance&lt;/code&gt; property.&lt;/li&gt;
&lt;li&gt;Lack of lifecyle methods. Even though it provides a static &lt;code&gt;DeleteInstance&lt;/code&gt; method, there&amp;rsquo;s no other methods to execute when the instance is created. You might think that &lt;code&gt;Awake&lt;/code&gt; can be used for that purpose, but it not explicit enough that &lt;code&gt;Awake&lt;/code&gt; is called immediately after &lt;code&gt;Instance&lt;/code&gt; is called. Another possible issue is &lt;code&gt;Awake&lt;/code&gt; will not be called when the prefab is disabled, which should never be desirable but can happen due to a mistake from the developers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is quite good but surely we can do better.&lt;/p&gt;
&lt;h2 id="discussions"&gt;Discussions
&lt;/h2&gt;&lt;p&gt;First of all, we realize that non of the above methods take into account concurrency issue. If we care about concurrency we can do something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="n"&gt;MySingleton&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;MySingleton&lt;/span&gt; &lt;span class="n"&gt;_instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="n"&gt;singletonLock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;MySingleton&lt;/span&gt; &lt;span class="n"&gt;Instance&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_instance&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;lock&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;singletonLock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_instance&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;singletonGameObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;GameObject&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;MySingleton&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;GameObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DontDestroyOnLoad&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;singletonGameObject&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;_instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;singletonGameObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddComponent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;MySingleton&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="n"&gt;initialization&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;By using a simple double lock pattern, we seemingly solve the &amp;ldquo;concurrency problem&amp;rdquo;. The question is: Do we need to?. Why you have the concurrency problem with singleton? It&amp;rsquo;s because you want to &lt;code&gt;lazy load&lt;/code&gt; the singleton, i.e. only create it when it is used for the first time. But that&amp;rsquo;s exactly what we want to avoid if we want to achieve smooth gameplay. So what you should do instead is just create the bloody singleton at the beginning and forget about it. Remember, &lt;code&gt;preload&lt;/code&gt; is better than &lt;code&gt;lazy load&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Secondly, I&amp;rsquo;ve already mentioned the check for null is redundant if we know we only call the singleton after it&amp;rsquo;s been initialized. In the usecases listed by &lt;code&gt;SecureSingleton&lt;/code&gt;, we see that the singleton is either created by code or already exists in the scene as a &lt;code&gt;GameObject&lt;/code&gt; which is supposed to be configured by designers. In either case, the code to initialize the scene should be a good place for calling the initialization code of the singleton and there&amp;rsquo;s no need for making it sooner.&lt;/p&gt;
&lt;p&gt;So what will happen if the &lt;code&gt;Instance&lt;/code&gt; property is called before you initialize the singleton? Obviously an exception will be thrown and this is an ideal case for using Unity Assert because you will have a nice message in development mode but you can also turn it off in production build.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	public class GameSingleton&amp;lt;T&amp;gt; : MyBaseBehaviour where T : GameSingleton&amp;lt;T&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public static T Instance
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; get {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Assert.IsNotNull (instance);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return instance;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Note that &lt;code&gt;MyBaseBehaviour&lt;/code&gt; class is a class derived from &lt;code&gt;MonoBehaviour&lt;/code&gt; and is customized specifically for our game. For instance, it might have general code for handling &lt;code&gt;Update&lt;/code&gt; or &lt;code&gt;OnDestroy&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;All that is left now is writing a function &lt;code&gt;CreateInstance&lt;/code&gt; for creating the singleton. This function should be called once only at the exact place where you want it. This means we should design it in such a way to discourage it from being called multiple times randomly by some careless developers. Calling &lt;code&gt;CreateInstance&lt;/code&gt; twice should throw an exception. This is better than mindlessly guard the function in the name of &amp;ldquo;defensive programming&amp;rdquo;. It will look something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;		public static T CreateInstance()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;		{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Assert.IsNull (instance);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;			GameObject go = new GameObject(typeof(T).Name);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;			instance = go.AddComponent&amp;lt;T&amp;gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;			instance.OnCreated();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;			DontDestroyOnLoad(go);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;			return instance;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;		protected virtual void OnCreated()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;		{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Here we have a virtual function &lt;code&gt;OnCreated&lt;/code&gt; waiting to be overriden in subclass. To destroy the singleton, we don&amp;rsquo;t have to use fancy static function &lt;code&gt;DeleteInstance&lt;/code&gt;, instead we can just get the singleton gameobject and destroy it like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; GameObject.Destroy (MySingleton.Instance.gameObject);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;When the &lt;code&gt;OnDestroy&lt;/code&gt; function is called, we will set &lt;code&gt;instance&lt;/code&gt; variable to null then allow subclass to do cleanup themselves. The reason why we don&amp;rsquo;t use &lt;code&gt;DeleteInstance&lt;/code&gt; is because we don&amp;rsquo;t want developers who use the API to think there&amp;rsquo;s anything special about destroying the singleton than just destroying the container object.&lt;/p&gt;
&lt;p&gt;Finally, we discuss feature &lt;code&gt;destroy if exists in scene&lt;/code&gt;. In my opinion, this feature accounts for a very small proportion of our usecases. Most of the time we have a singleton already exists in scene, or in some prefab is because we want to use Unity to store game data. But that&amp;rsquo;s should not be the main way to deal with game data. We&amp;rsquo;d better use off-unity format to store game data, like text or database. If we need to store linked resources we can use Scriptable Object. The point is to not rely too much on data stored in prefab or scene just because you want designers to change them easily, they can also change text file or database much more easily than firing up Unity. Also, merging prefab is harder than merging text data.&lt;/p&gt;
&lt;p&gt;If you really want to use avoid duplicate singleton in scene, we can simply use this piece of code from &lt;code&gt;SecureUnitySingleton&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	protected virtual void Awake()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;		if (InstanceExists &amp;amp;&amp;amp; instance != this)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;			Destroy(gameObject);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="implementation"&gt;Implementation
&lt;/h2&gt;&lt;p&gt;After we&amp;rsquo;ve considered different aspect of singletons and what our real usecases are, we finalize our own version Unity singleton as follows&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;using UnityEngine;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;using System;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;using UnityEngine.Assertions;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;public class SimpleSingleton&amp;lt;T&amp;gt; : BaseMonoBehaviour where T : SimpleSingleton&amp;lt;T&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; private static T instance;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public static T Instance {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; get {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Assert.IsNotNull (instance, &amp;#34;Instance is null. Please call CreateInstance first!&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return instance;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public static T CreateInstance ()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if (instance != null) {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Assert.IsNull (instance, &amp;#34;Instance is not null. Please call CreateInstance once only&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; GameObject go = new GameObject (typeof(T).Name);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; instance = go.AddComponent&amp;lt;T&amp;gt; ();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; instance.OnCreated ();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return instance;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; protected virtual void OnDestroy ()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; instance = null;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; protected virtual void OnCreated ()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Then remember to call &lt;code&gt;CreateInstance&lt;/code&gt; when necessary and in appropriate order.&lt;/p&gt;
&lt;p&gt;The code with a sample scene is available on github at &lt;a class="link" href="https://github.com/minhhh/unity-singleton" target="_blank" rel="noopener"
 &gt;https://github.com/minhhh/unity-singleton&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Regarding the &lt;code&gt;Has Customized Parameters&lt;/code&gt; singletons, there are some implementations of this type using Prefab to set the parameters. This method is not recommended. Instead, we can use ScriptableObject to store the parameter and let the Singleton read from these ScriptableObject. This method will make all the settings centralized in a single location.&lt;/p&gt;
&lt;p&gt;TODO: Create SceneSingleton&lt;/p&gt;</description></item></channel></rss>