<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Huy Minh Ha</title><link>https://minhhh.github.io/</link><description>Recent content on Huy Minh Ha</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Mon, 08 Jun 2026 00:00:00 +0700</lastBuildDate><atom:link href="https://minhhh.github.io/index.xml" rel="self" type="application/rss+xml"/><item><title>Migrating Pelican to Hugo with an LLM</title><link>https://minhhh.github.io/posts/migrating-pelican-to-hugo-with-an-llm/</link><pubDate>Mon, 08 Jun 2026 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/migrating-pelican-to-hugo-with-an-llm/</guid><description>&lt;p&gt;I&amp;rsquo;ve been running this blog on Pelican 3.4 since 2014. It worked, but the tooling was showing its age. I wanted to switch to Hugo — faster builds, simpler dependency story, and the Stack theme looked great out of the box.&lt;/p&gt;
&lt;p&gt;Rather than doing the migration manually, I used an LLM (this very session) to walk through it step by step.&lt;/p&gt;
&lt;h2 id="what-the-llm-handled"&gt;What the LLM handled
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Conversion script&lt;/strong&gt;: Wrote a Python script to convert 65 Pelican-format articles to Hugo frontmatter, handling field mapping, &lt;code&gt;{filename}&lt;/code&gt; cleanup, and URL preservation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Config scaffolding&lt;/strong&gt;: Set up Hugo modules, the Stack theme, and all 6 config files (&lt;code&gt;config.toml&lt;/code&gt;, &lt;code&gt;params.toml&lt;/code&gt;, &lt;code&gt;menu.toml&lt;/code&gt;, &lt;code&gt;permalinks.toml&lt;/code&gt;, &lt;code&gt;markup.toml&lt;/code&gt;, &lt;code&gt;module.toml&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deployment&lt;/strong&gt;: Created a GitHub Actions workflow with hash-pinned actions for supply-chain security.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Asset migration&lt;/strong&gt;: Moved avatar, favicon, and static images; verified all external image URLs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Site verification&lt;/strong&gt;: Ran through every page type, RSS, Disqus, syntax highlighting, dark mode, and search — all confirmed working.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cleanup&lt;/strong&gt;: Removed Pelican tooling (&lt;code&gt;fabfile.py&lt;/code&gt;, &lt;code&gt;develop_server.sh&lt;/code&gt;, &lt;code&gt;pelicanconf.py&lt;/code&gt;, old themes, &lt;code&gt;Pipfile&lt;/code&gt;), updated &lt;code&gt;Makefile&lt;/code&gt; and README.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="what-i-did"&gt;What I did
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Made decisions on menu order, category merges (Web Development → Programming), and deployment strategy (GitHub Actions vs. manual).&lt;/li&gt;
&lt;li&gt;Replaced the placeholder avatar with my actual photo.&lt;/li&gt;
&lt;li&gt;Reviewed and approved each step.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="result"&gt;Result
&lt;/h2&gt;&lt;p&gt;288 pages, 0 build errors, all old URLs preserved, and a much simpler publishing workflow:&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-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git push origin &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="c1"&gt;# that&amp;#39;s it&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;The whole migration took one continuous session. The backup branch &lt;code&gt;archive/pelican-source&lt;/code&gt; preserves the old setup.&lt;/p&gt;
&lt;h2 id="verdict"&gt;Verdict
&lt;/h2&gt;&lt;p&gt;Using an LLM for this kind of structured migration was surprisingly effective. The heavy lifting — script generation, config wiring, verification — is exactly the kind of task LLMs handle well. The human stays in charge of decisions and quality control.&lt;/p&gt;</description></item><item><title>Setup Tmux with Vim for Mac</title><link>https://minhhh.github.io/posts/setup-tmux-with-vim-for-mac/</link><pubDate>Fri, 03 Jul 2020 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/setup-tmux-with-vim-for-mac/</guid><description>&lt;h2 id="why-tmux"&gt;Why Tmux
&lt;/h2&gt;&lt;p&gt;When working on the Mac Terminal, I used to create multiple tabs. Then I can switch quickly between tabs using &lt;code&gt;Ctrl + Shift + [&lt;/code&gt; and &lt;code&gt;Ctrl + Shift + ]&lt;/code&gt;. While this works smoothly, one annoying problem is all the tabs will lose their content after reboot. So I&amp;rsquo;ve been looking for a solution that supports:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Multiple tabs. Easily switch between tabs&lt;/li&gt;
&lt;li&gt;Able to restore sessions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From my search, it&amp;rsquo;s quite obvious that &lt;code&gt;tmux&lt;/code&gt; is the solution to my problem. Another candidate is &lt;code&gt;screen&lt;/code&gt;, which I used for running some scripts on servers, but &lt;code&gt;screen&lt;/code&gt; is pretty much a dead project now and its functions are far inferior to &lt;code&gt;tmux&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="my-tmux-settings"&gt;My tmux settings
&lt;/h2&gt;&lt;p&gt;Tmux configuration is stored inside &lt;code&gt;~/.tmux.conf&lt;/code&gt;. On startup, &lt;code&gt;tmux&lt;/code&gt; will pick up the content on this file and run it. We will put our customization code in this file.&lt;/p&gt;
&lt;p&gt;First, we will remap reload key to &lt;code&gt;r&lt;/code&gt; so that we can reload &lt;code&gt;tmux.conf&lt;/code&gt; quickly.&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-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Set reload key to r&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;bind&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;~/.&lt;/span&gt;&lt;span class="n"&gt;tmux&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conf&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;Now, when we press &lt;code&gt;&amp;lt;prefix&amp;gt; r&lt;/code&gt;, &lt;code&gt;tmux.conf&lt;/code&gt; will be reloaded to reflect our new settings. The current &lt;code&gt;&amp;lt;prefix&amp;gt;&lt;/code&gt; is still &lt;code&gt;Ctrl B&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="remap-prefix-key"&gt;Remap prefix key
&lt;/h3&gt;&lt;p&gt;Prefix key is one of the most commonly used keys, so it&amp;rsquo;s super important to map it to a single key instead of &lt;code&gt;Ctrl B&lt;/code&gt; or &lt;code&gt;Ctrl A&lt;/code&gt; as some people might prefer.&lt;/p&gt;
&lt;p&gt;On Mac, one popular solution is to change the prefix to &lt;code&gt;Capslock&lt;/code&gt; key because it&amp;rsquo;s rarely used and very well positioned. We have 2 approaches to do this.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Approach 1: Remap &lt;code&gt;Capslock&lt;/code&gt; to &lt;code&gt;Esc&lt;/code&gt; and remap tmux &lt;code&gt;&amp;lt;prefix&amp;gt;&lt;/code&gt; to &lt;code&gt;Esc&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go to System Preferences =&amp;gt; Keyboard =&amp;gt; Modifier keys to remap &lt;code&gt;Capslock&lt;/code&gt; to &lt;code&gt;Esc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;One annoying problem is now we have to press &lt;code&gt;Esc&lt;/code&gt; or &lt;code&gt;Capslock&lt;/code&gt; twice in Vim. This is quite unacceptable as I use Vim a lot&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Approach 2: Remap &lt;code&gt;Capslock&lt;/code&gt; to &lt;code&gt;Home&lt;/code&gt; and remap tmux &lt;code&gt;&amp;lt;prefix&amp;gt;&lt;/code&gt; to &lt;code&gt;Home&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Normally you don&amp;rsquo;t have &lt;code&gt;Home&lt;/code&gt; in Mac keyboard, but fortunately there is a software called &lt;a class="link" href="https://github.com/tekezo/Karabiner-Elements" target="_blank" rel="noopener"
 &gt;Karabiner-Elements&lt;/a&gt; that allows you to completely customize your Mac keyboard.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;After that, remap tmux prefix key to &lt;code&gt;Home&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; set -g prefix Home
 bind-key Home send-prefix
 unbind C-b
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I learnt this from &lt;a class="link" href="https://blog.guilhermegarnier.com/2017/12/increasing-productivity-in-tmux-with-a-single-prefix-key/" target="_blank" rel="noopener"
 &gt;https://blog.guilhermegarnier.com/2017/12/increasing-productivity-in-tmux-with-a-single-prefix-key/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="fast-window-switching"&gt;Fast window switching
&lt;/h3&gt;&lt;p&gt;Windows in &lt;code&gt;tmux&lt;/code&gt; are the same concept as tabs in Terminal. I want to be able to switch between windows quickly without having to lift up all fingers.&lt;/p&gt;
&lt;p&gt;Fortunately, there&amp;rsquo;s an easy way to do this by mapping &lt;code&gt;next-window&lt;/code&gt; and &lt;code&gt;previous-window&lt;/code&gt; commands to &lt;code&gt;Shift Right&lt;/code&gt; and &lt;code&gt;Shift Left&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;/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;# Shift arrow to switch windows
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bind-key -r -T root S-Left previous-window
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bind-key -r -T root S-Right next-window
&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;You just have to hold Shift and press Left or Right arrows accordingly, which makes switching very fast.&lt;/p&gt;
&lt;p&gt;Next, we also want to be able to move a window to the left and right. We&amp;rsquo;ll do this by mapping &lt;code&gt;&amp;lt;prefix&amp;gt; n&lt;/code&gt; and &lt;code&gt;&amp;lt;prefix&amp;gt; p&lt;/code&gt; to swapping a window with the one of the left or right&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;# Prefix n/p to move window to the left or right
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bind-key -r -T prefix n { swap-window -t +1; next-window }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bind-key -r -T prefix p { swap-window -t -1; previous-window }
&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 effect, you will press &lt;code&gt;Capslock n&lt;/code&gt; or &lt;code&gt;Capslock p&lt;/code&gt;. However, unlike &lt;code&gt;Shift Left&lt;/code&gt; key combination, you cannot hold &lt;code&gt;Capslock&lt;/code&gt;. Instead, you will have to lift all your fingers and press 2 keys &lt;code&gt;Capslock&lt;/code&gt; and &lt;code&gt;n&lt;/code&gt; at the same time again. This is not a big problem since I&amp;rsquo;ll don&amp;rsquo;t usually move windows around a lot.&lt;/p&gt;
&lt;h3 id="restore-tmux-and-vim-sessions"&gt;Restore Tmux and Vim sessions
&lt;/h3&gt;&lt;p&gt;When it comes to restoring &lt;code&gt;tmux&lt;/code&gt; environment after system restart, the best solution is no other than &lt;a class="link" href="https://github.com/tmux-plugins/tmux-resurrect" target="_blank" rel="noopener"
 &gt;tmux-resurrect&lt;/a&gt;. The installation instruction in their website is rather easy to follow.&lt;/p&gt;
&lt;p&gt;After installing &lt;code&gt;tmux-resurrect&lt;/code&gt;, we can use &lt;code&gt;&amp;lt;prefix&amp;gt; Ctrl s&lt;/code&gt; to save, and &lt;code&gt;&amp;lt;prefix&amp;gt; Ctrl r&lt;/code&gt; to restore tmux sessions.&lt;/p&gt;
&lt;p&gt;Next and equally important, we also need a way to restore Vim session. I found &lt;a class="link" href="https://github.com/tpope/vim-obsession" target="_blank" rel="noopener"
 &gt;vim-obsession&lt;/a&gt; works well with &lt;code&gt;tmux-resurrect&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The part for tmux-resurrect in my &lt;code&gt;.tmux.conf&lt;/code&gt; looks 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;/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;# tmux-resurrect
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;set -g @resurrect-processes &amp;#39;&amp;#34;~sudo pmset&amp;#34; &amp;#34;~Vim&amp;#34;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;set -g @resurrect-capture-pane-contents &amp;#39;on&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;set -g @resurrect-strategy-vim &amp;#39;session&amp;#39;
&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;Pay attention to the line &lt;code&gt;set -g @resurrect-processes '&amp;quot;~sudo pmset&amp;quot; &amp;quot;~Vim&amp;quot;'&lt;/code&gt;. There are a number of default commands such as &lt;code&gt;vi vim nvim emacs man less more tail top htop irssi weechat mutt&lt;/code&gt; that &lt;code&gt;tmux-resurrect&lt;/code&gt; will automatically restore, but other commands outside of this list will not be restored automatically. So this line tells &lt;code&gt;tmux-resurrect&lt;/code&gt; to restores extra commands if the command string match what is specified in the &lt;code&gt;@resurrect-processes&lt;/code&gt; variable. In this case, since MacVim uses the command &lt;code&gt;Vim&lt;/code&gt; and not &lt;code&gt;vim&lt;/code&gt;, we have to specify &lt;code&gt;&amp;quot;~Vim&amp;quot;&lt;/code&gt; so &lt;code&gt;tmux-resurrect&lt;/code&gt; know that it should restore Vim window. Another command I use is &lt;code&gt;sudo pmset&lt;/code&gt;, so I specify &lt;code&gt;&amp;quot;~sudo pmset&amp;quot;&lt;/code&gt; here. For more details, read &lt;a class="link" href="https://github.com/tmux-plugins/tmux-resurrect/blob/master/docs/restoring_programs.md" target="_blank" rel="noopener"
 &gt;https://github.com/tmux-plugins/tmux-resurrect/blob/master/docs/restoring_programs.md&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Finally, there are 2 problems when you restore tmux sessions. First, if you create temporary tmux session first, so that you can run the command &lt;code&gt;&amp;lt;prefix&amp;gt; Ctrl r&lt;/code&gt; to restore previous sessions, you will have to kill the temporary session manually, which is annoying. Second, the restored windows will not have &lt;code&gt;automatic-rename&lt;/code&gt; set to &lt;code&gt;on&lt;/code&gt;, so their titles will not be updated automatically, which is equally annoying. To deal with these 2 problem, I use the following bash function:&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;/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;mux() {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; tmux new -d -s delete-me &amp;amp;&amp;amp; (tmux run-shell ~/.tmux/plugins/tmux-resurrect/scripts/restore.sh &amp;amp;&amp;amp; tmux kill-session -t delete-me) &amp;amp;&amp;amp;\
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; (for session_window in $(tmux list-windows -a -F &amp;#39;#{session_name}:#{window_index}&amp;#39;); do
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; tmux set-window-option -t $session_window automatic-rename on
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; done) &amp;amp;&amp;amp;\
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; tmux attach || tmux attach
&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 function is modified from &lt;a class="link" href="https://gist.github.com/rootulp/93f67511ae97c20c4d32b600a5ab6a8d" target="_blank" rel="noopener"
 &gt;https://gist.github.com/rootulp/93f67511ae97c20c4d32b600a5ab6a8d&lt;/a&gt;. To use it, simply type &lt;code&gt;mux&lt;/code&gt; in the terminal and it will restore previous session and reattach to it automatically. If there are multiple previous sessions, you can use &lt;code&gt;tmux a -t &amp;lt;name&amp;gt;&lt;/code&gt; to attach to the session you want.&lt;/p&gt;
&lt;h3 id="vim-binding-in-copy-mode"&gt;Vim binding in copy mode
&lt;/h3&gt;&lt;p&gt;Similar to &lt;code&gt;screen&lt;/code&gt;, &lt;code&gt;tmux&lt;/code&gt; has a copy mode to let you scroll through the content of your window, and copy/paste the parts you like.&lt;/p&gt;
&lt;p&gt;Below is the setting to make this easier&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;# Use vim bindings in copy mode too
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;set -g status-keys vi # in the status/command prompt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;setw -g mode-keys vi
&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;# Setup &amp;#39;v&amp;#39; to begin selection as in Vim
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bind-key -T copy-mode-vi v send-keys -X begin-selection
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel &amp;#34;reattach-to-user-namespace pbcopy&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;unbind -T copy-mode-vi Enter ; bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel &amp;#34;reattach-to-user-namespace pbcopy&amp;#34;
&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;You can start the copy mode with &lt;code&gt;&amp;lt;prefix&amp;gt; [&lt;/code&gt;.
Then you navigate the window content with Vim-mode keys &lt;code&gt;h j k l&lt;/code&gt;. &lt;code&gt;v&lt;/code&gt; to start selecting. &lt;code&gt;y&lt;/code&gt; or &lt;code&gt;Enter&lt;/code&gt; to copy.&lt;/p&gt;
&lt;h3 id="customize-status-bar"&gt;Customize Status bar
&lt;/h3&gt;&lt;p&gt;The default tmux status bar position is at the top, which is ideal for showing tab-like window titles. I want to maximize the space for showing window title, so I limit the left part and right part of the status bar to very basic information.&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;/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;# Set Colors
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;set -g default-terminal &amp;#34;screen-256color&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;setw -g window-status-style fg=colour254,bg=colour102
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;setw -g window-status-format &amp;#39;#I:#W &amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;setw -g window-status-current-style fg=colour254,bg=colour30,bright
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;setw -g window-status-current-format &amp;#39;#I:#W &amp;#39;
&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;# Set status bar
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;set -g status-bg colour252
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;set -g status-fg black
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;set -g status-left-length 90
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;set -g status-right-length 60
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;set -g status-left &amp;#34;#[fg=green]#S &amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;set -g status-justify left
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;set -g status-right &amp;#39; #[fg=green]%a %d %b %R&amp;#39;
&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 left part of status bar, specified by &lt;code&gt;status-left&lt;/code&gt;, only shows session title. The right part shows current date and time. Other colors and background colors are customized based on personal preferences.&lt;/p&gt;
&lt;h3 id="customize-window-title"&gt;Customize window title
&lt;/h3&gt;&lt;p&gt;For me, one important feature is a good window title, so that I can understand what&amp;rsquo;s in a window just by glancing at the title. One format that works quite well for me has these features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Show full path of the current directory if possible. Replace home directory with &lt;code&gt;~&lt;/code&gt; for brevity.&lt;/li&gt;
&lt;li&gt;Limit the length of the path to 20 characters so that the title is not too long&lt;/li&gt;
&lt;li&gt;But always try to show at least the full name of the current directory. This will deal with very long directory name that if truncated to 20 characters, will be hard to guess the full name.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The code to achieve these features is listed below. It uses &lt;code&gt;awk&lt;/code&gt; because &lt;code&gt;awk&lt;/code&gt; is best for one-liner kinds of programs.&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;# Set window title
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;set -g automatic-rename on
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;set -g automatic-rename-format &amp;#34;#(echo &amp;#39;#{pane_current_path}&amp;#39; | awk &amp;#39;{split($0, a, \&amp;#34;/\&amp;#34;);basename=a[length(a)];cmd=\&amp;#34;pwd\&amp;#34;; cmd | getline homepath; close(cmd);baselength=length(basename);i=index($0,homepath);path=$0;if (i==1) { path=\&amp;#34;~\&amp;#34;substr(path,length(homepath)+1,length(path)); };maxlength=15; if (length(basename) &amp;gt; maxlength-3) { print \&amp;#34;../\&amp;#34;basename; } else if (length(path) &amp;gt; maxlength) {print \&amp;#34;..\&amp;#34;substr(path, length(path)-maxlength+3, length(path)) } else print path }&amp;#39;) - #{pane_current_command}&amp;#34;
&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;If you want to customize this code, you can change &lt;code&gt;maxlength=15&lt;/code&gt; to whatever you like. If you want to customize further, then you need to get a bit more involved with &lt;code&gt;awk&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The result is pretty good as far as I&amp;rsquo;m concerned. Here are some examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;~/work&lt;/code&gt;: Shorter than 15 characters, so it shows full path&lt;/li&gt;
&lt;li&gt;&lt;code&gt;..rk/webarchive&lt;/code&gt;: full path is &lt;code&gt;~/work/webarchive&lt;/code&gt;, so it truncates to 13 characters and replaces the rest with &lt;code&gt;..&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;../a-very-long-folder-name&lt;/code&gt;: The folder name itself is longer than 15 characters, so it&amp;rsquo;s kept in tact and then prefixed with &lt;code&gt;../&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="conclusion"&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;Those are my main points of customization of &lt;code&gt;tmux&lt;/code&gt;. Granted there are other functions that can be customized such as pane splitting, pane switching, mouse mode, etc, but I don&amp;rsquo;t use those functions much if at all in my every day activities.&lt;/p&gt;
&lt;p&gt;My tmux settings can be found at &lt;a class="link" href="https://github.com/minhhh/dotfiles/blob/master/tmux/.tmux.conf" target="_blank" rel="noopener"
 &gt;https://github.com/minhhh/dotfiles/blob/master/tmux/.tmux.conf&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Setup nodejs development environment with conda and nodeenv</title><link>https://minhhh.github.io/posts/setup-nodejs-development-environment-with-conda-and-nodeenv/</link><pubDate>Fri, 09 Aug 2019 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/setup-nodejs-development-environment-with-conda-and-nodeenv/</guid><description>&lt;p&gt;When you want to develop your nodejs project on different node versions, you have some tools to help you install multiple node versions such as &lt;code&gt;nave&lt;/code&gt;, &lt;code&gt;nvm&lt;/code&gt;, &lt;code&gt;n&lt;/code&gt;. However, this is still not as nice as &lt;code&gt;virtualenv&lt;/code&gt; in Python, where you have completely isolated environments so one project does not affect the others.&lt;/p&gt;
&lt;p&gt;Fortunately, there is a tool called &lt;a class="link" href="https://github.com/ekalinin/nodeenv" target="_blank" rel="noopener"
 &gt;nodeenv&lt;/a&gt; that can help you create isolated node.js environment the same way as &lt;code&gt;virtualenv&lt;/code&gt;. Using &lt;code&gt;nodeenv&lt;/code&gt; is already good enough, but if you don&amp;rsquo;t want to store the virtualenv folder in the same project folder, then you would need some other tool to manage virtualenv folders globally. There are 2 options: &lt;code&gt;conda&lt;/code&gt; and &lt;code&gt;pipenv&lt;/code&gt;. &lt;code&gt;pipenv&lt;/code&gt; does not integrate very well with shell scripts because you have to start a separate pipenv shell. &lt;code&gt;conda&lt;/code&gt; is perfect because it can manage all kinds of packages, not just Python or nodejs and it&amp;rsquo;s very compatible with shell scripts.&lt;/p&gt;
&lt;p&gt;In conclusion, using &lt;code&gt;conda&lt;/code&gt; and &lt;code&gt;nodeenv&lt;/code&gt; is a much better choice than just &lt;code&gt;nave&lt;/code&gt; or &lt;code&gt;nvm&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Webview with schema</title><link>https://minhhh.github.io/posts/webview-with-schema/</link><pubDate>Mon, 08 Jan 2018 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/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/colored-project-folder/</link><pubDate>Mon, 27 Nov 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/colored-project-folder/</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/test-assetbundle-in-unity-2017/</link><pubDate>Tue, 14 Nov 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/test-assetbundle-in-unity-2017/</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/unity-plugin-usplitalpha/</link><pubDate>Thu, 26 Oct 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-plugin-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-and-missing-script-finder/</link><pubDate>Mon, 10 Jul 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-asset-reference-finder-and-missing-script-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-prefab-best-practices/</link><pubDate>Thu, 06 Jul 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-prefab-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>How to backup your gmail account</title><link>https://minhhh.github.io/posts/how-to-backup-your-gmail-account/</link><pubDate>Fri, 26 May 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/how-to-backup-your-gmail-account/</guid><description>&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="http://www.zdnet.com/article/ultimate-guide-to-gmail-backup/" target="_blank" rel="noopener"
 &gt;The 2017 ultimate guide to Gmail backup&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you want to backup mail from one gmail to another gmail you can use the following software:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/jay0lee/got-your-back/" target="_blank" rel="noopener"
 &gt;got-your-back&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://gmvault.org" target="_blank" rel="noopener"
 &gt;gmvault&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Introducing UAsync</title><link>https://minhhh.github.io/posts/introducing-uasync/</link><pubDate>Mon, 08 May 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/introducing-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/using-unity-assert/</link><pubDate>Tue, 25 Apr 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/using-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>Resources for learning Blender</title><link>https://minhhh.github.io/posts/resources-for-learning-blender/</link><pubDate>Tue, 21 Mar 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/resources-for-learning-blender/</guid><description>&lt;p&gt;This is collection of resources for learning Blender from the beginning&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="http://gryllus.net/Blender/3D.html" target="_blank" rel="noopener"
 &gt;Blender 3D Design Course&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.youtube.com/watch?v=JmVxCDZ6lEM" target="_blank" rel="noopener"
 &gt;Unity Mega-Tutorial: Blender 3D Modelling Tricks, High-Speed Physics, and Real-Time Reflections!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.youtube.com/watch?v=lY6KPrc4uMw&amp;amp;list=PLda3VoSoc_TR7X7wfblBGiRz-bvhKpGkS" target="_blank" rel="noopener"
 &gt;Blender 2.7 Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.reddit.com/r/gamedev/comments/43kes4/learning_3d_modelling_as_a_single_indie_developer/" target="_blank" rel="noopener"
 &gt;Learning 3D modelling as a single indie developer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://www.blenderguru.com/articles/12-useful-blender-addons-everyone-should-use/" target="_blank" rel="noopener"
 &gt;12 (More) Blender Addons Everyone Should Use&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Low poly
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.youtube.com/watch?v=w38wzDREnKk&amp;amp;index=3&amp;amp;list=PLv1DCiCg2KQLpl6mzDHsWZ70016emDfUu" target="_blank" rel="noopener"
 &gt;Low Poly Planet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.youtube.com/watch?v=_pK2Ya0CMww" target="_blank" rel="noopener"
 &gt;Learn to Create Geometric Assets in Blender&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.youtube.com/watch?v=oDWfB9JAZ9s" target="_blank" rel="noopener"
 &gt;GAME ASSET TUTORIAL&lt;/a&gt; In this Video Tutorial series for Beginners, we will create Low Poly Barrel Game Asset using Blender, Photoshop, and Unity.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.youtube.com/watch?v=JjW6r10Mlqs" target="_blank" rel="noopener"
 &gt;Create any low poly animal | Blender | 10 mins&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Unity Jelly Physics</title><link>https://minhhh.github.io/posts/unity-jelly-physics/</link><pubDate>Tue, 14 Mar 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-jelly-physics/</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-mesh-morphing/</link><pubDate>Thu, 09 Mar 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-mesh-morphing/</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>How to force Gmail to check your POP3 account as often as possible</title><link>https://minhhh.github.io/posts/how-to-force-gmail-to-check-your-pop3-account-as-often-as-possible/</link><pubDate>Mon, 27 Feb 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/how-to-force-gmail-to-check-your-pop3-account-as-often-as-possible/</guid><description>&lt;p&gt;&lt;a class="link" href="https://web.archive.org/web/20160306102134/http://rakowski.pro/how-to-force-gmail-to-check-your-pop3-account-as-often-as-possible/" target="_blank" rel="noopener"
 &gt;How to force Gmail to check your POP3 account as often as possible&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Unity Object Pooling</title><link>https://minhhh.github.io/posts/unity-object-pooling/</link><pubDate>Fri, 24 Feb 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-object-pooling/</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-unit-testing/</link><pubDate>Tue, 21 Feb 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-unit-testing/</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/property-backing-field-drawer/</link><pubDate>Tue, 14 Feb 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/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/better-unity-workflow-with-command-line/</link><pubDate>Thu, 02 Feb 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/better-unity-workflow-with-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-player-data-on-mobile/</link><pubDate>Wed, 01 Feb 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/best-practices-in-persisting-player-data-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/using-webp-texture-format-in-unity/</link><pubDate>Wed, 18 Jan 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/using-webp-texture-format-in-unity/</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>Git branching strategy</title><link>https://minhhh.github.io/posts/git-branching-strategy/</link><pubDate>Mon, 09 Jan 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/git-branching-strategy/</guid><description>&lt;p&gt;Branching strategy is an important part of using git correctly. Without a proper branching strategy, even with a few people in the project, you will create a mess in no time. Below is a simple branching strategy that can be applied to various situation. It is also available on github &lt;a class="link" href="https://github.com/minhhh/git-manual/blob/master/branching_strategy.md" target="_blank" rel="noopener"
 &gt;here&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="branch-description"&gt;Branch Description
&lt;/h2&gt;&lt;h3 id="master"&gt;master
&lt;/h3&gt;&lt;p&gt;Master branch represents what&amp;rsquo;s in live. It should not be modified directly.&lt;/p&gt;
&lt;p&gt;When it is deployed, it will be tagged so that we can revert to a certain deployment later.&lt;/p&gt;
&lt;p&gt;Lifetime: forever&lt;/p&gt;
&lt;h3 id="releasexxx"&gt;release/xxx
&lt;/h3&gt;&lt;p&gt;After finishing a feature, make a release branch off the develop branch, merge all the necessary feature branches and do final test. Bugs found in this final QA phases can also be hotfixed in the same branch. After everything is complete, we will rebase this branch over &lt;code&gt;develop&lt;/code&gt; branch, then the rebase branch will be merged into the &lt;code&gt;master&lt;/code&gt; branch for release in Live environment.&lt;/p&gt;
&lt;p&gt;Lifetime: Feature Finish ~ Release in Live&lt;/p&gt;
&lt;h3 id="hotfixxxx"&gt;hotfix/xxx
&lt;/h3&gt;&lt;p&gt;If a bug is found in production, we wil branch hotfix branch off master.&lt;/p&gt;
&lt;p&gt;Lifetime: Bugfix ~ Release in Live&lt;/p&gt;
&lt;h3 id="develop"&gt;develop
&lt;/h3&gt;&lt;p&gt;This is the main branch where feature branches should be branched off. Trivial changes can be directly applied to develop if you are sure it should go into the next version. Major feature/bugfix branches have to go through PR process to be merged into develop.&lt;/p&gt;
&lt;p&gt;Lifetime: forever&lt;/p&gt;
&lt;h3 id="featurexxx"&gt;feature/xxx
&lt;/h3&gt;&lt;p&gt;Feature branch should be branched off develop. While working on feature branches, developers can choose to merge develop into it. Once QA is completed on the feature branch, developers can send PR.&lt;/p&gt;
&lt;p&gt;Lifetime: Feature development ~ PR merge&lt;/p&gt;
&lt;h3 id="art"&gt;art
&lt;/h3&gt;&lt;p&gt;Art branch lives forever. Artists only need to deal with this branch.&lt;/p&gt;
&lt;p&gt;Lifetime: forever&lt;/p&gt;
&lt;h2 id="role-descriptions"&gt;Role Descriptions
&lt;/h2&gt;&lt;h3 id="engineer--uidesigner"&gt;Engineer / UIDesigner
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;develop -&amp;gt; feature&lt;/li&gt;
&lt;li&gt;feature -&amp;gt; develop (PR)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="artist"&gt;Artist
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;art -&amp;gt; art&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="lead-engineer"&gt;Lead Engineer
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;develop -&amp;gt; release&lt;/li&gt;
&lt;li&gt;release -&amp;gt; develop&lt;/li&gt;
&lt;li&gt;master -&amp;gt; hotfix&lt;/li&gt;
&lt;li&gt;hotfix -&amp;gt; master&lt;/li&gt;
&lt;li&gt;hotfix -&amp;gt; develop&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Unity package management</title><link>https://minhhh.github.io/posts/unity-package-management/</link><pubDate>Mon, 09 Jan 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-package-management/</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/dither-unity-textures-to-save-memory/</link><pubDate>Thu, 05 Jan 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/dither-unity-textures-to-save-memory/</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/using-unity-mecanim-animation-system/</link><pubDate>Mon, 02 Jan 2017 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/using-unity-mecanim-animation-system/</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/finite-state-machine-for-unity/</link><pubDate>Wed, 28 Dec 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/finite-state-machine-for-unity/</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-editor-extensions/</link><pubDate>Thu, 22 Dec 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/understanding-unity-editor-extensions/</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/understanding-unity-scriptableobject/</link><pubDate>Thu, 15 Dec 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/understanding-unity-scriptableobject/</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>Understanding Reactive</title><link>https://minhhh.github.io/posts/understanding-reactive/</link><pubDate>Sun, 04 Dec 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/understanding-reactive/</guid><description>&lt;h2 id="reactive-tutorials-and-manual"&gt;Reactive tutorials and manual
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="https://gist.github.com/staltz/868e7e9bc2a7b8c1f754" target="_blank" rel="noopener"
 &gt;The introduction to Reactive Programming you&amp;rsquo;ve been missing&lt;/a&gt;&lt;/strong&gt; Best introduction tutorial to Reactive Programming&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="http://www.introtorx.com/" target="_blank" rel="noopener"
 &gt;Introduction to Rx&lt;/a&gt;&lt;/strong&gt; This book aims to teach you:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;about the new types that Rx will provide&lt;/li&gt;
&lt;li&gt;about the extension methods and how to use them&lt;/li&gt;
&lt;li&gt;how to manage subscriptions to &amp;ldquo;sequences&amp;rdquo; of data&lt;/li&gt;
&lt;li&gt;how to visualize &amp;ldquo;sequences&amp;rdquo; of data and sketch your solution before coding it&lt;/li&gt;
&lt;li&gt;how to deal with concurrency to your advantage and avoid common pitfalls&lt;/li&gt;
&lt;li&gt;how to compose, aggregate and transform streams&lt;/li&gt;
&lt;li&gt;how to test your Rx code&lt;/li&gt;
&lt;li&gt;some guidance on best practices when using Rx.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="http://reactivex.io/intro.html" target="_blank" rel="noopener"
 &gt;ReactiveX&lt;/a&gt;&lt;/strong&gt; The home of ReactiveX. Introduction, All operators are illustrated with graphical marble diagrams, there makes easy to understand&lt;/p&gt;
&lt;h2 id="reactive-design-patterns"&gt;Reactive Design Patterns
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="http://www.slideshare.net/ZalandoTech/reactive-design-patterns-a-talk-by-typesafes-dr-roland-kuhn" target="_blank" rel="noopener"
 &gt;Reactive Design Patterns&lt;/a&gt;&lt;/strong&gt; by Dr. Roland Kuhn: leader of Typesafe’s Akka project, and coauthor of the book Reactive Design Patterns and the Reactive Manifesto. Roland highlighted the importance of making reactive software: of considering responsiveness, maintainability, elasticity and scalability from the outset of development. He explored several architecture elements that are commonly found in reactive systems, such as the circuit breaker, various replication techniques, and flow control protocols. These patterns are language-agnostic and also independent of the abundant choice of reactive programming frameworks and libraries.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="https://www.lightbend.com/resources/e-book/reactive-design-patterns" target="_blank" rel="noopener"
 &gt;Reactive Design Patterns&lt;/a&gt;&lt;/strong&gt; by Roland Kuhn and Jamie Allen&lt;/p&gt;
&lt;h2 id="reactive-usecases"&gt;Reactive usecases
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="http://blog.flowdock.com/2013/01/22/functional-reactive-programming-with-bacon-js/" target="_blank" rel="noopener"
 &gt;Bacon.js&lt;/a&gt;&lt;/strong&gt; introduces FRP concepts and benefits with Bacon.js, an FRP library for both browsers and server-side JS&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="https://www.youtube.com/watch?v=mS264h8KGwk" target="_blank" rel="noopener"
 &gt;Immutability, interactivity &amp;amp; JavaScript&lt;/a&gt;&lt;/strong&gt; Surprisingly the high performance mutation available in modern JavaScript engines is a great foundation for building high performance immutable collections. Even more surprisingly efficient immutable collections permit new ways of approaching user interface programming. While the details will be in Om, an immutable user interface toolkit written in ClojureScript over Facebook&amp;rsquo;s React, the talk will be primarily focused on high level concepts easily ported to JavaScript. We&amp;rsquo;ll dive in and see how trees of JavaScript arrays can permit building these efficient immutable collections. Then we&amp;rsquo;ll see how embracing immutable values dramatically simplifies some classic hard problems in client side programming including but not limited to undo, error playback, and online/offline synchronization.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="https://www.youtube.com/watch?v=sTSQlYX5DU0" target="_blank" rel="noopener"
 &gt;What does it mean to be Reactive&lt;/a&gt;&lt;/strong&gt; The inimitable Erik Meijer delivering his opening keynote to React 2014&lt;/p&gt;</description></item><item><title>Unity Texture compression and optimization</title><link>https://minhhh.github.io/posts/unity-texture-compression-and-optimization/</link><pubDate>Sat, 03 Dec 2016 00:01:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-texture-compression-and-optimization/</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/unity-geometry-distortion-on-child-object/</link><pubDate>Sat, 03 Dec 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-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/scale-shuriken-particle-system/</link><pubDate>Tue, 29 Nov 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/scale-shuriken-particle-system/</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>Game backends</title><link>https://minhhh.github.io/posts/game-backends/</link><pubDate>Fri, 25 Nov 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/game-backends/</guid><description>&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="http://blog.soom.la/2016/02/top-10-parse-alternatives-game-backend.html" target="_blank" rel="noopener"
 &gt;Top 10 Parse Alternatives For Your Game Backend&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GameSparks&lt;/li&gt;
&lt;li&gt;PlayFab&lt;/li&gt;
&lt;li&gt;HeroicLabs&lt;/li&gt;
&lt;li&gt;Gamedonia&lt;/li&gt;
&lt;li&gt;Kii&lt;/li&gt;
&lt;li&gt;Kinvey&lt;/li&gt;
&lt;li&gt;BrainCloud&lt;/li&gt;
&lt;li&gt;GamuaFlox&lt;/li&gt;
&lt;li&gt;App42&lt;/li&gt;
&lt;li&gt;Photon&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="link" href="http://www.pocketgamer.biz/feature/59149/12-reasons-to-use-gamesparks/" target="_blank" rel="noopener"
 &gt;Why should you use GameSparks&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GameSparks vs PlayFab vs Firebase&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.reddit.com/r/gamedev/comments/4otyeb/gamesparks_vs_playfab/" target="_blank" rel="noopener"
 &gt;Gamesparks vs PlayFab?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://spaceteamadmirals.club/blog/spaceteam-is-coming-to-your-library/" target="_blank" rel="noopener"
 &gt;Spaceteam&lt;/a&gt; uses GameSparks&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://forum.unity3d.com/threads/firebase-vs-playfab-vs-gamesparks.451840/" target="_blank" rel="noopener"
 &gt;Firebase vs Playfab vs Gamesparks?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Writing Unity iOS plugin</title><link>https://minhhh.github.io/posts/writing-unity-ios-plugin/</link><pubDate>Fri, 25 Nov 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/writing-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/how-to-do-blur-effect-in-unity/</link><pubDate>Thu, 24 Nov 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/how-to-do-blur-effect-in-unity/</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-local-network-multiplayer/</link><pubDate>Mon, 21 Nov 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/unity-local-network-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/setting-sorting-layer-and-order-in-layer-of-mesh-renderer/</link><pubDate>Sun, 30 Oct 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/setting-sorting-layer-and-order-in-layer-of-mesh-renderer/</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-script-execution-order/</link><pubDate>Fri, 28 Oct 2016 00:01:00 +0700</pubDate><guid>https://minhhh.github.io/posts/when-to-use-script-execution-order/</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-specific-code-when-editor-starts/</link><pubDate>Fri, 28 Oct 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/run-specific-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/mvc-in-unity/</link><pubDate>Thu, 27 Oct 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/mvc-in-unity/</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>Understanding Promises</title><link>https://minhhh.github.io/posts/understanding-promises/</link><pubDate>Wed, 26 Oct 2016 00:02:00 +0700</pubDate><guid>https://minhhh.github.io/posts/understanding-promises/</guid><description>&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="https://www.promisejs.org/" target="_blank" rel="noopener"
 &gt;Understand promise vs callback&lt;/a&gt;&lt;/strong&gt; The ABCs of promises&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="https://promise-nuggets.github.io/" target="_blank" rel="noopener"
 &gt;Promise nuggets&lt;/a&gt;&lt;/strong&gt; More examples of promises&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="https://spion.github.io/posts/why-i-am-switching-to-promises.html" target="_blank" rel="noopener"
 &gt;Why I am switching to promises&lt;/a&gt;&lt;/strong&gt; A guy switches from callbacks to promises.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html" target="_blank" rel="noopener"
 &gt;We have a problem with promises&lt;/a&gt;&lt;/strong&gt; Promises are not so easy to use if you don&amp;rsquo;t know exactly how to use them properly. Try to avoid the mistakes of using something without fully understanding it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="https://gist.github.com/briancavalier/842626" target="_blank" rel="noopener"
 &gt;Retry patterns&lt;/a&gt;&lt;/strong&gt; Several patterns of retry in promises&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="https://github.com/icodeforlove/promise-retryer" target="_blank" rel="noopener"
 &gt;promise-retryer&lt;/a&gt;&lt;/strong&gt; Another way to do retry with promise which supports
* custom delays based on attempts
* maxRetries
* promise result validation (if it fails then keep trying)&lt;/p&gt;</description></item><item><title>Building social networks</title><link>https://minhhh.github.io/posts/building-social-networks/</link><pubDate>Wed, 26 Oct 2016 00:01:00 +0700</pubDate><guid>https://minhhh.github.io/posts/building-social-networks/</guid><description>&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="http://www.feverbee.com/2010/01/how-to-build-an-online-community-the-ultimate-list-of-resources.html" target="_blank" rel="noopener"
 &gt;How To Build An Online Community: The Ultimate List Of Resources&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="http://www.communityspark.com/" target="_blank" rel="noopener"
 &gt;CommunitySpark&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="http://headrush.typepad.com/creating_passionate_users/2006/12/how_to_build_a_.html" target="_blank" rel="noopener"
 &gt;How to Build a User Community&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="http://www.chrisbrogan.com/25-ways-to-build-your-community/" target="_blank" rel="noopener"
 &gt;25 Ways to Build Your Community&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="http://blog.guykawasaki.com/2006/02/the_art_of_crea.html#axzz165byhjtT" target="_blank" rel="noopener"
 &gt;The Art of Creating a Community&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a class="link" href="http://www.digital-web.com/articles/building_an_online_community/" target="_blank" rel="noopener"
 &gt;Building an Online Community: Just Add Water&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>The power of checklist</title><link>https://minhhh.github.io/posts/the-power-of-checklist/</link><pubDate>Mon, 10 Oct 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/the-power-of-checklist/</guid><description>&lt;h2 id="why"&gt;Why
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;The world has become more complex&lt;/li&gt;
&lt;li&gt;Our brain has not changed much&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="examples"&gt;Examples
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Checklists in aviation help alleviate accidents&lt;/li&gt;
&lt;li&gt;Checklists in construction makes the failure list very low&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="benefits"&gt;Benefits
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Checklists verify that the necessary minimum gets done&lt;/strong&gt; Because sometimes the most important stuff is the simple ones.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Checklists free up mental RAM&lt;/strong&gt; Checklists don’t replace judgment, they enhance it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Checklists instill discipline&lt;/strong&gt; and increase the chance of stuff getting done.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Checklists save time&lt;/strong&gt; because you spend less time fixing simple mistakes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="how"&gt;How
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Investigate your failures and look for “killer items.”&lt;/strong&gt; Look for failure or friction points in the tasks you do routinely&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Focus only on the “stupid” essential stuff that’s frequently overlooked or skipped&lt;/strong&gt; Just focus on putting down the “stupid” but essential stuff that you frequently miss. Your checklist should have no more than 9 items on it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Decide if you need a “communication” checklist&lt;/strong&gt; Most checklists are likely procedural (they lay out things you need to do), but some tasks or projects are so complex that communicating with others becomes vital to managing all the moving pieces. In such a case, create a dedicated communication checklist and make sure it includes who needs to talk to whom, by when, and about what.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Decide if your checklist will be a “DO-CONFIRM” or “READ-DO” checklist&lt;/strong&gt;. With DO-CONFIRM checklists, you do your job from memory and experience, but then at a certain point you stop to go through your list to verify you did everything. READ-DO checklists require you to read and perform a task on the checklist before you can move to the next task. If you need more flexibility, go with DO-CONFIRM; if you need more exactness go with READ-DO.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Test your checklist in the real world and refine as needed&lt;/strong&gt;. If you’re still experiencing the same failures or if the checklist makes work cumbersome to the point that it becomes a stumbling block, then you need to refine your checklist.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="references"&gt;References
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="http://www.artofmanliness.com/2014/12/08/the-power-of-checklists/" target="_blank" rel="noopener"
 &gt;The Power of Checklists&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Generate one-time password from the command line</title><link>https://minhhh.github.io/posts/generate-one-time-password-from-the-command-line/</link><pubDate>Sun, 02 Oct 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/generate-one-time-password-from-the-command-line/</guid><description>&lt;p&gt;One-time password is pretty common these days for any type of account that offers two-factor authentication. We can use an app to generate OTP but it would be troublesome if we lost the app or the phone. Fortunately there&amp;rsquo;s a simple way to generate OTP programmatically using libraries such as Python &lt;code&gt;OneTimePass&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;First, install &lt;code&gt;OneTimePass&lt;/code&gt; with &lt;code&gt;pip&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;/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;pip install onetimepass
&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 you get the secret generated from the service provider you&amp;rsquo;re using. Normally it would be a time-based token, such as the ones you use for Google Authenticator.&lt;/p&gt;
&lt;p&gt;To get time-based token you invoke 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;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;import onetimepass as otp
&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;my_secret = &amp;#39;MFRGGZDFMZTWQ2LK&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;my_token = otp.get_totp(my_secret)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;print my_token
&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;Remember to store your secret safely.&lt;/p&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><item><title>Maple.js Deconstructed</title><link>https://minhhh.github.io/posts/maple.js-deconstructed/</link><pubDate>Sun, 25 Sep 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/maple.js-deconstructed/</guid><description>&lt;p&gt;&lt;a class="link" href="https://github.com/BonsaiDen/Maple.js" target="_blank" rel="noopener"
 &gt;Maple.js&lt;/a&gt; is a simple event-based multiplayer framework using Node.js&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Deconstruction&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Maple provides a base class for &lt;code&gt;Client&lt;/code&gt; and &lt;code&gt;Server&lt;/code&gt;. Your specific game code should inherit these base classes.&lt;/li&gt;
&lt;li&gt;The supported functionality includes:
&lt;ul&gt;
&lt;li&gt;Connect/Disconnect&lt;/li&gt;
&lt;li&gt;Ping server&lt;/li&gt;
&lt;li&gt;Handle arbitrary message&lt;/li&gt;
&lt;li&gt;Sync client server update tick on every frame&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The problems with Maple are:
&lt;ul&gt;
&lt;li&gt;Use Websocket, which is slow&lt;/li&gt;
&lt;li&gt;Require too much sync and only applicable for Round-based games.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Osmus Deconstructed</title><link>https://minhhh.github.io/posts/osmus-deconstructed/</link><pubDate>Sun, 25 Sep 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/osmus-deconstructed/</guid><description>&lt;p&gt;&lt;a class="link" href="https://github.com/borismus/osmus" target="_blank" rel="noopener"
 &gt;Osmus&lt;/a&gt; is a tech demo of a HTML5 multiplayer game inspired by &lt;a class="link" href="http://www.osmos-game.com/" target="_blank" rel="noopener"
 &gt;Osmos&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Deconstruction&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Osmus uses node.js for the server and HTML5 Canvas with Javascript on the client side. The simulation code is shared between client and server.&lt;/li&gt;
&lt;li&gt;Regarding network, Osmus uses &lt;code&gt;socket.io&lt;/code&gt;. &lt;code&gt;Socket.io&lt;/code&gt; is quite stable and performant so this is ok.&lt;/li&gt;
&lt;li&gt;The multiplayer architecture is Server/Client, with the server being the sole authority. All inputs from any client will be rebroadcast to all clients in the room. There are several problems with this approach
&lt;ul&gt;
&lt;li&gt;Not scalable: Simply rebroadcast all messages will increase the load on the server exponentially so this is totally not acceptable. Some sort of rate limit should be applied, such as only sending messages to viewable entities.&lt;/li&gt;
&lt;li&gt;Sudden positional jump on client: If the client entities can move around, then client simulation. client prediction and interpolation with server states should be applied to ensure smooth movement.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Autoformat C# code from command line</title><link>https://minhhh.github.io/posts/autoformat-c%23-code-from-command-line/</link><pubDate>Sun, 11 Sep 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/autoformat-c%23-code-from-command-line/</guid><description>&lt;p&gt;We all need a tool to format code automatically according to project&amp;rsquo;s convention. Using an IDE like Visual Studio, Xamarin or MonoDevelop, we can format code easily. However, it&amp;rsquo;s not always convenient to fireup the IDE just for formatting some code, and also having a tool on the command line makes it easier to integrate with other workflows. Therefore, it&amp;rsquo;s great if we have some tool which runs on the command line to auto format our code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Customizable format options&lt;/li&gt;
&lt;li&gt;Format whole directory recursively&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The second requirement is relatively easy to implement if we have a tool to format a single file on the commandline because we can just use &lt;code&gt;find&lt;/code&gt; with some filter to iteratively apply the tool to a bunch of files.&lt;/p&gt;
&lt;h2 id="solution-1-astyle"&gt;Solution 1: Astyle
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="http://astyle.sourceforge.net/" target="_blank" rel="noopener"
 &gt;Artistic Style&lt;/a&gt; is a source code indenter, formatter, and beautifier for the C, C++, C++/CLI, Objective‑C, C# and Java programming languages. We can download and install Astyle rather quickly without any problems on most platforms.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;
We will use a simple script below to help us install AStyle on Mac OSX. Installation on other platforms can be done in a similar manner&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;
After we have &lt;code&gt;astyle&lt;/code&gt; available on the command line, applying it for our project is a matter of wrapping everything in a single Make command 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;/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;# Supposed our Code is in the Code folder
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;format:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	find Code -iname &amp;#34;*.cs&amp;#34; -not -path &amp;#34;Code/excludedpath/*&amp;#34; | xargs -n 1 -I {} bash -c &amp;#34;astyle --options=.astylerc \&amp;#34;{}\&amp;#34;&amp;#34;
&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;Remember to create a file called &lt;code&gt;.astylerc&lt;/code&gt; and put whatever format options you want to customize for your project there.&lt;/p&gt;
&lt;h2 id="solution-2-nrefactory"&gt;Solution 2: NRefactory
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://github.com/icsharpcode/NRefactory" target="_blank" rel="noopener"
 &gt;NRefactory&lt;/a&gt; is the C# analysis library used in the SharpDevelop and MonoDevelop IDEs. We can write a command line client with our customized parameters and format options, which uses &lt;code&gt;NRefactory&lt;/code&gt; internally to format code.&lt;/p&gt;
&lt;p&gt;TODO: Write a cli using &lt;code&gt;docopt&lt;/code&gt;&lt;/p&gt;</description></item><item><title>Setup Github pages as your blog</title><link>https://minhhh.github.io/posts/setup-github-pages-as-your-blog/</link><pubDate>Sat, 10 Sep 2016 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/setup-github-pages-as-your-blog/</guid><description>&lt;p&gt;How to setup github page as your blog? It&amp;rsquo;s actually very easy, just follow the following guides&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="http://24ways.org/2013/get-started-with-github-pages/" target="_blank" rel="noopener"
 &gt;Get Started With GitHub Pages (Plus Bonus Jekyll)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://www.thinkful.com/learn/a-guide-to-using-github-pages/start/new-project/user-page/" target="_blank" rel="noopener"
 &gt;A guide to using Github Pages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://knightlab.northwestern.edu/2013/06/13/getting-github-why-journalists-should-know-and-use-the-social-coding-site/" target="_blank" rel="noopener"
 &gt;Getting GitHub: Why journalists should know and use the social coding site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/csswizardry/csswizardry.github.com" target="_blank" rel="noopener"
 &gt;csswizardry.github.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>What is Medium</title><link>https://minhhh.github.io/posts/what-is-medium/</link><pubDate>Thu, 03 Dec 2015 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/what-is-medium/</guid><description>&lt;p&gt;Medium is a web-based service that let anyone publish articles online that was founded in 2012 by 2 founders of Twitter: Ev Williams and Biz Stone. Ev Williams said Medium was &amp;ldquo;a new place on the Internet where people share ideas and stories that are longer than 140 characters and not just for friends.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;According to wikipedia, medium is a &lt;a class="link" href="https://en.wikipedia.org/wiki/Medium_%28publishing_platform%29" target="_blank" rel="noopener"
 &gt;blog publishing platform&lt;/a&gt;. While Medium might look like a standard blogging platform, it had been &amp;ldquo;designed for little stories that make your day better and manifestos that change the world.&amp;rdquo; And yet &amp;ldquo;it helps you find the right audience for whatever you have to say.&amp;rdquo;. Also, Medium does not show articles in a reverse-chronological index of content like normal blogging platform.&lt;/p&gt;
&lt;p&gt;Medium seems to do following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a beautiful, simple blogging platform for everyone&lt;/li&gt;
&lt;li&gt;Pay some people to post to the site, but not most of them&lt;/li&gt;
&lt;li&gt;Promote the people they&amp;rsquo;ve paid along with a very small subset of everyone else.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Therefore the content on medium can be either be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;awesome if they were written by profesisonal writers who were hired and edited by professional editors&lt;/li&gt;
&lt;li&gt;opposite of awesome if they were written by mediocre bloggers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The differences between Medium and traditional publication are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the traditional publication publish anything bad or plagiarised, it reflects poorly on them.&lt;/li&gt;
&lt;li&gt;If Medium publishes anything bad or plagiarised, it reflects poorly on the writers&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Medium is good for you if:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You aren’t not going to blog a lot.&lt;/li&gt;
&lt;li&gt;You like the Medium environment.&lt;/li&gt;
&lt;li&gt;You aren’t in it for the money. Medium does have some paid contributors, but not for everyone.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="references"&gt;REFERENCES
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="http://www.theatlantic.com/technology/archive/2013/08/what-is-medium/278965/" target="_blank" rel="noopener"
 &gt;What is medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://time.com/37586/what-is-medium-medium-is-pretty-cool-thats-what/" target="_blank" rel="noopener"
 &gt;http://time.com/37586/what-is-medium-medium-is-pretty-cool-thats-what/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Setup OSX</title><link>https://minhhh.github.io/posts/setup-osx/</link><pubDate>Wed, 14 Oct 2015 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/setup-osx/</guid><description>&lt;p&gt;&lt;a class="link" href="https://github.com/minhhh/wiki" target="_blank" rel="noopener"
 &gt;minhhh/wiki/mac.md&lt;/a&gt;&lt;/p&gt;</description></item><item><title>An Introduction to Memcache</title><link>https://minhhh.github.io/posts/an-introduction-to-memcache/</link><pubDate>Sat, 10 Oct 2015 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/an-introduction-to-memcache/</guid><description>&lt;p&gt;&lt;a class="link" href="https://github.com/minhhh/wiki" target="_blank" rel="noopener"
 &gt;minhhh/wiki/memcache.md&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A netcat cheatsheet</title><link>https://minhhh.github.io/posts/a-netcat-cheatsheet/</link><pubDate>Thu, 01 Jan 2015 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/a-netcat-cheatsheet/</guid><description>&lt;p&gt;&lt;a class="link" href="https://github.com/minhhh/wiki" target="_blank" rel="noopener"
 &gt;minhhh/wiki/netcat.md&lt;/a&gt;&lt;/p&gt;</description></item><item><title>An Introduction to Bash</title><link>https://minhhh.github.io/posts/an-introduction-to-bash/</link><pubDate>Sun, 23 Nov 2014 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/an-introduction-to-bash/</guid><description>&lt;p&gt;&lt;a class="link" href="https://github.com/minhhh/wiki" target="_blank" rel="noopener"
 &gt;minhhh/wiki/bash.md&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A Guide to Python's Magic Methods</title><link>https://minhhh.github.io/posts/a-guide-to-pythons-magic-methods/</link><pubDate>Sun, 19 Oct 2014 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/a-guide-to-pythons-magic-methods/</guid><description>&lt;p&gt;&lt;a class="link" href="https://github.com/minhhh/magicmethods" target="_blank" rel="noopener"
 &gt;minhhh/magicmethods/README.md&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Awk tutorial</title><link>https://minhhh.github.io/posts/awk-tutorial/</link><pubDate>Sun, 05 Oct 2014 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/awk-tutorial/</guid><description>&lt;p&gt;&lt;a class="link" href="https://github.com/minhhh/wiki" target="_blank" rel="noopener"
 &gt;minhhh/wiki/awk.md&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Python decorator tutorial</title><link>https://minhhh.github.io/posts/python-decorator-tutorial/</link><pubDate>Sun, 05 Oct 2014 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/python-decorator-tutorial/</guid><description>&lt;p&gt;&lt;a class="link" href="https://github.com/minhhh/wiki" target="_blank" rel="noopener"
 &gt;minhhh/wiki/py_decorators.md&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Android CLI tool cheatsheet</title><link>https://minhhh.github.io/posts/android-cli-tool-cheatsheet/</link><pubDate>Fri, 03 Oct 2014 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/android-cli-tool-cheatsheet/</guid><description>&lt;p&gt;&lt;a class="link" href="https://github.com/minhhh/wiki" target="_blank" rel="noopener"
 &gt;minhhh/wiki/android_cli.md&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Embed git file to pelican</title><link>https://minhhh.github.io/posts/embed-git-file-to-pelican/</link><pubDate>Thu, 11 Sep 2014 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/embed-git-file-to-pelican/</guid><description>&lt;p&gt;Writing articles in github pages is nice, because you have github repository with all the nice features for document management, however sometimes it&amp;rsquo;s not where I want my articles to reside. For instance, I want the articles about git to be in a separate &lt;code&gt;git&lt;/code&gt; repository.&lt;/p&gt;
&lt;p&gt;I have several solutions for this problem:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I could duplicate the article. But I won&amp;rsquo;t do this.&lt;/li&gt;
&lt;li&gt;I could store the articles as &lt;code&gt;gist&lt;/code&gt; like this:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;[gist:id=dc8b7c536d0fe9c7003f]&lt;/p&gt;
&lt;p&gt;But I can&amp;rsquo;t store a lot of related things in gist because that&amp;rsquo;s the role of a real git repo.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I could store the articles in the normal &lt;code&gt;git&lt;/code&gt; repo, and embed it into the article in github page. I chose this approach for long articles. Like this:&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- &lt;script src="http://gistit-minhhh.appspot.com/github/robertkrimen/gist-it-example/blob/master/example.js"&gt;&lt;/script&gt; --&gt;
&lt;p&gt;There&amp;rsquo;s already a nice tool to do this: &lt;a class="link" href="https://github.com/minhhh/gist-it" target="_blank" rel="noopener"
 &gt;gist-it&lt;/a&gt;. Using it is really simple, just clone the repo and deploy it to an AppEngine instance. The downside of this is it does not generate &lt;code&gt;html&lt;/code&gt; code for &lt;code&gt;Markdown&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The best solution for me is to use a plugin for embedding git file into &lt;code&gt;pelican&lt;/code&gt; like this:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="link" href="https://github.com/minhhh/wiki" target="_blank" rel="noopener"
 &gt;minhhh/wiki/sample.md&lt;/a&gt;&lt;/p&gt;</description></item><item><title>How to rebase in Git</title><link>https://minhhh.github.io/posts/how-to-rebase-in-git/</link><pubDate>Tue, 09 Sep 2014 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/how-to-rebase-in-git/</guid><description>&lt;p&gt;&lt;a class="link" href="https://github.com/minhhh/git-manual" target="_blank" rel="noopener"
 &gt;minhhh/git-manual/git_rebase.md&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Git cheat sheet</title><link>https://minhhh.github.io/posts/git-cheat-sheet/</link><pubDate>Fri, 05 Sep 2014 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/git-cheat-sheet/</guid><description>&lt;p&gt;&lt;a class="link" href="https://github.com/minhhh/git-manual" target="_blank" rel="noopener"
 &gt;minhhh/git-manual/README.md&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Creating this blog</title><link>https://minhhh.github.io/posts/creating-this-blog/</link><pubDate>Sat, 07 Jun 2014 00:00:00 +0700</pubDate><guid>https://minhhh.github.io/posts/creating-this-blog/</guid><description>&lt;p&gt;When creating this blog, I used the following references:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="http://ntanjerome.org/blog/how-to-setup-github-user-page-with-pelican" target="_blank" rel="noopener"
 &gt;Setup github page with pelican&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://mathamy.com/migrating-to-github-pages-using-pelican.html" target="_blank" rel="noopener"
 &gt;Migrating to github pages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://www.macdrifter.com/2012/08/pelican-guide-moving-from-wordpress-and-initial-setup.html" target="_blank" rel="noopener"
 &gt;Pelican Guide initial setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://www.macdrifter.com/2012/08/moving-to-pelican-design-planning.html" target="_blank" rel="noopener"
 &gt;Moving to Pelican planning&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/streeter/pelican-gist" target="_blank" rel="noopener"
 &gt;pelican-gist&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/minhhh/gist-it" target="_blank" rel="noopener"
 &gt;gist-it&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>