<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: The Gamedev Guru</title>
    <description>The latest articles on DEV Community by The Gamedev Guru (@thegamedevguru).</description>
    <link>https://dev.to/thegamedevguru</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F231437%2F123ed129-e9b6-4548-aad2-c9dada74bc6d.jpg</url>
      <title>DEV Community: The Gamedev Guru</title>
      <link>https://dev.to/thegamedevguru</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thegamedevguru"/>
    <language>en</language>
    <item>
      <title>The Ultimate Guide to Draw Call Batching in Unity 2020+</title>
      <dc:creator>The Gamedev Guru</dc:creator>
      <pubDate>Mon, 13 Jan 2020 18:49:10 +0000</pubDate>
      <link>https://dev.to/thegamedevguru/the-ultimate-guide-to-draw-call-batching-in-unity-2020-5g0j</link>
      <guid>https://dev.to/thegamedevguru/the-ultimate-guide-to-draw-call-batching-in-unity-2020-5g0j</guid>
      <description>&lt;p&gt;[Find the original post at &lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/"&gt;Unity Draw Calls&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;Draw calls are never a problem. That is, until you add one more element and suddenly your render thread becomes your new bottleneck. Can you guess why keeping Unity draw calls at bay is today more relevant than ever?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--51WFnQER--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedevguru.b-cdn.net/wp-content/uploads/2020/01/Unity-Draw-Call-Reduction-Thumbnail.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--51WFnQER--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedevguru.b-cdn.net/wp-content/uploads/2020/01/Unity-Draw-Call-Reduction-Thumbnail.jpg" alt="" title="Unity-Draw-Call-Reduction-Thumbnail" width="469" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Warning: this is an in-depth post, make yourself comfortable and grab a tea. Use the table of contents if you're in a rush.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Quick Navigation (redirects to my blog)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#tab-con-15"&gt;My Background Story&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#tab-con-16"&gt;Signs You Have Too Many Draw Calls&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;    &lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#tab-con-12"&gt;Soft Sign: Battery Draining Too Quickly&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;    &lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#tab-con-1"&gt;Soft Sign: Device Heating Up&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;    &lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#tab-con-13"&gt;Soft Sign: Game-Play Not Running Smoothly&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;    &lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#tab-con-9"&gt;Soft-Sign: VR Users Look Paler Than Ever&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;    &lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#tab-con-17"&gt;Hard Sign: The Profiler Reveals a Render Thread Bottleneck&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#tab-con-18"&gt;Wait... What's a Draw Call?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;    &lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#tab-con-19"&gt;Batches vs SetPasses&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;    &lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#tab-con-3"&gt;Counting Unity Draw Calls&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#tab-con-4"&gt;3 Reasons to Keep Draw Calls at Bay&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#tab-con-2"&gt;Fight the Battle: Batching Unity Draw Calls&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;    &lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#tab-con-7"&gt;Requirement: Merging Unity Materials&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;    &lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#tab-con-8"&gt;Technique 1: Static Batching&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;    &lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#tab-con-10"&gt;Technique 2: GPU Instancing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;    &lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#tab-con-11"&gt;Technique 3: Dynamic Batching&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;    &lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#tab-con-5"&gt;Technique 4: Run-Time Batching API&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#tab-con-6"&gt;See Draw Call Batching in Action&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--p20YKnB4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/IMG_20200107_205117.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--p20YKnB4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/IMG_20200107_205117.jpg" alt="" title="IMG_20200107_205117" width="600" height="426"&gt;&lt;/a&gt;\&lt;br&gt;
&lt;em&gt;Taken with my Nokia 3210&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My Background Story
&lt;/h2&gt;

&lt;p&gt;Just a few years ago, I was an inexperienced young lad... Especially when it came to game programming.&lt;/p&gt;

&lt;p&gt;I was working on one of my first professional assignments and my task was clear.&lt;/p&gt;

&lt;p&gt;I just had to improve and implement several gameplay systems for an existing game.&lt;/p&gt;

&lt;p&gt;Fair enough.&lt;/p&gt;

&lt;p&gt;So that's what I focused on for months. Creating fun for my players it is.&lt;/p&gt;

&lt;p&gt;The thing is, every other area in game development remained pretty much unknown to me.&lt;/p&gt;

&lt;p&gt;And I couldn't stop asking myself...&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What if I have to put off a fire in one of these areas I have no idea about?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That simple thought made me very uncomfortable. After all, I didn't want to disappoint my boss. He hired me for a reason so they he expected me to know my stuff.&lt;/p&gt;

&lt;p&gt;Yet I knew it was only about time I had to face problems I never dealt with.&lt;/p&gt;

&lt;p&gt;And I didn't feel prepared.&lt;/p&gt;

&lt;p&gt;In any case, I happily kept adding content and worried no further. Everything was going smoothly and I received good feedback on my work.&lt;/p&gt;

&lt;p&gt;Even better, performance was great all long...&lt;/p&gt;

&lt;p&gt;Until it wasn't.&lt;/p&gt;

&lt;p&gt;After several months, I noticed something was off.&lt;/p&gt;

&lt;p&gt;I went to the stores and started noticing more and more negative reviews.&lt;/p&gt;

&lt;p&gt;I was used to a certain proportion of negative reviews. That's always part of exposing your work to the world.&lt;/p&gt;

&lt;p&gt;But the trend worried me. It was getting worse than ever.&lt;/p&gt;

&lt;p&gt;More users started complaining about battery draining faster, the device heating more than ever and the gameplay feeling too slow.&lt;/p&gt;

&lt;p&gt;It took me some time to connect the dots.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;That must be the performance thing,&lt;/em&gt; I thought.&lt;/p&gt;

&lt;p&gt;I started worrying that I messed up the user experience.&lt;/p&gt;

&lt;p&gt;Even worse, what would my client think of me? It surely had to be the work I did on gameplay.&lt;/p&gt;

&lt;p&gt;Worry quickly transformed into stress.&lt;/p&gt;

&lt;p&gt;I was used to stress. After all, I often spent over 12 hours a day at the University just a few years before.&lt;/p&gt;

&lt;p&gt;But this time it was different. It was not about me anymore. It was about real people that I was disappointing.&lt;/p&gt;

&lt;p&gt;Armed with courage, I started digging into the unknown world of performance.&lt;/p&gt;

&lt;p&gt;And that I did especially over my free time.&lt;/p&gt;

&lt;p&gt;I quickly learned about the Unity Profiler. That valuable tool showed me how the render thread appeared to be taking just too long. But I didn't know why.&lt;/p&gt;

&lt;p&gt;So I kept investigating.&lt;/p&gt;

&lt;p&gt;However, no matter how much time I put in, problems arose faster than I could fix them.&lt;/p&gt;

&lt;p&gt;I was about to give up.&lt;/p&gt;

&lt;p&gt;Maybe game development wasn't for me, after all.&lt;/p&gt;

&lt;p&gt;But then, I became one of the luckiest developer of the world.&lt;/p&gt;

&lt;p&gt;I was lucky enough to come across a great online article about technical debt. And I realized I dug my own graveyard.&lt;/p&gt;

&lt;p&gt;But at the same time, I became inspired.&lt;/p&gt;

&lt;p&gt;Over time, I introduced content that exploded the amount of unity draw calls I had in the game. And draw calls were supposed to be kind of requests to draw something on the screen.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Are 130 draw calls too much? Yeah, that must be it&lt;/em&gt;, I thought. &lt;em&gt;I added non-optimized content that is causing the battery drain and slow gameplay, so now I just need to optimize it&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So I got to work and started the long journey of optimizing my materials. After all, draw calls were highly related to the material setup in Unity. The juicy over-hours were on me. I caused that problem, so I was ready to suck it up.&lt;/p&gt;

&lt;p&gt;I couldn't stop thinking about the long-term problems, though.&lt;/p&gt;

&lt;p&gt;If I had this problem, chances were other people had it as well.&lt;/p&gt;

&lt;p&gt;As I saw it, the only way to solve this problem was to create processes to continuously monitor performance metrics.&lt;/p&gt;

&lt;p&gt;That was my second job.&lt;/p&gt;

&lt;p&gt;In a matter of days, I implemented a prototype system to continuously monitor the number of unity draw calls in the game. I wanted to make sure people submitted only optimized content in the future, especially myself.&lt;/p&gt;

&lt;p&gt;Still, I struggled to keep the deadlines.&lt;/p&gt;

&lt;p&gt;I knew I had to be resilient. And that I became.&lt;/p&gt;

&lt;p&gt;With endless effort, I unified game materials substantially and greatly reduced the number of shaders.&lt;/p&gt;

&lt;p&gt;This long journey brought me to a draw call count well under 60.&lt;/p&gt;

&lt;p&gt;Performance was great again, as everyone held to the performance guidelines. The processes made sure of that.&lt;/p&gt;

&lt;p&gt;And I was proud of that.&lt;/p&gt;

&lt;p&gt;However, I still had my inner voice reminding me about these players that I upset.&lt;/p&gt;

&lt;p&gt;They used to have great times playing the game. They made friends through it. They went as far as to strengthen their relationships with their family members.&lt;/p&gt;

&lt;p&gt;That's why I worked hard to alleviate the pain they showed through the reviews.&lt;/p&gt;

&lt;p&gt;But these players never came back. I lost them forever.&lt;/p&gt;

&lt;p&gt;And that was heart-breaking.&lt;/p&gt;

&lt;p&gt;Losing these players taught me how important it was to monitor performance all along the project.&lt;/p&gt;

&lt;p&gt;Loading times, frame-rate, performance spikes, battery and power efficiency... All of that way matters more than I thought.&lt;/p&gt;

&lt;p&gt;This was one of the defining moments that made me focus so heavily on game performance optimization. I learned the lesson.&lt;/p&gt;

&lt;p&gt;The game is still performing well today. And thanks to the optimizations, the ports to weaker platforms became much easier.&lt;/p&gt;

&lt;p&gt;Ever since then, I monitor the performance of my games almost daily.&lt;/p&gt;

&lt;p&gt;But I don't do this alone.&lt;/p&gt;

&lt;p&gt;I have systems in place that report me these numbers automatically. When something is off, I go and investigate.&lt;/p&gt;

&lt;p&gt;Monitoring unity draw calls is now more important than ever with Virtual Reality gaining so much traction. We have to render at consistent frame-rates of 72, 90 or even 144 Hz. Those timings don't give you a substantial CPU budget.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F2ZwBKdM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedevguru.b-cdn.net/wp-content/uploads/2019/10/ruben-portrait.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F2ZwBKdM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedevguru.b-cdn.net/wp-content/uploads/2019/10/ruben-portrait.jpg" alt="" title="ruben-portrait" width="184" height="200"&gt;&lt;/a&gt; "You better spend well the little technical budget you have in VR" --&lt;em&gt;Rubén Torres Bonet&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Signs You Have Too Many Draw Calls
&lt;/h2&gt;

&lt;p&gt;At any specific moment during gameplay, there are some important signs to watch for.&lt;/p&gt;

&lt;p&gt;Over time, you'll develop a sixth sense that will spawn some chills running down your spine whenever you experience these situations.&lt;/p&gt;

&lt;p&gt;However, symptoms are just symptoms. They do not always reveal a draw call problem, as bottlenecks can origin from many corners. To make the distinction more clear, I divided them in two categories.&lt;/p&gt;

&lt;p&gt;Soft symptoms are a weak indication for high draw calls; they can perfectly come from other performance factors such as overdraw.&lt;/p&gt;

&lt;p&gt;Lastly, hard signs are those that strongly show that your game might have too many draw calls.&lt;/p&gt;

&lt;h3&gt;
  
  
  Soft Sign: Battery Draining Too Quickly
&lt;/h3&gt;

&lt;p&gt;Phone batteries usually last for a day or two under average use.&lt;/p&gt;

&lt;p&gt;But games excel at stealing the energy from your users' lithium ions.&lt;/p&gt;

&lt;p&gt;However, realize that power consumption varies across different games. Optimized games will relax your CPU and GPU so they consume fewer watts.&lt;/p&gt;

&lt;p&gt;And optimizing your game is important because your users became pretty good at noticing how much battery your game takes for breakfast.&lt;/p&gt;

&lt;p&gt;Even if you didn't care about your users (who doesn't?), this is still a relevant factor for you.&lt;/p&gt;

&lt;p&gt;This is why...&lt;/p&gt;

&lt;p&gt;Efficient games let your players play for longer sessions. And the more they play, the more money will land in your pocket (or your employer's). More In-App Purchases sold, more ads consumed, more word-of-mouth marketing, you name it.&lt;/p&gt;

&lt;p&gt;Optimizing for battery is a good return on investment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Soft Sign: Device Heating Up
&lt;/h3&gt;

&lt;p&gt;Most of the energy you take from your users' devices is converted into heat (and light). Surprise.&lt;/p&gt;

&lt;p&gt;This might be handy in winter to warm up your hands. But still, there are 3 seasons left where your users would prefer to go around without a portable battery pack.&lt;/p&gt;

&lt;p&gt;I still remember my times in Berlin ordering Glühwein just to warm up my hands during winter. I didn't enjoy the wine-based drink, but I learned to appreciate the warm sensation in my hands.&lt;/p&gt;

&lt;p&gt;So I kept buying it.&lt;/p&gt;

&lt;p&gt;If you're targeting a VR headset, you should especially optimize for energy efficiency. That is, unless you're developing an application to replace a conventional face tanner.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--423N-E2i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Old-Counter-Strike-Terrorist.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--423N-E2i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Old-Counter-Strike-Terrorist.jpg" alt="" title="Old-Counter-Strike-Terrorist" width="880" height="495"&gt;&lt;/a&gt;&lt;em&gt;Source: &lt;a href="https://eu.alienwarearena.com/ucf/show/377714/boards/fan-art/Image/counter-strike-1-6-terror-awp"&gt;AlienwareArena&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Soft Sign: Game-Play Not Running Smoothly
&lt;/h3&gt;

&lt;p&gt;Picture this...&lt;/p&gt;

&lt;p&gt;You're playing a slow-paced multi-player shooter.&lt;/p&gt;

&lt;p&gt;But as you're new to it, so everybody plays it better than you.&lt;/p&gt;

&lt;p&gt;After hours of frustration, you finally have your chance: a distracted sniper.&lt;/p&gt;

&lt;p&gt;You're sneaking upon him from behind. They didn't notice you yet, but you know it's only about time they turn their back to you. So you get ready to aim for the perfect head-shot.&lt;/p&gt;

&lt;p&gt;You slowly move your mouse to aim a few pixels higher.&lt;/p&gt;

&lt;p&gt;But after a delay of half a second, your cross-hair is now suddenly pointing at the sky.&lt;/p&gt;

&lt;p&gt;The sniper notices you and by the time you realize it you're already dead.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What the hell has just happened?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Low frame-rate.&lt;/p&gt;

&lt;p&gt;Now, low performance could happen for multiple reasons, such as garbage collection, but a high amount of unity draw calls is surely one of them.&lt;/p&gt;

&lt;p&gt;I remember the early days of Counter Strike where people with the beefiest GPUs threw smoke grenades to gain an unfair advantage. Players with low-end computers couldn't really handle smoke that well, so they ended up dying of low frame-rate. This was probably more due to overdraw than draw-calls, but I still find it memorable to mention.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SI4JW1Bf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Decoration-Sick-VR.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SI4JW1Bf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Decoration-Sick-VR.jpg" alt="" title="Decoration-Sick-VR" width="600" height="356"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Soft-Sign: VR Users Look Paler Than Ever
&lt;/h3&gt;

&lt;p&gt;The lower your VR game performs, the worse your users will feel.&lt;/p&gt;

&lt;p&gt;Wait, I can say this in a different way.&lt;/p&gt;

&lt;p&gt;The more potential draw calls you have, the worse your worst case becomes.&lt;/p&gt;

&lt;p&gt;Yeah, that's better.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F2ZwBKdM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedevguru.b-cdn.net/wp-content/uploads/2019/10/ruben-portrait.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F2ZwBKdM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedevguru.b-cdn.net/wp-content/uploads/2019/10/ruben-portrait.jpg" alt="" title="ruben-portrait" width="184" height="200"&gt;&lt;/a&gt; "Performance spikes are the quickest way to convert VR players into patients" --&lt;em&gt;Rubén Torres Bonet&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Hard Sign: Unity Profiler Reveals a Render Thread Bottleneck
&lt;/h3&gt;

&lt;p&gt;If your render thread is taking too long to execute, chances are you have too many draw calls. Or worse, you might have too many SetPasses (we'll see the difference in the next section).&lt;/p&gt;

&lt;p&gt;Your main thread is probably just idling around while the render thread finishes processing all draw calls.&lt;/p&gt;

&lt;p&gt;You can identify this situation through the Unity Profiler, as seen below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fWdDBhxz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Unity-Draw-Calls-RenderThread-Expensive.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fWdDBhxz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Unity-Draw-Calls-RenderThread-Expensive.png" alt="Unity Draw Calls: Expensive Render Thread" title="Unity Draw Calls: Expensive Render Thread" width="424" height="105"&gt;&lt;/a&gt;\&lt;br&gt;
&lt;em&gt;Unity Draw Calls: Expensive Render Thread&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The more of these signs you have, the higher the chances are that your game has way too many draw calls.&lt;/p&gt;

&lt;p&gt;And we've been speaking about draw calls for a long time.&lt;/p&gt;

&lt;p&gt;But what's exactly a draw call?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8OqIh86J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedevguru.b-cdn.net/wp-content/uploads/2020/01/Decoration-Painting-Logo.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8OqIh86J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedevguru.b-cdn.net/wp-content/uploads/2020/01/Decoration-Painting-Logo.jpg" alt="" title="Decoration-Painting-Logo" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wait... What's a Draw Call?
&lt;/h2&gt;

&lt;p&gt;Simply put, a draw call is your CPU asking your GPU to draw something.&lt;/p&gt;

&lt;p&gt;It's your CPU saying: &lt;em&gt;hey, draw this chair in that corner over there with these textures and lighting information&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If you have many "things", then you prepare many draw calls:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;I want a chair in that corner&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;And also another chair there in the other corner&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Oh, and a bookcase as well.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The issue is, preparing unity draw calls steals a huge portion of your CPU time and energy. Unity has to convert your scene content into a format your GPU understands. And a very expensive part of this process is to set the correct render parameters, such as textures, shaders, meshes, etc...&lt;/p&gt;

&lt;p&gt;Setting rendering parameters manually is tedious. That's why game developers introduced the concept of materials.&lt;/p&gt;

&lt;p&gt;A material is a data structure with information about how to draw an object. It contains a shader with all its parameters, plus information about how to set the GPU render state.&lt;/p&gt;

&lt;p&gt;And every material you add to your scene increases the complexity of your rendering pipeline. Each material adds at least one SetPass (this sets rendering parameters). And you really want to minimize those if you want your game to perform well.&lt;/p&gt;

&lt;p&gt;Does this mean we cannot draw too many objects at once?&lt;/p&gt;

&lt;p&gt;Not necessarily.&lt;/p&gt;

&lt;p&gt;Game developers use batching to group the rendering of similar objects into the same draw call.That way, the CPU pays the price of a single draw call to render multiple objects.&lt;/p&gt;

&lt;p&gt;With batching, we ask the gpu once to &lt;em&gt;draw three chairs here, there and behind&lt;/em&gt; instead of asking three different times.&lt;/p&gt;

&lt;p&gt;Now, the key is understanding what "similar" (objects) means.&lt;/p&gt;

&lt;p&gt;In batching, it all comes down to using the same material across different objects. Really. If you get this done, you achieved the most complicated step.&lt;/p&gt;

&lt;p&gt;With the help of the Unity Frame Debugger, you can see below the sequence for 4 draw calls: 3 for the furniture and 1 for the floor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedevguru.b-cdn.net/wp-content/uploads/2020/01/Unity-Draw-Call-Sequence-Demo.gif"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QpeEG_iL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Unity-Draw-Call-Sequence-Demo.gif" alt="Unity Draw Calls: No Batching" title="Unity Draw Calls: No Batching" width="880" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Unity Draw Calls: No Batching&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That was expensive.&lt;/p&gt;

&lt;p&gt;But batching will help us reduce these draw calls. This, in turn, will reduce the CPU load of your players. Having more resources lets you add more gameplay features or just keep it that way to reduce the energy consumption of the device.&lt;/p&gt;

&lt;h3&gt;
  
  
  Batches vs SetPasses
&lt;/h3&gt;

&lt;p&gt;There's a little detail that few developers know of.&lt;/p&gt;

&lt;p&gt;There's a difference between the &lt;em&gt;Batches *and *SetPasses&lt;/em&gt; metrics you see in the profiler and stats window.&lt;/p&gt;

&lt;p&gt;But this difference has a huge impact.&lt;/p&gt;

&lt;p&gt;Batches are what we usually describe as draw calls. Those are plain draw commands, e.g. draw this object here and then this other one there. This is mostly about drawing an object with the current global render state. Same shader, similar parameters.&lt;/p&gt;

&lt;p&gt;SetPasses, however, describe a more expensive operation: material changes. Changing a material is expensive because we have to set a new render state.  This includes shader parameters and pipeline settings, such as alpha blending, Z testing, Z writing, etc...&lt;/p&gt;

&lt;p&gt;Let me explain this to you with an example.&lt;/p&gt;

&lt;p&gt;Let's consider we have 3 chairs sharing the same mesh. &lt;/p&gt;

&lt;p&gt;We'll now explore three scenarios with different batching and material setup. Each scenario will result indifferent batches and SetPasses. Check the following table;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/unity-draw-calls-table/"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RMWylGNM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/unity-draw-calls-table/" alt="" width="880" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first and second scenarios are similar: different materials skyrocket our SetPass count. And those have the worst performance hit in the render thread. Batching is not possible, as batching requires using identical materials.&lt;/p&gt;

&lt;p&gt;However, we see a hint of light with the third scenario. Sharing materials makes all the difference. Having a unique material reduces the SetPass count to 1, which gives you an incredible performance boost. Sure, we still have three draw calls, but those are very cheap.&lt;/p&gt;

&lt;p&gt;Finally, if you really want to kick ass, then the fourth scenario is for you. Here, we enable batching. And batching loves unique materials. Enabling batching reduces the Draw Call count to 1. Here we have the perfect output:  1 SetPass, 1 Batch&lt;/p&gt;

&lt;h3&gt;
  
  
  Counting Unity Draw Calls
&lt;/h3&gt;

&lt;p&gt;Before we dig into fighting draw calls, we first need the proper tools to measure them. There are many tools available for this, such as &lt;em&gt;RenderDoc&lt;/em&gt;, but we will stick to the simplest: the stats window and the Unity Frame Debugger.&lt;/p&gt;

&lt;p&gt;You can access the stats window any time by clicking on the *Stats *button on the top-right corner of the game view. This panel shows you metrics for the current game view. Expect these numbers to evolve if your screen contents change (which should if you're serious about game development).&lt;/p&gt;

&lt;p&gt;There, pay attention to Batches (draw calls) and SetPasses (material changes). As we saw, these are connected but have a different performance impact profile.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sKHJLFvO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Unity-Draw-Calls-Stats-Window.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sKHJLFvO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Unity-Draw-Calls-Stats-Window.jpg" alt="Unity Performance Stats Window" title="Unity Performance Stats Window" width="290" height="200"&gt;&lt;/a&gt;\&lt;br&gt;
&lt;em&gt;Unity Performance Stats Window&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Lastly, you can and should use the Unity Frame Debugger. This tool will show you the specific draw calls (batches) that you're issuing for the current view. You can open it in &lt;em&gt;Window → Analysis → Frame Debugger&lt;/em&gt;. This &lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/?tve=true&amp;amp;tcbf=f3046a5176#tve-jump-16f863debf8"&gt;image&lt;/a&gt; shows you what to expect.&lt;/p&gt;

&lt;h2&gt;
  
  
  3 Reasons to Keep Draw Calls at Bay
&lt;/h2&gt;

&lt;p&gt;My experience has taught me it is crucial to reduce SetPasses and draw calls even if they are not the bottleneck of your game. Here are my top reasons to reduce draw calls from the start of a project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  It makes porting to future platforms much easier.\
You surely spent thousands of hours working on your game.  That's a baseline cost everyone has to pay to get their game shipped.\
Once you paid that price, why not profit from it further and port it to other platforms? It will take you a fraction of the cost to multiply your sales.\
The thing is, the more optimized your game is, the less effort you must put in the porting process.&lt;/li&gt;
&lt;li&gt;  Save time and pain by optimizing now rather than in the future.\
Just optimize them today, really. You probably know how it feels to optimize a dozen of assets a colleague of yours created a year ago. Especially when that colleague of yours left your project.\
This becomes crucial when shopping in the asset store. Most assets from the store are poorly implemented and use multi-material setups. Those will make your life impossible when targeting mobile.&lt;/li&gt;
&lt;li&gt;  It improves the efficiency of your game.\
Your game will use less CPU resources and perform better, which is critical in VR. You'll steal less energy from your players' batteries. The players and environment will reward you for that with better reviews and more in-app purchases. The longer your users play your game, the more ads they will see, the faster they'll consume and pay for your content.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You see, while working with Unity you are adding draw calls by default. Assets tend to use different materials unless you pay attention to them. And by using different materials, you're adding draw calls that you cannot batch. Over time, this will explode.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fight the Battle: Batching Unity Draw Calls
&lt;/h2&gt;

&lt;p&gt;Instead of drawing one object 10 times, we draw 10 objects once.&lt;/p&gt;

&lt;p&gt;That's the power of batching.&lt;/p&gt;

&lt;p&gt;The main requirement to batch draw calls is to get the objects to use the same drawing properties (material). When that happens, Unity can then merge the different meshes into a single chunk that uses the common material.&lt;/p&gt;

&lt;p&gt;As we said, most assets will use different materials by default. But worry no further, we'll see several ways to merge materials into a single one.&lt;/p&gt;

&lt;p&gt;Below there's a flowchart diagram that summarizes the options you have for batching in Unity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WMgzl4WR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Unity-Draw-Call-Reduction-Diagram-1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WMgzl4WR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Unity-Draw-Call-Reduction-Diagram-1.jpg" alt="Unity Draw Call Reduction: Batching Diagram" title="Unity Draw Call Reduction: Batching Diagram" width="390" height="551"&gt;&lt;/a&gt;\&lt;br&gt;
&lt;em&gt;Unity Draw Call Reduction: The Guru's Batching Diagram&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Your entry point is to find out if the objects you want to batch share the same material.&lt;/p&gt;

&lt;p&gt;Sharing materials is a precondition for batching to work. Different materials have different drawing settings that change the global GPU render state.&lt;/p&gt;

&lt;p&gt;If these objects don't use the exact same material but they're similar enough, then you must merge them into a single one. This usually involves creating shared texture atlases and updating the individual objects' UV coordinates to point at the new correct locations. There are tools to help you out here.&lt;/p&gt;

&lt;p&gt;Once your objects use the same material, you have many options to batch these draw calls.&lt;/p&gt;

&lt;p&gt;The batching technique I suggest you to use use depends on the nature of the objects you want to batch.&lt;/p&gt;

&lt;p&gt;But before getting into batching, let's see how to merge materials.&lt;/p&gt;

&lt;p&gt;(Get the full-resolution diagram &lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#download"&gt;here&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#predownload"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HA74ah1B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Draw-Calls-Printable-Preview.jpg" alt="" width="880" height="578"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Requirement: Merging Unity Materials
&lt;/h3&gt;

&lt;p&gt;The first requirement to merge materials is this:&lt;/p&gt;

&lt;p&gt;The materials for the objects you want to batch must use the same shader&lt;/p&gt;

&lt;p&gt;Changing the current shader is one of the most expensive operations you can do. This slows down rendering significantly.&lt;/p&gt;

&lt;p&gt;Almost every game must change shaders to some degree, and that's fine as you're aware of its cost. Try to reduce the shader count you have in your project (including shader variants).&lt;/p&gt;

&lt;p&gt;If you can merge two shaders that look alike into the same one, you'll get huge wins in performance.&lt;/p&gt;

&lt;p&gt;So the first step is to remove shaders from your project, whenever you can. Chances are, you can get many original materials to look similarly under a common shader.&lt;/p&gt;

&lt;p&gt;Once your target objects use the same shader, the next step is to merge their materials. That is probably complicated, as they probably had different material parameters such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Textures: each material often has one or more textures that are not shared with other materials. One way to use the same texture across different materials is by creating bigger textures that contain all individual textures. Those textures are called atlases.&lt;/li&gt;
&lt;li&gt;  Decimal values: such as metallic, specular and other parameters. To merge those, you can either find a common average value that suits them all or create a texture atlas containing that value in a specific channel. You can &lt;a href="https://docs.unity3d.com/Manual/StandardShaderMaterialParameterMetallic.html"&gt;re-purpose the 3 or 4 texture channels&lt;/a&gt; for different parameters, e.g. storing the metallic value in the red channel.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, if you have several objects with the same material but they must have different parameters, you can give &lt;a href="https://docs.unity3d.com/ScriptReference/MaterialPropertyBlock.html"&gt;MaterialPropertyBlock &lt;/a&gt;a shot. Instead of creating individual material instances, you can create a *MaterialPropertyBlock *for each renderer that needs custom parameters. You can then set your individual parameters in each of these blocks. This will not reduce your draw calls but it will make rendering much cheaper, as you're explicitly telling Unity what's different about each object.&lt;/p&gt;

&lt;p&gt;Creating texture atlases for materials sharing a shader often follows this pattern:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Create a big texture we'll call texture atlas.&lt;/li&gt;
&lt;li&gt; Take a texture channel of all materials and fit its textures into the newly created texture atlas.&lt;/li&gt;
&lt;li&gt; Go over the meshes using these materials to recalculate their UVs. The new UVs will point at the new sub-region of the texture atlas that contains the original texture.&lt;/li&gt;
&lt;li&gt; Disable the old mesh and instead use the new mesh with the updated UVs.&lt;/li&gt;
&lt;li&gt; Unlink the original material to use the merged material.&lt;/li&gt;
&lt;li&gt; Repeat all these steps per additional texture property your shader takes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I recommend you to do this in your 3d software. If you have the time, this is the best method because it gives you fine control over the process. This will improve the output quality because you can tweak critical variables such as texel resolution. You can also apply more advanced techniques such as palettes.&lt;/p&gt;

&lt;p&gt;If you don't have the time, resources or experience to do this, then I'll take you through another path...&lt;/p&gt;

&lt;p&gt;Use tools to do this for you.&lt;/p&gt;

&lt;p&gt;As a programmer, I'm not as efficient with 3d modeling tools so I often use this approach.&lt;/p&gt;

&lt;p&gt;In no particular order, here are some Unity packages you can use to merge materials within Unity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Mesh Baker: &lt;a href="https://assetstore.unity.com/packages/tools/modeling/mesh-baker-5017"&gt;premium&lt;/a&gt; or &lt;a href="https://assetstore.unity.com/packages/tools/modeling/mesh-baker-free-31895"&gt;free&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://assetstore.unity.com/packages/tools/modeling/super-combiner-92129"&gt;Super Combiner&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://assetstore.unity.com/packages/tools/utilities/advanced-batcher-19877"&gt;Advanced Batcher&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://assetstore.unity.com/packages/tools/utilities/one-batch-128259"&gt;One Batch&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once we merged multiple materials into a single material, then we can start batching our draw calls.&lt;/p&gt;

&lt;p&gt;You need criteria that help you choose between the different batching methods.&lt;/p&gt;

&lt;p&gt;There's always a price to pay with all batching techniques. They all have some requirements that might be hard to meet depending on your gameplay situation.&lt;/p&gt;

&lt;p&gt;Let's explain it following the &lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#tve-jump-16f8ef8ee72"&gt;diagram sequence&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technique 1: Unity Static Batching
&lt;/h3&gt;

&lt;p&gt;Static batching is enabled by default (and I suggest you to keep it that way).&lt;/p&gt;

&lt;p&gt;Unity applies this technique automatically to all static objects in the scene that share a material. If we start with the following draw calls:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Draw static chair 1&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Draw static chair 2&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Draw static table&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then static batching creates a single draw call out of them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Draw the static dining furniture (containing 2 chairs and a table).&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tat3VvUP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Unity-Draw-Call-Batching-Settings.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tat3VvUP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Unity-Draw-Call-Batching-Settings.png" alt="Unity Draw Call Batching Settings" title="Unity-Draw-Call-Batching-Settings" width="738" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Unity Draw Call Batching Settings&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You can find this setting under player settings, as shown on the image. Select the target platform you're aiming for to enable it.&lt;/p&gt;

&lt;p&gt;Note for later that dynamic batching is also enabled/disabled in the player settings.&lt;/p&gt;

&lt;p&gt;More precisely, Unity will look for objects whose batching static flag is enabled. Then, Unity will attempt to merge those that share a material.&lt;/p&gt;

&lt;p&gt;Unity static batching works by creating a huge mesh containing the individual meshes. But Unity doesn't discard the individual meshes. Instead, Unity keeps the original meshes intact so we are still able to render them individually. We need this for frustrum culling to work. This way, we can draw only the objects that lie within the visible field of view and discard those who aren't.&lt;/p&gt;

&lt;p&gt;By having all meshes in a single mesh, we're able to draw them all without changing the render state.&lt;/p&gt;

&lt;p&gt;Static batching happens just before you hit the play button on the editor and also happens while making a build. Unity goes through each scene and tries to batch as many static objects as possible.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.gamasutra.com/blogs/https;//thegamedev.guru/wp-content/uploads/2020/01/Unity-Draw-Call-Sequence-Static-Batching.gif"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TiYgWRzk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Unity-Draw-Call-Sequence-Static-Batching.gif" alt="Unity Draw Calls: Static Batching" title="Unity-Draw-Call-Sequence-Static-Batching" width="880" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Unity Draw Calls: Static Batching&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The main limit to static batching is the amount of vertices and indices each batch can have. This is often 64k for each, but check the updated requirements &lt;a href="https://docs.unity3d.com/Manual/DrawCallBatching.html"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The downside to static batching is an increased memory usage. If you have 100 stones and each stone model takes 1MB, then you can expect memory usage to be around 100MB+. This happens because the huge batched mesh contains all stones together as a single mesh.&lt;/p&gt;

&lt;p&gt;But memory usage shouldn't be a concern for you. After all, you can check out my &lt;a href="https://thegamedev.guru/unity-addressables/tutorial-learn-the-basics/"&gt;Unity Addressables Tutorial&lt;/a&gt; that will help you get huge memory savings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technique 2: Unity GPU Instancing
&lt;/h3&gt;

&lt;p&gt;GPU instancing is one of my favorite batching techniques because it works with non-static objects.&lt;/p&gt;

&lt;p&gt;If we have these draw calls:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Draw dynamic stone 1&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  ...&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Draw dynamic stone 100&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then with GPU instancing we convert them to a single draw call:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Draw 100 dynamic stones here and there and there...&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a setting you activate per material, as seen below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QCeTFw6m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Unity-Draw-Call-Batching-GPU-Instancing-Material.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QCeTFw6m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Unity-Draw-Call-Batching-GPU-Instancing-Material.png" alt="Unity GPU Instancing: Material Settings" title="Unity GPU Instancing: Material Settings" width="406" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Unity GPU Instancing: Material Settings&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;GPU instancing lets you draw the same mesh several times very efficiently. Unity does it by passing a list of transforms. After all, each stone had its own position, rotation and scale.&lt;/p&gt;

&lt;p&gt;This is a powerful technique because it does not skyrocket the memory usage and it doesn't require the objects to be static, compared to static batching.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ces2Qb6t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Unity-Draw-Call-Sequence-GPU-Instancing.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ces2Qb6t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Unity-Draw-Call-Sequence-GPU-Instancing.gif" alt="Unity Draw Calls: GPU Instancing" title="Unity Draw Calls: GPU Instancing" width="880" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Unity Draw Calls: GPU Instancing&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To make GPU instancing work, you just need to enable it in the material inspector. If you have multiple objects with the same mesh and material, then they'll batch automatically.&lt;/p&gt;

&lt;p&gt;However, there's a performance cost of creating the list of transforms. You pay this price once if no object moves/rotates/scales during gameplay. But you can pay this once per frame if an object changes per frame.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technique 3: Unity Dynamic Batching
&lt;/h3&gt;

&lt;p&gt;If you cannot meet the requirements of static batching and GPU instancing, you still have hope.&lt;/p&gt;

&lt;p&gt;You can still batch dynamic objects that use different meshes with dynamic batching.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m507F6BP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Unity-Draw-Call-Sequence-Dynamic-Batching.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m507F6BP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Unity-Draw-Call-Sequence-Dynamic-Batching.gif" alt="Unity Draw Calls: Dynamic Batching" title="Unity Draw Calls: Dynamic Batching" width="880" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Unity Draw Calls: Dynamic Batching&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;However, bear in mind that Unity dynamic batching is heavily limited. You can apply it only to meshes that have less than 300 vertices and 900 vertex attributes (&lt;em&gt;colors, UVs&lt;/em&gt;, etc). The material should use a single-pass shader as well. Make sure to check the full list of requirements &lt;a href="https://docs.unity3d.com/Manual/DrawCallBatching.html"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The reason for this limit is the CPU performance cost of creating these batches in run-time. Above 300 vertices it becomes hard to justify the batching CPU cost compared to issuing the draw calls individually.&lt;/p&gt;

&lt;p&gt;Not only that, dynamic batching is highly unpredictable. You cannot really tell how your objects will batch. And the result often changes from frame to frame. It's confusing to check out the Unity Frame Debugger and see how results dramatically change across frames.&lt;/p&gt;

&lt;p&gt;In my opinion, this should be your method of last resort. But hey, it's still a tool, don't overlook it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technique 4: Unity Run-Time Batching API
&lt;/h3&gt;

&lt;p&gt;For all special cases where you want to have finer control over batching, you can just do it manually.&lt;/p&gt;

&lt;p&gt;Don't worry, you won't have to deal with vertices yourself.&lt;/p&gt;

&lt;p&gt;Unity gives you access to 2 powerful APIs to combine meshes in run-time.&lt;/p&gt;

&lt;p&gt;Let's say you're driving a car. In the interior you see several elements such as the seats, the handles, the windshield and all the coffee mugs you accumulated over time. You customize these elements before the race starts.&lt;/p&gt;

&lt;p&gt;Once you made your choice and start the race, these elements become kind of static within your car. Let me explain this...&lt;/p&gt;

&lt;p&gt;The car itself is dynamic. After all, you're driving it .&lt;/p&gt;

&lt;p&gt;But all its non-moving inner parts? They can be considered static relative to the car object. The windshield will always remain at the same place within the car.&lt;/p&gt;

&lt;p&gt;Yet, Unity considers all these pieces to be dynamic. That's why static batching won't work in this situation.&lt;/p&gt;

&lt;p&gt;Still, we can profit from the static batching APIs to create these batches manually.&lt;/p&gt;

&lt;p&gt;The easy way is to use &lt;a href="https://docs.unity3d.com/ScriptReference/StaticBatchingUtility.Combine.html"&gt;StaticBatchingUtility.Combine&lt;/a&gt;. This function takes a root game object and will iterate over all its children and merge their geometry into a big single chunk. One requirement that is easy to forget is that the import settings of all sub-meshes to batch must allow &lt;em&gt;CPU &lt;/em&gt;&lt;em&gt;read/write&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The second way is by using &lt;a href="https://docs.unity3d.com/ScriptReference/Mesh.CombineMeshes.html"&gt;Mesh.CombineMeshes&lt;/a&gt;. This function indirectly takes a list of meshes and creates a combined mesh. You can then assign that mesh to a mesh filter and you're good to go.&lt;/p&gt;

&lt;p&gt;I simplified the explanation for both functions. Check the documentation for details on how to use them.&lt;/p&gt;

&lt;p&gt;In the image below, you see how I applied the power of the StaticBatchingUtility API to batch a few dynamic tanks into a single static batch. And I do this in run-time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2020/01/Unity-Draw-Calls-Manual-Batching.jpg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1oOS0CQ---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Unity-Draw-Calls-Manual-Batching.jpg" alt="Unity Draw Calls: Manual Batching With StaticBatchingUtility.Combine" title="Unity Draw Calls: Manual Batching With StaticBatchingUtility.Combine" width="880" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Unity Draw Calls: Manual Batching With StaticBatchingUtility.Combine&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  See Draw Call Batching in Action
&lt;/h2&gt;

&lt;p&gt;I know...&lt;/p&gt;

&lt;p&gt;With so many possibilities, benefits and limitations, batching draw calls in Unity can be overwhelming at first.&lt;/p&gt;

&lt;p&gt;It's hard to understand in an hour what took me years to master.&lt;/p&gt;

&lt;p&gt;But you can take shortcuts.&lt;/p&gt;

&lt;p&gt;That's why I prepared a resources pack to guide you in optimizing your game.&lt;/p&gt;

&lt;p&gt;This is what you're getting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  A full-resolution image of the batching diagram, including a printable version to keep at hand&lt;/li&gt;
&lt;li&gt;  The Unity project with four scenes showing you how I apply the four batching techniques&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#predownload"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HA74ah1B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2020/01/Draw-Calls-Printable-Preview.jpg" alt="" width="880" height="578"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Get it &lt;a href="https://thegamedev.guru/unity-performance/draw-call-optimization/#download"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>csharp</category>
      <category>gamedev</category>
      <category>indiedev</category>
    </item>
    <item>
      <title>Breaking the Rules of Unity Garbage Collection</title>
      <dc:creator>The Gamedev Guru</dc:creator>
      <pubDate>Wed, 01 Jan 2020 21:02:42 +0000</pubDate>
      <link>https://dev.to/thegamedevguru/breaking-the-rules-of-unity-garbage-collection-1ni3</link>
      <guid>https://dev.to/thegamedevguru/breaking-the-rules-of-unity-garbage-collection-1ni3</guid>
      <description>&lt;p&gt;Once upon a time, there was a unity game programmer called Lancelot. A very passionate one, I would say. He didn't know yet, but eventually he would face the darkest side of Unity garbage collection.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F12%2FGC-GarbageCollection-Thumbnail.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F12%2FGC-GarbageCollection-Thumbnail.jpg" title="GC-GarbageCollection-Thumbnail"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(No time to read? Long story short version &lt;a href="https://thegamedev.guru/unity-performance/garbage-collection-manually/#tve-jump-16f62f5cca2" rel="noopener noreferrer"&gt;here&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Lancelot was always looking for bigger and &lt;strong&gt;bigger titles&lt;/strong&gt; to work on. And so he worked hard to get his big chance in the games industry.&lt;/p&gt;

&lt;p&gt;It was not easy, that he knew.&lt;/p&gt;

&lt;p&gt;These spots in the game industry were and still are reserved for a small minority of game programmers. And he wasn't sure he'd be up to the standards, anyway.&lt;/p&gt;

&lt;p&gt;But he persisted and continued to sharpen his programming skills.&lt;/p&gt;

&lt;p&gt;Lancelot started working on small games. Maybe at some point, he would get the big chance he was looking for, he thought.&lt;/p&gt;

&lt;p&gt;Years passed till he got the opportunity he was waiting for. He was asked to port a big VR game to a mobile platform. As excited as Lancelot was, he couldn't stop wondering if he was &lt;strong&gt;good enough&lt;/strong&gt; for the task. It was daunting but he accepted the challenge. He knew that he could only grow out of that.&lt;/p&gt;

&lt;p&gt;Lancelot's biggest concern was the need to massively improve the performance of the game. It was a double challenge, in fact. He had to &lt;strong&gt;improve &lt;/strong&gt;&lt;strong&gt;performance by 20% &lt;/strong&gt;for a considerably &lt;strong&gt;less powerful platform&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After months of non-stop work, he finally managed to optimize the game enough to have a rock-solid performance baseline.&lt;/p&gt;

&lt;p&gt;However, an unexpected issue was just around the corner​...&lt;/p&gt;

&lt;p&gt;The unity profiler revealed him a considerable frame-rate drop every few seconds. And that worried him, because that wouldn't allow him to ship the game. The game release was in jeopardy. That made him utterly uncomfortable.&lt;/p&gt;

&lt;p&gt;Based on his previous experience, Lancelot quickly suspected of the &lt;strong&gt;garbage collector&lt;/strong&gt;. After all, he knew that allocating temporary memory in the game too often could cause these performance spikes. Just like the trash can in everyone's kitchen, you know it's time to clean it when it reaches 80% of its capacity.&lt;/p&gt;

&lt;p&gt;And so he spent days fighting the bothersome memory allocations. He performed all types of optimizations he could think of. Object pools, data caching, data structure optimizations...&lt;/p&gt;

&lt;p&gt;Spending these days optimizing got him a bit ahead in the performance journey. Lancelot was proud of his work, but his concerns only grew when he saw the garbage collector still running every 15 seconds.&lt;/p&gt;

&lt;p&gt;Playing the game in VR with these performance drops would somehow make people look pale.&lt;/p&gt;

&lt;p&gt;"How could that be happening?" he wondered.&lt;/p&gt;

&lt;p&gt;With more patience and digging, Lancelot discovered a second source of memory allocations he didn't see before. Those happened in a &lt;strong&gt;3rd party library&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;He had a look and soon realized he was in the worst position ever: that library was closed source. Not only that, he also tried using Unity's &lt;strong&gt;incremental garbage collector&lt;/strong&gt; but he couldn't afford to pay its performance price.&lt;/p&gt;

&lt;p&gt;Lancelot was running out of options.&lt;/p&gt;

&lt;p&gt;He felt desperate but managed to keep calm. He's been in worse situations after all.&lt;/p&gt;

&lt;p&gt;He could &lt;strong&gt;reverse engineer&lt;/strong&gt; the library and do the memory allocation optimizations himself. The problem was that the license disallowed such things. And he was too young to go to jail.&lt;/p&gt;

&lt;p&gt;The second option he considered was to &lt;strong&gt;pre-allocate&lt;/strong&gt; a lot of memory on the heap. He knew that unity triggered the garbage collection process when the heap usage reached a certain percentage. So increasing the heap should give him more time between garbage collections.&lt;/p&gt;

&lt;p&gt;Sadly, that was still not enough.&lt;/p&gt;

&lt;p&gt;It slowly felt as if he had no control over the situation. It was tough, but again, he &lt;strong&gt;persisted&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So Lancelot came up with a &lt;strong&gt;crazy idea&lt;/strong&gt;. What if he disabled the garbage collection entirely? Was that even possible? He felt in his bones how risky such an idea was. He didn't want to add the possibility for the game to crash at unpredictable points. Last time he checked, that was no fun for the players. Maybe times did change, but better safe than sorry.&lt;/p&gt;

&lt;p&gt;On top of that, he worried about delaying the release of the game. He didn't want his players to miss this title for Christmas. He remembered how much fun he had playing &lt;em&gt;EverQuest&lt;/em&gt; during these holidays. He wouldn't take that away from the players.&lt;/p&gt;

&lt;p&gt;Reached this point, he had no other choice than to disable the garbage collector.&lt;/p&gt;

&lt;p&gt;He got into research mode and found that he could indeed &lt;strong&gt;manually disable the garbage collection&lt;/strong&gt;. He ran dozens of experiments to see how long the game would hold without running out of memory. He did all sorts of tests to stress the system. Clicking everywhere, walking and jumping around, switching between different applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Numbers &lt;/strong&gt;started arriving in his spreadsheet: 25 minutes, 28 minutes, 30 minutes... He also noted how the heap usage increased over time to be certain he'd never exceed a safe budget.&lt;/p&gt;

&lt;p&gt;With those numbers, Lancelot established a generous &lt;strong&gt;safe margin&lt;/strong&gt; and prepared a &lt;strong&gt;prototype&lt;/strong&gt;. He would run the garbage collection manually during loading screens and every few minutes.&lt;/p&gt;

&lt;p&gt;He had hope again.&lt;/p&gt;

&lt;p&gt;He politely asked QA to go through the game dozens of times.&lt;/p&gt;

&lt;p&gt;Memory was always within the budget. No crashes. No side effects.&lt;/p&gt;

&lt;p&gt;This long journey brought him to the point where he was able to &lt;strong&gt;ship &lt;/strong&gt;the game.&lt;/p&gt;

&lt;p&gt;And guess what? Hundreds of players are now enjoying it over the Christmas period.&lt;/p&gt;

&lt;p&gt;In the beginning, he was not comfortable with this solution. It was a risky move and he knew it. But he managed to pull it off.&lt;/p&gt;

&lt;p&gt;Lancelot learned to be comfortable with the &lt;strong&gt;uncomfortable&lt;/strong&gt;. He learned to be more &lt;strong&gt;pragmatic&lt;/strong&gt;. Because there are times when a programmer has to be.&lt;/p&gt;

&lt;p&gt;Does anything of the story ring a bell? If so, your intuition is probably right.&lt;/p&gt;

&lt;p&gt;That programmer was me.&lt;/p&gt;

&lt;p&gt;For the times you need it, this is how you can manage the &lt;a href="https://docs.unity3d.com/ScriptReference/Scripting.GarbageCollector.GCMode.html" rel="noopener noreferrer"&gt;garbage collector&lt;/a&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class GarbageCollectionManager : MonoBehaviour
{
  [SerializeField] private float maxTimeBetweenGarbageCollections = 60f;
  private float _timeSinceLastGarbageCollection;

  private void Start()
  {
#if !UNITY_EDITOR
    GarbageCollector.GCMode = GarbageCollector.Mode.Disabled;
#endif
    // You might want to run this during loading times, screen fades and such.
    // Events.OnScreenFade += CollectGarbage;
  }

  private void Update()
  {
    _timeSinceLastGarbageCollection += Time.unscaledDeltaTime;
    if (_timeSinceLastGarbageCollection &amp;gt; maxTimeBetweenGarbageCollections)
    {
      CollectGarbage();
    }
  }

  private void CollectGarbage()
  {
    _timeSinceLastGarbageCollection = 0f;
    Debug.Log("Collecting garbage"); // talking about garbage... 
#if !UNITY_EDITOR
    // Not supported on the editor
    GarbageCollector.GCMode = GarbageCollector.Mode.Enabled;
    GC.Collect();
    GarbageCollector.GCMode = GarbageCollector.Mode.Disabled;
#endif
  }
}

~~~~

That code snippet shows you how to disable automatic garbage collections. It runs the GC process manually every minute and possibly during screen transitions (fade to black).

Be aware of its possible **side effects**:

-   **Crashes**: if you don't play safe enough you'll run out of memory. Worse, the OS might kill your game when you switch between applications
-   **Longer garbage collection times**: increasing the heap will make future garbage collections slower

If you need to **produce generous amounts of garbage**, here's a straightforward method that'll just work:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;public class GenerousGarbageCreator : MonoBehaviour&lt;br&gt;
{&lt;br&gt;
  [SerializeField] private int garbageCreationRate = 1024;&lt;br&gt;
  private static int[] _garbage;&lt;br&gt;
  void Update()&lt;br&gt;
  {&lt;br&gt;
    _garbage = new int[garbageCreationRate];&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;~~~~&lt;/p&gt;

&lt;p&gt;This is what you'll be getting in the profiler:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F12%2FGC-Garbage-Collection-Management-Highlight.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F12%2FGC-Garbage-Collection-Management-Highlight.gif" title="GC-Garbage-Collection-Management-Highlight" alt="Unity Garbage Collection: Time-Based Manual Trigger"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unity Garbage Collection: Time-Based Manual Trigger&lt;/p&gt;

&lt;p&gt;There you see an increasing memory usage. The growing heap usage is highlighted as "mono". Luckily for us, we're running the manual garbage collector every 3 seconds.&lt;/p&gt;

&lt;p&gt;You can clearly see this &lt;strong&gt;garbage generation-clearance cycle&lt;/strong&gt; in the profiler graph. For those game developers who studied physics, you might recognize it as a sawtooth wave shape.&lt;/p&gt;

&lt;p&gt;For more general memory optimizations, you might be interested in &lt;a href="https://thegamedev.guru/unity-addressables/benefits-for-your-game/" rel="noopener noreferrer"&gt;Unity Addressables&lt;/a&gt;. With addressables you get to reduce your total memory usage so you can trigger garbage collections less frequently. In turn, this will reduce the performance spikes your players will experience.&lt;/p&gt;

&lt;p&gt;If you want the source code of this project, you know where to find it (spoiler: &lt;a href="https://thegamedev.guru/unity-performance/garbage-collection-manually/#download" rel="noopener noreferrer"&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;I'm looking forward to working with you all in 2020. Happy new year.&lt;/p&gt;

&lt;p&gt;Ruben&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>csharp</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Unity: Your Scene Hierarchy is Robbing you Performance</title>
      <dc:creator>The Gamedev Guru</dc:creator>
      <pubDate>Thu, 21 Nov 2019 07:03:17 +0000</pubDate>
      <link>https://dev.to/thegamedevguru/unity-your-scene-hierarchy-is-robbing-you-performance-3gc4</link>
      <guid>https://dev.to/thegamedevguru/unity-your-scene-hierarchy-is-robbing-you-performance-3gc4</guid>
      <description>&lt;p&gt;&lt;em&gt;You've optimized all of the low-hanging fruits of your game. Except that you didn't. You missed a sneaky, non-so-obvious spot: optimizing your Unity Scene Hierarchy.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;[The original entry with its formatting can be found at &lt;a href="https://thegamedev.guru/unity-performance/scene-hierarchy-optimization/" rel="noopener noreferrer"&gt;Unity Optimization: Your Scene Hierarchy is Robbing you Performance&lt;/a&gt;&lt;/em&gt;&lt;em&gt;]&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F11%2FUnity-Optimization-Hierarchy-Thumbnail.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F11%2FUnity-Optimization-Hierarchy-Thumbnail.jpg" title="Unity-Optimization-Hierarchy-Thumbnail"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What's the crack with the hierarchy now?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I want to show you something.&lt;/p&gt;

&lt;p&gt;Launch Unity and open your game project. Then, run your game on your target device and attach the Unity Profiler to it. Record a few frames during gameplay.&lt;/p&gt;

&lt;p&gt;In the Unity Profiler, look for the following unpleasant &lt;strong&gt;profiler &lt;/strong&gt;&lt;strong&gt;markers&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;UpdateRenderer&lt;/strong&gt;&lt;strong&gt;Bounding&lt;/strong&gt;&lt;strong&gt;Volumes&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Physics.SyncColliderTransform&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Transform&lt;/strong&gt;&lt;strong&gt;Changed&lt;/strong&gt;&lt;strong&gt;â&lt;/strong&gt;&lt;strong&gt;€‹&lt;/strong&gt;&lt;strong&gt;Dispatch&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;You didn't find any?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Keep looking. I'm sure you'll find at least one.&lt;/p&gt;

&lt;p&gt;They'll spawn when you're about to give up. As soon as you mouse over the close button of the Profiler, they'll show up.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Found them already?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If so, it's your lucky day.&lt;/p&gt;

&lt;p&gt;I discovered those in my previous project as well and I learned how to &lt;strong&gt;land a final blow to them&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I know the evil behind them...&lt;/p&gt;

&lt;p&gt;Do you want to know the &lt;strong&gt;performance secrets of Unity Scene Hierarchies&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick Navigation (opens in a new tab)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/unity-performance/scene-hierarchy-optimization/#tab-con-6" rel="noopener noreferrer"&gt;Level 1 Developer: A Typical Unity Scene Hierarchy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/unity-performance/scene-hierarchy-optimization/#tab-con-2" rel="noopener noreferrer"&gt;Level 2 Developer: An Optimized Unity Scene Hierarchy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/unity-performance/scene-hierarchy-optimization/#tab-con-1" rel="noopener noreferrer"&gt; The Gamedev Guru's Golden Rules of a Clean Unity Scene Hierarchy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/unity-performance/scene-hierarchy-optimization/#tab-con-3" rel="noopener noreferrer"&gt;Level 3 Developer: The FAP Hierarchy Tool&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/unity-performance/scene-hierarchy-optimization/#tab-con-5" rel="noopener noreferrer"&gt; The Gamedev Guru's Hierarchy Score&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F09%2Fthe-gamedev-guru-logo-full.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F09%2Fthe-gamedev-guru-logo-full.jpg" title="the-gamedev-guru-logo-full"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 1 Developer: A Typical Unity Scene Hierarchy
&lt;/h2&gt;

&lt;p&gt;I still remember the first Unity project I worked on, just slightly over a decade ago.&lt;/p&gt;

&lt;p&gt;I was not sure what the difference between game objects and components were.&lt;/p&gt;

&lt;p&gt;But that didn't matter. I created games anyway.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F11%2FUnity-Scene-Hierarchy-Optimization-Deep-Hierarchy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F11%2FUnity-Scene-Hierarchy-Optimization-Deep-Hierarchy.png" title="Unity-Scene-Hierarchy-Optimization-Deep-Hierarchy" alt="Deep Unity Scene Hierarchy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Deep Unity Scene Hierarchy&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Was it uncommon to see a messy unity scene hierarchy like this?&lt;/p&gt;

&lt;p&gt;Actually, yes. Because it used to be worse than that.&lt;/p&gt;

&lt;p&gt;Interestingly enough, you can get away with this kind of hierarchies most of the time.&lt;/p&gt;

&lt;p&gt;But you'll suffer. You'll pay the price later on.&lt;/p&gt;

&lt;p&gt;Luckily, before I started developing games professionally, I learned to appreciate more structured hierarchies.&lt;/p&gt;

&lt;p&gt;A great scene hierarchy structure can be your best friend. Structure makes development and collaboration much easier.&lt;/p&gt;

&lt;p&gt;It doesn't have to be the best, whatever that means. It's enough for it to be good.&lt;/p&gt;

&lt;p&gt;But bear with me here. &lt;strong&gt;This is important.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Having a cluttered unity scene hierarchy is dangerous and will get you into trouble. This is so because it's highly unlikely you'll directly notice its side effects.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;There'll be a creepy ghost chasing you, pulling you back, slowing you down. Sometimes you think you hear something, but when you look back, there's nothing. So you get used to walking slower.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I learned to diagnose these side effects over the years. And the main problem is that the side effects of a messy unity scene hierarchy are not obvious to spot.&lt;/p&gt;

&lt;p&gt;You'll see the profiler and wonder what some markers mean. Their names are often cryptic... what secrets do they hide?&lt;/p&gt;

&lt;p&gt;The only thing you can be sure of is this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mysterious markers tell you something's worth investigating&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you and I talk about structuring your scenes better, we usually discuss about increasing clarity and reducing maintenance cost.&lt;/p&gt;

&lt;p&gt;But performance? Just like my cat *gitignores *all the toys she has around my flat, everybody forgets about performance when it comes to the Unity Scene Hierarchy.&lt;/p&gt;

&lt;p&gt;Let's analyze the previously shown unity scene hierarchy. It contains &lt;strong&gt;2,000 rotating spheres nested on top of each other&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;What does the profiler say about it? Look, don't be scared.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/11/Unity-Scene-Hierarchy-Optimization-Deep-Hierarchy-Profiler-Overview.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F11%2FUnity-Scene-Hierarchy-Optimization-Deep-Hierarchy-Profiler-Overview.png" title="Unity-Scene-Hierarchy-Optimization-Deep-Hierarchy-Profiler-Overview" alt="Unity Scene Hierarchy Optimization-Deep-Hierarchy Profiler Overview"&gt;&lt;/a&gt;&lt;em&gt;Unity Scene Hierarchy Optimization-Deep-Hierarchy Profiler Overview&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That's pretty bad for a simple prefab and a rotation script applied to a built-in sphere.&lt;/p&gt;

&lt;p&gt;As you can see, *Physics.SyncColliderTransform *and *UpdateRendererBoundingVolumes *are taking a huge portion of your frame budget.&lt;/p&gt;

&lt;p&gt;But let's not stop analyzing there, because I'm quite curious about this case.&lt;/p&gt;

&lt;p&gt;Let's dig further. I hope you saved some 4G data this month for this impressive image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/11/Unity-Scene-Hierarchy-Optimization-Deep-Hierarchy-Profiler.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F11%2FUnity-Scene-Hierarchy-Optimization-Deep-Hierarchy-Profiler.png" title="Unity-Scene-Hierarchy-Optimization-Deep-Hierarchy-Profiler" alt="Unity Scene Hierarchy Optimization-Deep-Hierarchy Profiler Details"&gt;&lt;/a&gt;&lt;em&gt;Unity Scene Hierarchy Optimization-Deep-Hierarchy Profiler Details&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here lies the key of the article.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unoptimized hierarchies causes two BIG problems in Unity.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Deep hierarchies do not allow the job system to work efficiently in parallel.&lt;/li&gt;
&lt;li&gt;  Nested hierarchies cause bottlenecks in several subsystems within Unity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember my words...&lt;/p&gt;

&lt;p&gt;Because &lt;strong&gt;this applies to all types of dynamic objects&lt;/strong&gt; and especially user interfaces.&lt;/p&gt;

&lt;p&gt;In case you're wondering, I own a Threadripper with 16 physical cores and 32 threads. Do you know how many am I using effectively in this project? Just one.&lt;/p&gt;

&lt;p&gt;There're so many ways to say the same: the performance of your game will suffer. And by trying to fix this mess by following your gut feeling based on those mysterious names, you'll start to age blazingly faster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What would a Level 2 Developer do with 2,000 objects?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F10%2Flaptop-coffee.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F10%2Flaptop-coffee.jpg" title="laptop-coffee"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 2 Developer: An Optimized Unity Scene Hierarchy
&lt;/h2&gt;

&lt;p&gt;A Level 2 Unity Developer knows that parenting transforms comes at a price.&lt;/p&gt;

&lt;p&gt;The Level 2 Developer also knows this price is paid in milliseconds of CPU time. Or, similarly put, it is paid in hours of overtime spent by the developer chasing this up.&lt;/p&gt;

&lt;p&gt;Ask yourself: do you have enough CPU budget to pay for this expensive hierarchy?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;From which area of your game are you subtracting those milliseconds from&lt;/strong&gt;&lt;strong&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Will your game bombard the player with less and less flashy particles? Or will you cut the number of city invaders your player will have to defend from?&lt;/p&gt;

&lt;p&gt;Hopefully, you'll do nothing of these two things., but rather...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F10%2Fruben-portrait.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F10%2Fruben-portrait.jpg" title="ruben-portrait"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Create efficient Scene Hierarchies. Destroy those who aren't so." &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Rubén Torres Bonet&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The reason complicated parenting steals resources from your game is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Each transform modification affects its children and potentially its parent and siblings&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unity recalculates a lot of thingies for you when you change an object's position, rotation or scale.&lt;/p&gt;

&lt;p&gt;This process is transparently done for you, so you can focus on developing your game. That is great, but the price to pay for it becomes astronomical if you're caught off-guard.&lt;/p&gt;

&lt;p&gt;The solution?&lt;/p&gt;

&lt;p&gt;Keep it simple, adhere to...&lt;/p&gt;

&lt;h3&gt;
  
  
   The Gamedev Guru's Golden Rules of a Clean Unity Scene Hierarchy
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;No more than &lt;a href="http://es-from-the-spotlight-team-optimizing-the-hierarchy/" rel="noopener noreferrer"&gt;50&lt;/a&gt; total child elements per game object&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;No more than 4 levels of depth in any game object&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Isn't that simple?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A Level 2 Developer will keep their unity scene hierarchies as flat as possible.&lt;/p&gt;

&lt;p&gt;Look below. Same amount of objects, this time structured under a flat hierarchy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/11/Unity-Scene-Hierarchy-Optimization-Flat-Hierarchy-Profiler.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F11%2FUnity-Scene-Hierarchy-Optimization-Flat-Hierarchy-Profiler.png" title="Unity-Scene-Hierarchy-Optimization-Flat-Hierarchy-Profiler"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Savings are huge, I see.&lt;/p&gt;

&lt;p&gt;But doing this is easier said than done, right? Detaching and destroying relation(ships) between objects is a laborious, error-prone and time-intensive task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What would a Level 3 developer do?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F09%2FTime.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F09%2FTime.jpg" title="Time"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 3 Developer: The FAP Hierarchy Tool
&lt;/h2&gt;

&lt;p&gt;A good Unity developer gets things done.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;great &lt;/strong&gt;Unity developer gets things done faster, more accurately.&lt;/p&gt;

&lt;p&gt;But how is that?&lt;/p&gt;

&lt;p&gt;By using tools.&lt;/p&gt;

&lt;p&gt;Because the only cheap hierarchy is the empty one, there's one key answer you need to answer at all points from your game...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How complex are your hierarchies?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can answer this by methodically analyzing your hierarchies and giving it a score.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Gamedev Guru's  Hierarchy Score&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Below 35: Smells of Trouble. RUN!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Around 50: You might be OK (For now)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Above 70: Profit! (But don't relax)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So what are the math formulas I need to calculate the score?&lt;/p&gt;

&lt;p&gt;Luckily, none. I've done this for you.&lt;/p&gt;

&lt;p&gt;I prototyped a tool to automatically analyze and detect bottlenecks in your hierarchy based on The Gamedev Guru's Golden Rules of a Clean Hierarchy.&lt;/p&gt;

&lt;p&gt;I call this tool...&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Fabulous Advanced Profiling &lt;/strong&gt;Hierarchy Tool&lt;/p&gt;

&lt;p&gt;Run your game. Get to a point of interest. Open the tool and let it do the work for you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/11/Unity-Scene-Hierarchy-Optimization-Gamdev-Guru-FAP-Hierarchy-Tool.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthegamedev.guru%2Fwp-content%2Fuploads%2F2019%2F11%2FUnity-Scene-Hierarchy-Optimization-Gamdev-Guru-FAP-Hierarchy-Tool.png" title="Unity-Scene-Hierarchy-Optimization-Gamdev-Guru-FAP-Hierarchy-Tool" alt="The Gamedev Guru's FAP Hierarchy Tool"&gt;&lt;/a&gt;&lt;em&gt;The Gamedev Guru's FAP Hierarchy Tool&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let the tool *whisper *in your ear the magical melody of an integer that we will call... score.&lt;/p&gt;

&lt;p&gt;Once you know what your score is, you know what to do... Or not?&lt;/p&gt;

&lt;p&gt;Because I'm not giving you only that tool, but also a bonus script to boost your hierarchy problem-solving techniques.&lt;/p&gt;

&lt;p&gt;I'm giving you the extraordinary power of the simple *DetachGameObject.cs *Demigod script.&lt;/p&gt;

&lt;p&gt;You're not likely to encounter many 27-line scripts that will help you improving performance so much in that small time frame.&lt;/p&gt;

&lt;p&gt;What this does is simple: it'll move your heavy and nested game objects to the root of the scene hierarchy in run-time. That way, you'll profit from having &lt;strong&gt;structured hierarchies during development&lt;/strong&gt; and gain an &lt;strong&gt;insane performance advantage during run-time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Chances are, you can do this for the great part of your hierarchy that is heavily nested for structure's sake.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/unity-performance/scene-hierarchy-optimization/#tab-con-5" rel="noopener noreferrer"&gt;&lt;strong&gt;Claim your &lt;/strong&gt;free bonuses***&lt;em&gt;** before they become a 404 error&lt;/em&gt;*&lt;/a&gt; (opens in a new tab)&lt;/p&gt;

&lt;p&gt;And after that? Comment below and &lt;strong&gt;share your score&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>csharp</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Unity UI: My Top 3 Optimization Strategies</title>
      <dc:creator>The Gamedev Guru</dc:creator>
      <pubDate>Sat, 12 Oct 2019 10:13:58 +0000</pubDate>
      <link>https://dev.to/thegamedevguru/unity-ui-my-top-3-optimization-strategies-2p71</link>
      <guid>https://dev.to/thegamedevguru/unity-ui-my-top-3-optimization-strategies-2p71</guid>
      <description>&lt;p&gt;[&lt;em&gt;Read the original blog post on &lt;a href="https://thegamedev.guru/unity-ui/optimization-strategies/"&gt;Unity UI Optimization&lt;/a&gt; at The Gamedev Guru's Blog&lt;/em&gt;]&lt;/p&gt;

&lt;p&gt;I normally do not share my past struggles, but this topic deserves it.&lt;br&gt;
What to do when you lose hope with &lt;em&gt;Unity UI&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;I still remember that weekend, about five years ago...&lt;/p&gt;

&lt;p&gt;I spent the entire weekend worried about all the technical debt I was&lt;br&gt;
accumulating over the months in one of my projects. I had done&lt;br&gt;
things *too *quickly, without really understanding them. Clearly enough,&lt;br&gt;
that had to stop working at some point.&lt;/p&gt;

&lt;p&gt;The thing is, I owed my clients results but I had no idea how to bring&lt;br&gt;
them. That morning though, I said to myself: &lt;em&gt;Rubén, this is enough.&lt;br&gt;
Stop the excuses. You are becoming a professional today.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So, I decided to gather every single resource I could find about user&lt;br&gt;
interfaces in Unity, because that was the biggest hurdle I was dealing&lt;br&gt;
with for several weeks. I read forums, best practices, Unite videos,&lt;br&gt;
read all blogs I could find on that topic and did my own research.&lt;/p&gt;

&lt;p&gt;Did you ever experience this feeling of slowly getting overwhelmed by&lt;br&gt;
technical debt? It accumulates over time and someday you either give up&lt;br&gt;
or decide to crush it. In my case, it was the later.&lt;/p&gt;

&lt;p&gt;You probably heard that optimizing UI in Unity is challenging. Or, if&lt;br&gt;
lucky, you know it from first-hand experience. Yes, Unity UI is a&lt;br&gt;
powerful tool and I love it. However, its mightiness can quickly&lt;br&gt;
transform into a deadly weapon if it falls into inexperienced hands. And&lt;br&gt;
so were my hands back then.&lt;/p&gt;

&lt;p&gt;If I had to confess anything to you today, it would be this: I wished I&lt;br&gt;
had had a solid foundation on Unity UI before I designed the UI of&lt;br&gt;
several games.&lt;/p&gt;

&lt;p&gt;It is SO easy to do it wrong, SO easy to get frustrated. In my opinion,&lt;br&gt;
there's something even easier than that. That is, for your client to&lt;br&gt;
ask you to do over-hours to get your shit together.&lt;/p&gt;

&lt;p&gt;In my experience in the professional sector, &lt;strong&gt;companies do not want&lt;br&gt;
developers who design poorly optimizable interfaces and leave the tuning&lt;br&gt;
task to experienced programmers&lt;/strong&gt;. They rather want developers who&lt;br&gt;
create visually stunning interfaces, but also performant.&lt;/p&gt;

&lt;p&gt;And even in the indie development scene, where would you choose to spend&lt;br&gt;
your time on? Bringing fun to your players, or spending hours clicking&lt;br&gt;
through the profiler to find bottlenecks?&lt;/p&gt;

&lt;p&gt;In my opinion: no matter your role, you should understand basic Unity UI&lt;br&gt;
design principles. But this takes time and project experience. You might&lt;br&gt;
not have any of these.&lt;/p&gt;

&lt;p&gt;Hopefully, I can help you there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Today, I will give you one of my most powerful tools: The Guru's UI&lt;br&gt;
Development Diagram&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As usual, I'd like to start with the Level 1 Developer construct&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--91iV_TMg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/unity-ui-update-batches-layout-spikes.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--91iV_TMg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/unity-ui-update-batches-layout-spikes.jpg" alt="Level 1 Unity UI Developer: UpdateBatches &amp;amp; Layout Spikes in Unity&amp;lt;br&amp;gt;
UI" title="unity-ui-update-batches-layout-spikes" width="880" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 1 Unity UI Developer: free-style UI
&lt;/h2&gt;

&lt;p&gt;This is where we all start: free-style design, free-style results.&lt;/p&gt;

&lt;p&gt;I used to import sprites with whatever settings. Then, I would add them&lt;br&gt;
as images everywhere with no predefined criteria. And so I ended up with&lt;br&gt;
an unstructured hierarchy full of components that I didn't need. I used&lt;br&gt;
the wrong systems for the wrong reasons.&lt;/p&gt;

&lt;p&gt;Overlapping UI elements, a motherload of batches, profiler spikes. Those&lt;br&gt;
are all common.&lt;/p&gt;

&lt;p&gt;Do I have anything against this?&lt;/p&gt;

&lt;p&gt;Partially. I think it is great to play around and to make mistakes.&lt;br&gt;
Breaking and repairing help learning.&lt;/p&gt;

&lt;p&gt;But if you want to do this for a living, at some point you might want to&lt;br&gt;
level up your skills and embrace professionalism.&lt;/p&gt;

&lt;p&gt;This becomes unacceptable in the games industry, especially in Virtual&lt;br&gt;
Reality. If you do this in VR you will turn players into patients.&lt;/p&gt;

&lt;p&gt;Such a chaotic Canvas hierarchy structure could look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cRr7HLqA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/unity-ui-unstructured-hierarchy-e1567930044845.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cRr7HLqA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/unity-ui-unstructured-hierarchy-e1567930044845.jpg" alt="Level 1 Unity UI Developer: Unstructured Unity UI&amp;lt;br&amp;gt;
Hierarchy" title="unity-ui-unstructured-hierarchy" width="500" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 1 Unity UI Developer: Unstructured Unity UI Hierarchy
&lt;/h2&gt;

&lt;p&gt;You do a lot of nesting, you use auto-layout components everywhere and&lt;br&gt;
there is a lack of rules.&lt;/p&gt;

&lt;p&gt;At some point, someone will ask you to optimize your UI. That could be&lt;br&gt;
your players, your boss or even your own pride.&lt;/p&gt;

&lt;p&gt;But you might not be ready for this. You might be caught off-guard&lt;br&gt;
having other tasks on your plate. And UI development is daunting at the&lt;br&gt;
beginning.&lt;/p&gt;

&lt;p&gt;The reason for its complexity lies in the amount of factors it involves.&lt;br&gt;
Leaving the visual appeal aside, you can say that &lt;strong&gt;the way you work&lt;br&gt;
with Unity UI will have a big impact in three critical hardware pieces:&lt;br&gt;
the CPU, the GPU, and the developer theirself&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you are lost, it's good, because...&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I am about to show you something cool&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's level up as a developer!&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PgUlFY_X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/the-gamedev-guru-Unity-UI-development-diagram.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PgUlFY_X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/the-gamedev-guru-Unity-UI-development-diagram.jpg" alt="Level 2 Unity UI Developer: The Guru's UI Development&amp;lt;br&amp;gt;
Diagram" title="the-gamedev-guru-Unity-UI-development-diagram" width="800" height="1026"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Level 2 Unity UI Developer: The Guru's UI Development Diagram
&lt;/h1&gt;

&lt;p&gt;Here we are with a Venn Diagram. I decided to call it &lt;em&gt;The Guru's UI&lt;br&gt;
Development Diagram&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;There we see three big chunks related to Unity UI Optimization: CPU,&lt;br&gt;
GPU, and Developer. Those are the main resources you will have to spare&lt;br&gt;
when developing UI.&lt;/p&gt;

&lt;p&gt;I want to give you a short overview before we start digging in the&lt;br&gt;
topics.&lt;/p&gt;

&lt;p&gt;You pay the CPU toll mainly when generating and submitting batches of&lt;br&gt;
UI. You can think of them as UI components, such as images. The more of&lt;br&gt;
those you have, the more strain you will put in your processor.&lt;/p&gt;

&lt;p&gt;The turn for the GPU. You pay the GPU resources mostly in concept of&lt;br&gt;
overdraw. This means, stacking layers of graphics on top of each&lt;br&gt;
other.&lt;/p&gt;

&lt;p&gt;Lastly, the developer pain is paid in time. You spend time every time&lt;br&gt;
you design or maintain your UI. Unity offers you some tools to make it&lt;br&gt;
easier for you, e.g. auto-layout helpers.&lt;/p&gt;

&lt;p&gt;The cost of the three components rely mostly on you, but they sometimes&lt;br&gt;
counteract each other. It's very challenging to perform in every&lt;br&gt;
aspect, unless you are very experienced and you have the right tools.&lt;/p&gt;

&lt;p&gt;Eventually, you will get there.&lt;/p&gt;

&lt;p&gt;I would like you to have a closer look at the attached &lt;strong&gt;Guru's UI&lt;br&gt;
Development Diagram&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You might be confused. That's alright because we are going to cover&lt;br&gt;
each section separately. You will get to understand all of it.&lt;/p&gt;

&lt;p&gt;For now, you only have to understand one thing: in the end, it will be&lt;br&gt;
up to you to find the balance between the three variables in your game.&lt;/p&gt;

&lt;p&gt;Before we start with each component, have a look at these general rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The easier you want the UI design workflow to be, the less
performant your UI will be.&lt;/li&gt;
&lt;li&gt;  If you want more GPU performance, you will have to focus on finely
tweaking graphical elements and avoid element stacking.&lt;/li&gt;
&lt;li&gt;  For more CPU performance, you will need to reduce the amount of
graphical elements present in the hierarchy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's move on, I can't wait to show you the CPU side of Unity UI&lt;br&gt;
Optimization!&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bW9fxLCl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Unity-UI-optimization-diagram-cpu-only.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bW9fxLCl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Unity-UI-optimization-diagram-cpu-only.jpg" alt="Level 2 Unity UI Developer: The&amp;lt;br&amp;gt;
CPU" title="Level 2 Unity UI Developer: The CPU" width="811" height="792"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Level 2 Unity UI Developer: The CPU
&lt;/h3&gt;

&lt;p&gt;In my opinion, this is very simple.&lt;/p&gt;

&lt;p&gt;The golden rule is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Every time you add a UI component in your scene, you are adding CPU&lt;br&gt;
overhead&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each component increases the CPU cost for the following reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;RectTransform calculation:&lt;/strong&gt; this is pretty much free in simple
canvas hierarchies. However, your CPU will have a harder time if you
are using &lt;a href="https://docs.unity3d.com/Manual/comp-UIAutoLayout.html"&gt;auto-layout components&lt;/a&gt; to ease your UI design workflow, such as vertical layout groups and such. The issue with those is that most *RectTransforms *present in the hierarchy will now depend on each other, so the calculation becomes more complex.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Vertex generation&lt;/strong&gt;: the GPU understands vertices, thus those must
be provided by the CPU. Vertices must be generated based on the
entire canvas hierarchy of the involved &lt;em&gt;RectTransform&lt;/em&gt; elements*. *The vertices depend as well on
the specific type of UI element you added (images, texts). Under
this category, we also include the cost for the CPU to add other
per-vertex attributes such as colors and UVs.&lt;/li&gt;
&lt;/ul&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Dynamic batching&lt;/strong&gt;: because draw calls are expensive, Unity does
its best to dynamically batch as many of them as possible.
Think of this as combining a large number of small groups of
vertices into a single, huge group of vertices. Because... would
you rather go to the supermarket ten times to bring an apple each,
or go just once and grab them all together?
Batching is, however, an expensive operation for the CPU which
increases with the amount of UI elements you have.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Draw call emission&lt;/strong&gt;: finally, the generated batches must be sent
to the GPU. These graphical processing units are very picky with the
data formats they accept, so the CPU has to make extra work to pack
them in a way that they like.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is expensive, yes. But luckily for us, Unity is kind of smart and&lt;br&gt;
caches the canvas so these expensive processes do not happen in every&lt;br&gt;
frame.&lt;/p&gt;

&lt;p&gt;Just as I brought you good news, I will give you the bad ones: this&lt;br&gt;
cache is super easy to break.&lt;/p&gt;

&lt;p&gt;Changing almost any attribute of any UI element will break the cache of&lt;br&gt;
your canvas. If that happens, we go through most of the process again.&lt;br&gt;
These changes, by the way, trigger what is called a &lt;strong&gt;canvas rebuild&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I'll give you some examples of the breaking changes: scaling,&lt;br&gt;
positioning, rotation, color, image swapping, animations and more.&lt;/p&gt;

&lt;p&gt;After exposing the basics, I want to conclude with three practical&lt;br&gt;
observations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The more elements you have in your Unity Canvas, the more CPU
overhead you will have on each canvas rebuild.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Avoid any kind of changes in UI to avoid canvas rebuilds&lt;/strong&gt;. If&lt;br&gt;
needed, then &lt;a href="https://thegamedev.guru/unity-ui-development-diagram/"&gt;put dynamic elements in different&lt;br&gt;
canvases&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Canvases are either static or dynamic. Design accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt; &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--agkPG1r0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Unity-UI-optimization-diagram-gpu-only.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--agkPG1r0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Unity-UI-optimization-diagram-gpu-only.jpg" alt="Level 2 Unity UI Developer: The&amp;lt;br&amp;gt;
GPU" title="Unity-UI-optimization-diagram-gpu-only" width="649" height="634"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Level 2 Unity UI Developer: The GPU
&lt;/h3&gt;

&lt;p&gt;Now is the turn for the friendly Graphical Processing Unit, don't you&lt;br&gt;
think?&lt;/p&gt;

&lt;p&gt;The GPU is the piece of hardware that makes us fall in love with games.&lt;br&gt;
We owe them so much. What about showing it some affection? Well, we&lt;br&gt;
can...&lt;/p&gt;

&lt;p&gt;By treating it well.&lt;/p&gt;

&lt;p&gt;But guess what? UI can make the GPU pretty upset. Especially mobile&lt;br&gt;
GPUs, where it is relatively easy to be memory-bound. To put it simply:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In mobile, there is a massive reason UI is expensive: overdraw!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;*Overdraw *happens when we render the same pixel multiple times per&lt;br&gt;
frame. And this is soooo easy to achieve with Unity.&lt;/p&gt;

&lt;p&gt;Every time to add a &lt;em&gt;Unity UI Image&lt;/em&gt;, you are commanding your GPU to&lt;br&gt;
draw a full rectangle, rendering every single pixel inside that&lt;br&gt;
rectangle. And it does not matter if the pixel you are drawing is&lt;br&gt;
transparent, it will cost you still.&lt;/p&gt;

&lt;p&gt;That means, I advise you to be careful with the transparent regions of&lt;br&gt;
your sprites!&lt;/p&gt;

&lt;p&gt;This has some implications for you. If you add 10 full-screen images,&lt;br&gt;
then you get 10x overdraw. As my grandmother used to say, &lt;em&gt;WTAIWYG&lt;/em&gt;!&lt;br&gt;
(&lt;em&gt;What You Add Is What You Get&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Stacking of layers on top of each other will slowly enrage your GPU. It&lt;br&gt;
will add milliseconds to it, which is a crime in VR games where your&lt;br&gt;
budget could very well be under 13ms.&lt;/p&gt;

&lt;p&gt;I do not want to get too technical in this post... but I can't just&lt;br&gt;
help it! Some day you will be having a delicious coffee break&lt;br&gt;
conversation with your colleagues and you might feel tempted to drop a&lt;br&gt;
few intellectual lines. If that's the case, say this one aloud:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UI Overdraw is expensive in mobile because you devour the precious&lt;br&gt;
memory bandwidth of the device and this is further worsened by the alpha&lt;br&gt;
blending happening internally&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You'll make some jaws drop.&lt;/p&gt;

&lt;p&gt;The key lesson is easy: avoid stacking UI elements on top of each other&lt;br&gt;
and you will be fine &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  GPU cost mainly comes from stacking graphical layers on top of each
other. Avoid these.&lt;/li&gt;
&lt;li&gt;  Reduce the space UI takes in screen to reduce GPU cost.&lt;/li&gt;
&lt;li&gt;  Implement sprite atlasing to improve CPU and GPU performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;PRO TIP #1&lt;/strong&gt;:  &lt;a href="https://thegamedev.guru/unity-ui/optimization-strategies/#protips"&gt;Sprite Atlasing&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PRO TIP #2&lt;/strong&gt;: &lt;a href="https://thegamedev.guru/unity-ui/optimization-strategies/#protips"&gt;Opaque UI Shading&lt;/a&gt; (&lt;strong&gt;Advanced&lt;/strong&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iTMvOJbD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Unity-UI-optimization-diagram-developer-only.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iTMvOJbD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Unity-UI-optimization-diagram-developer-only.jpg" alt="Level 2 Unity UI Developer: The&amp;lt;br&amp;gt;
Developer" title="Level 2 Unity UI Developer: The Developer" width="649" height="634"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Level 2 Unity UI Developer: The Developer!
&lt;/h3&gt;

&lt;p&gt;I am afraid we often under-estimate the effort required to design,&lt;br&gt;
implement and especially maintain optimized user interfaces in Unity.&lt;/p&gt;

&lt;p&gt;Surely, Unity improved in this area during the last few years and now it&lt;br&gt;
is easier and faster than ever to create those. But this comes at a&lt;br&gt;
cost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In general, the more Unity UI &lt;em&gt;extras&lt;/em&gt; you use, the worse your game&lt;br&gt;
will perform.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.unity3d.com/Manual/comp-UIAutoLayout.html"&gt;auto-layout&lt;/a&gt; helpers are especially expensive. Unfortunately, they are the most helpful. For&lt;br&gt;
instance, I find Vertical Layout Groups especially handy when designing&lt;br&gt;
responsive UI. These neat scripts help you organize your elements in a&lt;br&gt;
manner that is structured and therefore visually appealing.&lt;/p&gt;

&lt;p&gt;The problem I see with those is that they incur on a big CPU cost&lt;br&gt;
whenever there are &lt;em&gt;canvas rebuilds&lt;/em&gt;!&lt;/p&gt;

&lt;p&gt;You might be able to get away with UI helpers if your UI is static 99%&lt;br&gt;
of the time, but the frame it isn't, you will notice it.&lt;/p&gt;

&lt;p&gt;We love working with helpers, but we don't want to ruin our&lt;br&gt;
performance. Here's one trick you can try: keep the auto-layout helpers&lt;br&gt;
around while designing but disable them all just before saving your&lt;br&gt;
scene. By doing this, they will be deactivated for run-time players, but&lt;br&gt;
they already did their work for you!&lt;/p&gt;

&lt;p&gt;I don't want to disappoint you, so just remember that this auto-layout&lt;br&gt;
disabling secret will not work if your UI content is dynamic.&lt;/p&gt;

&lt;p&gt;At the end of the day, the more tasks you delegate to Unity, the more&lt;br&gt;
work your hardware will have to do.  Find your own balance here! You can&lt;br&gt;
start using those helpers but be ready to remove them if you have to.&lt;/p&gt;

&lt;p&gt;While optimizing, do the biggest gains for the buck first. Only advance&lt;br&gt;
in the ladder of diminishing returns if the profiler tells you that you&lt;br&gt;
have to.&lt;/p&gt;

&lt;p&gt;For instance, creating sprite atlases is easy and will bring you good&lt;br&gt;
fortune. Tweaking graphics to avoid transparent regions, however, is&lt;br&gt;
more time-consuming. Lastly, creating your own UI shaders might bring&lt;br&gt;
you big gains but at a big cost.&lt;/p&gt;

&lt;p&gt;Remember, &lt;strong&gt;saving a few microseconds in your game might not be worth if&lt;br&gt;
it costs you weeks of your life-time&lt;/strong&gt; and your application does not&lt;br&gt;
need it. This should not be taken as an excuse to never&lt;br&gt;
care; &lt;strong&gt;optimizations in the future are more expensive than in the&lt;br&gt;
present&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Profile before you optimize&lt;/li&gt;
&lt;li&gt;  Keep profiling&lt;/li&gt;
&lt;li&gt;  Go for the biggest gains for the buck first&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2cb4N22A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Unity-UI-optimization-diagram-intersection.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2cb4N22A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Unity-UI-optimization-diagram-intersection.jpg" alt="The Guru's UI Development Diagram - Intersection&amp;lt;br&amp;gt;
Regions" title="Unity-UI-optimization-diagram-intersection" width="649" height="634"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 3 Developer: The Sweet Spots
&lt;/h2&gt;

&lt;p&gt;From the &lt;em&gt;Venn Diagram&lt;/em&gt;, you might see several sweet spots where you&lt;br&gt;
could find yourself in: &lt;em&gt;Fine-Grained UI Development&lt;/em&gt;, &lt;em&gt;Coarse-Grained&lt;br&gt;
UI Development&lt;/em&gt;, &lt;em&gt;Massive PP *and *Balance&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;They sounded quite obscure to me at the beginning, but then, with time,&lt;br&gt;
it all started to make sense to me. Experience brought understanding.&lt;/p&gt;

&lt;p&gt;What I still hold true is that, the more tools you know, the better.&lt;br&gt;
This is the main way I am able to recognize the subtle patterns in all&lt;br&gt;
problems. And, when you recognize the heart of the challenge, you know&lt;br&gt;
which tool to take out of your toolbox.&lt;/p&gt;

&lt;p&gt;Nothing will help your team more than having a developer possessing both&lt;br&gt;
a high-level overview of UI and an eye for detail.&lt;/p&gt;

&lt;p&gt;A Level 3 developer would confidently answer important practical&lt;br&gt;
questions that only come through experience. I can think of a few that&lt;br&gt;
any client could ask you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Here's a UI architecture for you. How performant is it?&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;What are 3 alternatives I have to optimize this user interface?&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Can you show me numerical proof?&lt;/em&gt;
 &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You see, I prepared a few Unity examples for you.&lt;/p&gt;

&lt;p&gt;The examples you will have access to illustrate each of the UI&lt;br&gt;
optimization methods I propose.&lt;/p&gt;

&lt;p&gt;Not only that, I analyzed them all so you can feel safe the information&lt;br&gt;
is accurate.&lt;/p&gt;

&lt;p&gt;Because... do you know what comes after speaking out of our gut&lt;br&gt;
feelings? Speaking with certainty, based on real experience.&lt;/p&gt;

&lt;p&gt;So, are you serious about becoming a &lt;em&gt;Level 3 Unity UI Developer&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/unity-ui/optimization-strategies/#level-3-guide"&gt;---&amp;gt; Grab Now the Level 3 Guide from my Blog Post&lt;/a&gt; .&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>csharp</category>
      <category>gamedev</category>
      <category>ui</category>
    </item>
    <item>
      <title>Unity Addressables: The Final Quiz Analysis</title>
      <dc:creator>The Gamedev Guru</dc:creator>
      <pubDate>Mon, 07 Oct 2019 20:48:48 +0000</pubDate>
      <link>https://dev.to/thegamedevguru/unity-addressables-the-final-quiz-analysis-45mj</link>
      <guid>https://dev.to/thegamedevguru/unity-addressables-the-final-quiz-analysis-45mj</guid>
      <description>&lt;p&gt;&lt;em&gt;This post on &lt;a href="https://thegamedev.guru/unity-addressables/quiz-analysis/"&gt;Unity Addressables Quiz&lt;/a&gt; was originally published with its original formatting in The Gamedev Guru's Blog&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Heya, Unity Addressables fan.&lt;/p&gt;

&lt;p&gt;Last week, I posted a short but powerful article detailing three &lt;a href="//thegamedev.guru/unity-addressables/benefits-for-your-game/"&gt;Unity Addressables benefits&lt;/a&gt; for your game. The article was very well received, thanks for your active participation.&lt;/p&gt;

&lt;p&gt;Just at the end of that post, you were given the chance to test your knowledge in Unity Addressables through a short quiz.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/10/Addressables-Quiz-Thumbnail.jpg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bC0MPK6h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/10/Addressables-Quiz-Thumbnail.jpg%26key%3D863c7d5ce99338c3d1e38754fee74eb0201fac32ddf9573e8329c20dec2c6c1a" alt="Addressables-Quiz-Thumbnail.jpg" title="Addressables-Quiz-Thumbnail" width="469" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The goal I had in mind when creating the quiz was to help you become aware of the areas you might be less familiar with, so you can get to develop your skills where you need the most.&lt;/p&gt;

&lt;p&gt;I'll confess that, initially, I didn't expect many people to go through the quiz. After all, quizzes can be daunting and, as usual, there's this extra babbling coming from me.&lt;/p&gt;

&lt;p&gt;But to my surprise, &lt;strong&gt;the quiz results well outperformed my expectations&lt;/strong&gt;. I'm really happy to see that so many people accepted the challenge. You all rock!&lt;/p&gt;

&lt;p&gt;I got some interesting statistics out of the quiz. Here are some figures I wanted to share with you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The greatest part of the people who started it, about 80%, actually were determined enough to finish it&lt;/li&gt;
&lt;li&gt;  The average score was about 12, which is pretty damn good for an API that was only introduced recently&lt;/li&gt;
&lt;li&gt;  5% of the quiz participants fell in the &lt;em&gt;Troll Guru&lt;/em&gt; rank&lt;/li&gt;
&lt;li&gt;  About 35% are part of the &lt;em&gt;Apprentice Guru&lt;/em&gt; group&lt;/li&gt;
&lt;li&gt;  45% of the participants scored enough to be &lt;em&gt;Enlightened Gurus&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  But only 5% made it to be considered &lt;em&gt;The Final Boss Guru&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, congratulations if you were part of the quiz experience!&lt;/p&gt;

&lt;p&gt;And independently from the score you got, I am sure it will not take you much effort to reach the production-level required score of 20+. I'll be helping you along the path.  &lt;/p&gt;

&lt;p&gt;In this post, I will explain the most interesting challenges posed in the quiz. Some answers might differ depending on your particular context, so make sure to comment at the end of the post if you had a complementary experience.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you didn't complete the quiz before, &lt;/strong&gt;&lt;a href="https://thegamedev.guru/unity-addressables/benefits-for-your-game/#end"&gt;&lt;strong&gt;do it now&lt;/strong&gt;&lt;/a&gt; before reading further.&lt;/p&gt;

&lt;p&gt;Do not cheat. I'll know.  &lt;/p&gt;

&lt;p&gt;What were your results? Are you a &lt;em&gt;Troll Guru&lt;/em&gt;, an &lt;em&gt;Apprentice Guru&lt;/em&gt;, an &lt;em&gt;Enlightened Guru _or _The Final Boss Guru&lt;/em&gt;? Share your results in the comments section.&lt;/p&gt;

&lt;p&gt;Trusting that you finished it, let's have a look at the questions and some of the answers. The format should be self-explanatory, but I admit I could have chosen less cheesy graphics for it— &lt;em&gt;yes, that's me&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/10/funny-review.jpg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FmjaibPo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/10/funny-review.jpg%26key%3D1a36672ad5778b8472992cc3a5b55513e23952643db5a82de9648bbc4cfcc458" alt="funny-review.jpg" title="funny-review" width="880" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Question 1: Intense Memory Pressure
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;An angry player leaves a 1-star review because your game uses too much memory. You...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/10/crying-smiley-transparent.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5QjahvFv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/10/crying-smiley-transparent.png%26key%3D2794a88555a767433fffb0617ff3e1001fd1bc189c13ddb86cdbb9b03d717079" alt="crying-smiley-transparent.png" title="crying-smiley-transparent" width="64" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt; Answer in public, telling the player to upgrade their device and then come back&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a popular answer somehow. As much as we might feel like answering this, chances are, we have been too busy (or lazy) to implement a proper architecture. Blaming players for playing with a brick-phone won't get us more sales, so a better strategy is to fix our mess.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_neutral.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HKWeTeci--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_neutral.png%26key%3D722181003ffaa74152470146344cd8e1d3ae10a97bca16d2c42b10bec8f9c2fb" alt="Smiley - Neutral" title="smiley_neutral" width="97" height="104"&gt;&lt;/a&gt;&lt;strong&gt; Switch to a more advanced texture compression method, e.g. ETC2 to ASTC&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is helpful and you should indeed switch to more advanced compression methods, where possible. But this solution will only take you so far. You'll get moderate gains in memory usage and texture quality, but they'll not be enough to cover your memory pressure issues.&lt;br&gt;&lt;br&gt;
 &lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_angry.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WqyXaiRZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_angry.png%26key%3Db1a6b402bd3466714e0b365a06ed53d4272fda64884a270e03fbf68310236131" alt="Smiley - Furious" title="smiley_angry" width="100" height="104"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt; Split your scenes into sub-scenes, so less content is loaded in memory&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In general, sub-scenes used to be a good solution. I've used them in the past with great success. However, if you are having bad reviews already, chances are it is too late to introduce such a massive change in the architecture of your game. Better to look somewhere else.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_happy.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d7nfvmQx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_happy.png%26key%3D8104742794ec66684f4a890acbf6af76d504b5a03b227b6fdd06faa9ba4b51b4" alt="smiley_happy.png" title="smiley_happy" width="99" height="104"&gt;&lt;/a&gt;&lt;strong&gt;Implement an asset lazy-loading mechanism through AssetReferences&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Over 75% of people agreed on this, that's great.&lt;/p&gt;

&lt;p&gt;AssetReferences are likely to give you the biggest gain for the buck. The migration to this workflow is usually straight-forward and much easier than the other alternatives.&lt;/p&gt;

&lt;p&gt;However, be aware that, in some cases, it might be hard to work around the asynchronous requirements of the Unity Addressables API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/10/laptop-coffee.jpg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xZBCmOhK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/10/laptop-coffee.jpg%26key%3Dc8d16cc3b6dba6b1378a58779ba272c5cd4cb6a16febebb15832026d70629052" alt="laptop-coffee.jpg" title="laptop-coffee" width="600" height="356"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Question 2: Endless Loading Times
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;You press the play button. By the time your in-game scene is loaded, your coffee is cold. You...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/10/crying-smiley-transparent.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5QjahvFv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/10/crying-smiley-transparent.png%26key%3D2794a88555a767433fffb0617ff3e1001fd1bc189c13ddb86cdbb9b03d717079" alt="crying-smiley-transparent.png" title="crying-smiley-transparent" width="64" height="64"&gt;&lt;/a&gt; &lt;strong&gt;Blame the artists and ask them to put every texture into atlases. Also, you buy a faster PC&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
10% of the subscribers chose this one. I love you guys.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_angry.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WqyXaiRZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_angry.png%26key%3Db1a6b402bd3466714e0b365a06ed53d4272fda64884a270e03fbf68310236131" alt="Smiley - Furious" title="smiley_angry" width="100" height="104"&gt;&lt;/a&gt;&lt;strong&gt;Reduce the texture size globally, so asset loading is much faster. You don't submit these meta file changes in your versioning system&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I've done this a few times recently. It works.&lt;/p&gt;

&lt;p&gt;However, the pay to price is high. Your versioning system might go nuts and your changelists will be full of garbage. This is indeed hard to manage, as if you ignore these temporal texture import settings modifications, the real changes will mostly go unnoticed and won't be submitted.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_neutral.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HKWeTeci--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_neutral.png%26key%3D722181003ffaa74152470146344cd8e1d3ae10a97bca16d2c42b10bec8f9c2fb" alt="Smiley - Neutral" title="smiley_neutral" width="97" height="104"&gt;&lt;/a&gt;&lt;strong&gt;Create custom scenes that contain just the functionality you are working on&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Creating sub-scenes for faster iterations might be a possibility for your game, but in my experience, they tend to be left unmaintained. With time, they break and one might spend more time fixing them than the gain you eventually had back then.&lt;/p&gt;

&lt;p&gt;Consider implementing sub-scenes only if you don't see these problems in your project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_happy.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d7nfvmQx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_happy.png%26key%3D8104742794ec66684f4a890acbf6af76d504b5a03b227b6fdd06faa9ba4b51b4" alt="smiley_happy.png" title="smiley_happy" width="99" height="104"&gt;&lt;/a&gt; &lt;strong&gt;Remove direct references and add indirect references instead, so only the required assets are loaded&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Indirect references for the winner.&lt;/p&gt;

&lt;p&gt;Direct references will implicitly ask Unity to load all their content as soon as the script holding them is instantiated. Indirect references, however, gives you full control over the when/how/what. That means, you can delay loading until you need it, if at all, saving you from unnecessary loading times and wasted memory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/10/Unity-Addressables-Play-Script-Mode.jpg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RBCuRbdp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/10/Unity-Addressables-Play-Script-Mode.jpg%26key%3Dd7248e1b2706284cc85d2f02a6ffde3224364b75aaa71db8ba5e38ba0b5d1212" alt="Unity-Addressables-Play-Script-Mode.jpg" title="Unity-Addressables-Play-Script-Mode" width="682" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Question 3: What Play Mode Script?
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;You are currently implementing materials for your new characters. You want to try Addressables, so in the Play Mode script section of Addressables, you select...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_neutral.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HKWeTeci--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_neutral.png%26key%3D722181003ffaa74152470146344cd8e1d3ae10a97bca16d2c42b10bec8f9c2fb" alt="Smiley - Neutral" title="smiley_neutral" width="97" height="104"&gt;&lt;/a&gt; &lt;strong&gt;Fast Mode: we want it always fast, after all&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a valid option, but fast mode does no validation at all of important aspects of development, such as asset dependencies and cross-references.&lt;/p&gt;

&lt;p&gt;If there are no substantial changes in the content you're working on, fast mode will be fine. Otherwise, we can do better.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_angry.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WqyXaiRZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_angry.png%26key%3Db1a6b402bd3466714e0b365a06ed53d4272fda64884a270e03fbf68310236131" alt="Smiley - Furious" title="smiley_angry" width="100" height="104"&gt;&lt;/a&gt; &lt;strong&gt;Packed Play Mode: yes! we want our characters to be packed&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No! The Packed play mode requires you packing the assets every time you do a change in your addressable asset contents, otherwise you'll end up loading the old versions.&lt;/p&gt;

&lt;p&gt;You don't want to be packing every time, it's a huge time sink.&lt;/p&gt;

&lt;p&gt;But you might consider packed play mode once you're done working with addressables content to gain faster iterations, as these assets will require minimum processing while being loaded.&lt;/p&gt;

&lt;p&gt;35% of the Guru Challengers chose this answer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_happy.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d7nfvmQx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_happy.png%26key%3D8104742794ec66684f4a890acbf6af76d504b5a03b227b6fdd06faa9ba4b51b4" alt="smiley_happy.png" title="smiley_happy" width="99" height="104"&gt;&lt;/a&gt; &lt;strong&gt;Virtual Mode: it sounds safer than fast mode&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Virtual Mode is the option I suggest you using while actively working on your addressable content.&lt;/p&gt;

&lt;p&gt;The virtual mode is fast enough to keep iteration times short and at the same time, it'll give you useful validation checks to avoid screwing it up and finding out the mess way too late.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@6.7/manual/Images/UpgradingToHDRP2.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SOPFuCcF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition%406.7/manual/Images/UpgradingToHDRP2.png%26key%3D1375eef55237efcd3ab752c8fff5213a3ddf8ae9d2043fa36fc607ffa0d42036" alt="Pink shader" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Question 4: Oops... Error Diagnosing
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;You try Addressables but you don't recall your assets looking pink in your Android device. How weird! You...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_neutral.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HKWeTeci--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_neutral.png%26key%3D722181003ffaa74152470146344cd8e1d3ae10a97bca16d2c42b10bec8f9c2fb" alt="Smiley - Neutral" title="smiley_neutral" width="97" height="104"&gt;&lt;/a&gt; &lt;strong&gt;Enable the ADDRESSABLES_LOG_ALL symbol, make a development build and check the logcat logs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you came to me with such a description, I wouldn't necessarily take you down this road directly.&lt;/p&gt;

&lt;p&gt;The main issue with adding scripting defines and checking the logs on the device is the time it takes to prepare such a build, deploy it, test it and gather useful information from the logs.&lt;/p&gt;

&lt;p&gt;There are indeed better ways to tackle this, but certainly keep this as a backup option if they fail to give you an accurate diagnosis of the problem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_happy.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d7nfvmQx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_happy.png%26key%3D8104742794ec66684f4a890acbf6af76d504b5a03b227b6fdd06faa9ba4b51b4" alt="smiley_happy.png" title="smiley_happy" width="99" height="104"&gt;&lt;/a&gt;&lt;strong&gt;Set the play mode script to Packed Play Mode and run it in the editor to further diagnose the issue with the Addressable Profiler&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Emulating as much as you can the environment in which the content will be displayed is my preferred option, as it takes the least total amount of time. You do this by selecting the packed play mode in the main Addressables Window settings. The Unity Editor will load the addressable resources directly from the built content, so this is expected to give you a similar behavior than on the device, as long as the editor can load such a content.&lt;/p&gt;

&lt;p&gt;You can also try running it in virtual play mode, which does some validation on top of the traditional asset loading pipeline for addressables.&lt;/p&gt;

&lt;p&gt;Don't forget to count on the Addressable Profiler's help, a tool that will inform you about the addressable operations that are taking place at all times in your game.&lt;/p&gt;

&lt;p&gt;This answer was correctly chosen by 66% of the participants.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/10/crying-smiley-transparent.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5QjahvFv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/10/crying-smiley-transparent.png%26key%3D2794a88555a767433fffb0617ff3e1001fd1bc189c13ddb86cdbb9b03d717079" alt="crying-smiley-transparent.png" title="crying-smiley-transparent" width="64" height="64"&gt;&lt;/a&gt; &lt;strong&gt;Post in StackOverflow and Unity Answers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;12% of you see value in posting questions on these platforms, as there are always people willing to help. But preparing a reproduction project, posting and refreshing your screen with F5 is likely to take you much longer than just diagnosing and fixing the problem yourself. Trust me, this should be your last resort.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/10/Unity-NSFW.jpg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h5z3Y8Hg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/10/Unity-NSFW.jpg%26key%3Dc523537232d1d78837a9d591396ab67a5aa0099f57b64864cfcf4970ab2087d2" alt="Unity-NSFW.jpg" title="Unity-NSFW" width="300" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Question 5: Heavy Video Packing
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;You want your mp4 trailer video to be included in your game. You...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_neutral.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HKWeTeci--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_neutral.png%26key%3D722181003ffaa74152470146344cd8e1d3ae10a97bca16d2c42b10bec8f9c2fb" alt="Smiley - Neutral" title="smiley_neutral" width="97" height="104"&gt;&lt;/a&gt; &lt;strong&gt;Toss it into the StreamingAssets folder&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The StreamingAssets directory works just fine, especially when coupled with famous video plugins you find in the store. The assets stored in that directory are not packed together like Resources do but rather left as individual files when your game is installed. Its simplicity and easy I/O is the reason it is the default method of playing video.&lt;/p&gt;

&lt;p&gt;The biggest con is that the assets stored in StreamingAssets are forcefully packed in your distributed game from the beginning, so they are likely to take a lot of space in your build.&lt;/p&gt;

&lt;p&gt;Why would your users have to wait 5 minutes longer just to download the credits video that will be played at the end of a 30+ hours game?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_angry.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WqyXaiRZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_angry.png%26key%3Db1a6b402bd3466714e0b365a06ed53d4272fda64884a270e03fbf68310236131" alt="Smiley - Furious" title="smiley_angry" width="100" height="104"&gt;&lt;/a&gt; &lt;strong&gt;Mark it as Addressable, add a "videos" label to it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sure, making it addressable sounds cool. But adding a "videos" label to it?&lt;/p&gt;

&lt;p&gt;Usually, labels are used to download &lt;strong&gt;all &lt;/strong&gt;assets belonging to that label category at once. Unless you have a very specific use case, doing this is not likely to help your project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_happy.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d7nfvmQx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_happy.png%26key%3D8104742794ec66684f4a890acbf6af76d504b5a03b227b6fdd06faa9ba4b51b4" alt="smiley_happy.png" title="smiley_happy" width="99" height="104"&gt;&lt;/a&gt; &lt;strong&gt;Mark it as Addressable, adding it to a "videos" group with the following attributes: static content, no compression&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Videos are not likely to change, so making them static makes sense. Also, there's no need to compress them, as the used video codec should already offer you compression. Adding LZ4 or LZMA compression on top of this already-compressed content will only incur in CPU overhead. Your users' battery will drain faster as well. I'm sure your players wouldn't appreciate it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_neutral.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HKWeTeci--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_neutral.png%26key%3D722181003ffaa74152470146344cd8e1d3ae10a97bca16d2c42b10bec8f9c2fb" alt="Smiley - Neutral" title="smiley_neutral" width="97" height="104"&gt;&lt;/a&gt; &lt;strong&gt;Mark it as Addressable, adding it to a "videos" group with the following attributes: dynamic content, LZMA compression&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dynamic, compressed content is by far the most commonly chosen answer. But it is a misleading one.&lt;/p&gt;

&lt;p&gt;For the reasons stated above, you should avoid using compression on already compressed content. And videos are often enough very static, so by marking that group dynamic you wouldn't be helping your asset building workflows.&lt;/p&gt;

&lt;p&gt;Most people (46%) thought this was to best option.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/10/Unity-Addressables-LoadAssetAsync.jpg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tpLOw8cK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/10/Unity-Addressables-LoadAssetAsync.jpg%26key%3Dd3c36712dbb98dae45a45ef2797e7b4d2eb380acc8219965f05ffdd4e76876fc" alt="Unity-Addressables-LoadAssetAsync.jpg" title="Unity-Addressables-LoadAssetAsync" width="527" height="42"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Question 6: Memory on Instance Releasing
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;You loaded your asset once through LoadAssetAsync. Now you're done with it, so you...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_angry.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WqyXaiRZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_angry.png%26key%3Db1a6b402bd3466714e0b365a06ed53d4272fda64884a270e03fbf68310236131" alt="Smiley - Furious" title="smiley_angry" width="100" height="104"&gt;&lt;/a&gt; &lt;strong&gt;Call Addressables.Release, so the memory is immediately released&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There's no guarantee that the memory will be freed right away, as the current &lt;a href="https://docs.unity3d.com/Packages/com.unity.addressables@1.2/manual/MemoryManagement.html"&gt;documentation&lt;/a&gt; correctly points out. But do not worry about it too much, it will be correctly freed by Unity. 23% popular.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/10/crying-smiley-transparent.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5QjahvFv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/10/crying-smiley-transparent.png%26key%3D2794a88555a767433fffb0617ff3e1001fd1bc189c13ddb86cdbb9b03d717079" alt="crying-smiley-transparent.png" title="crying-smiley-transparent" width="64" height="64"&gt;&lt;/a&gt; &lt;strong&gt;Call Destroy, we better make sure we free that memory up&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Addressables is, as of now, unaware of traditional Unity instantiation and destroy mechanisms. If you do so by yourself, you are doing it at your own risk and bookkeeping. If you mess it up, the API and OS are unlikely to be happy about it. And you will know.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_happy.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d7nfvmQx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_happy.png%26key%3D8104742794ec66684f4a890acbf6af76d504b5a03b227b6fdd06faa9ba4b51b4" alt="smiley_happy.png" title="smiley_happy" width="99" height="104"&gt;&lt;/a&gt; &lt;strong&gt;Call Addressables.Release, so the memory is released at some point in the future&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The documentation implies that the memory occupied by addressable assets will be freed at some point in the future after calling the Unity addressables release method.&lt;/p&gt;

&lt;p&gt;You can count on Unity smartly deciding when it is time to do just so (e.g. low memory situations, Resources.UnloadAllUnusedAssets, etc.). You guys got this one right!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/10/Unity-Addressables-LoadAssetAsync-Yield.jpg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jZBYLKFV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/10/Unity-Addressables-LoadAssetAsync-Yield.jpg%26key%3Db6ff0faebbef9b6b978d73f47dae97e826d71bc90e4c591f6ab5c29d0d5a0cc6" alt="Unity-Addressables-LoadAssetAsync-Yield." title="Unity-Addressables-LoadAssetAsync-Yield" width="525" height="36"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Question 7: Loading with LoadAssetAsync
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;You're excited about doing your first Addressables.LoadAssetAsync. So you call it and use its returned handle like...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_angry.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WqyXaiRZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_angry.png%26key%3Db1a6b402bd3466714e0b365a06ed53d4272fda64884a270e03fbf68310236131" alt="Smiley - Furious" title="smiley_angry" width="100" height="104"&gt;&lt;/a&gt; &lt;strong&gt;while (handle.Status == AsyncOperationStatus.Succeeded) ;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I confess to you that I've tried this method to try to force a synchronous behavior out of the Addressables API (e.g. Photon Networking under Unity Addressables).&lt;/p&gt;

&lt;p&gt;But you can guess what happened after seeing the answer's smiley. My computer's fan started spinning insanely fast and I had to reboot the computer as the OS became utterly unresponsive. I'm not trying this again any time soon, thanks.&lt;/p&gt;

&lt;p&gt;Doing this loop is likely to cause a deadlock, as part of the loading process is executed in Unity's main thread. And that line of code is the easiest way to block your main thread.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_happy.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d7nfvmQx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_happy.png%26key%3D8104742794ec66684f4a890acbf6af76d504b5a03b227b6fdd06faa9ba4b51b4" alt="smiley_happy.png" title="smiley_happy" width="99" height="104"&gt;&lt;/a&gt; &lt;strong&gt;await handle.Task;&lt;/strong&gt; or &lt;strong&gt;yield return handle;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These two solutions are asynchronous ways of waiting for the loading process to finish before continuing with our code. That's great stuff for you and me, as they offer great readability and are easy to maintain.&lt;/p&gt;

&lt;p&gt;However, be aware they incur on some performance penalty.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_happy.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d7nfvmQx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_happy.png%26key%3D8104742794ec66684f4a890acbf6af76d504b5a03b227b6fdd06faa9ba4b51b4" alt="smiley_happy.png" title="smiley_happy" width="99" height="104"&gt;&lt;/a&gt; &lt;strong&gt;handle.Completed += OnLoadCompleted;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the simplest and yet most powerful option to do something after the asset has been loaded into memory.&lt;/p&gt;

&lt;p&gt;Keep in mind, though, that you're introducing lambdas and/or callbacks. They will reduce the readability of your code and therefore make your programming style more dangerous. Unless you are a pro, of course.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/10/The-Gamedev-Guru-Recycle-Bin.jpg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YWnEJFaS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/10/The-Gamedev-Guru-Recycle-Bin.jpg%26key%3Dcd5c79cbd436f52aaca283f41c08e9a4aacec82a2b38afcbb3424d1526b4a4fa" alt="The-Gamedev-Guru-Recycle-Bin.jpg" title="The-Gamedev-Guru-Recycle-Bin" width="666" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Question 8: Migrating to Better Workflows
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;You have a bunch of skyboxes living as direct references in your Skybox manager as a list of materials. Those are eating all your memory, so you...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_angry.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WqyXaiRZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_angry.png%26key%3Db1a6b402bd3466714e0b365a06ed53d4272fda64884a270e03fbf68310236131" alt="Smiley - Furious" title="smiley_angry" width="100" height="104"&gt;&lt;/a&gt; &lt;strong&gt;Move them into the Resources folder and start using Resources.Load as you need them&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No! Bad boy!&lt;/p&gt;

&lt;p&gt;Don't ever use the Resources directory for heavy assets. They are a major cause of pain, tears and  burnouts in large scale projects. It is indeed surprisingly easy to misuse the Resources API. Read more info on why it is so &lt;a href="https://learn.unity.com/tutorial/assets-resources-and-assetbundles"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_neutral.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HKWeTeci--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_neutral.png%26key%3D722181003ffaa74152470146344cd8e1d3ae10a97bca16d2c42b10bec8f9c2fb" alt="Smiley - Neutral" title="smiley_neutral" width="97" height="104"&gt;&lt;/a&gt; &lt;strong&gt;Put all skyboxes in an asset bundle that you will load appropriately&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Asset bundles were a much-needed solution back then. But we have better solutions now with Unity Addressables.&lt;/p&gt;

&lt;p&gt;The issue is that working with asset bundles is way more tedious and expensive to implement and maintain than just using Unity Addressables. Unless you're doing a port and you don't want to touch much of the original systems, try to avoid them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_happy.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d7nfvmQx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_happy.png%26key%3D8104742794ec66684f4a890acbf6af76d504b5a03b227b6fdd06faa9ba4b51b4" alt="smiley_happy.png" title="smiley_happy" width="99" height="104"&gt;&lt;/a&gt; &lt;strong&gt;Replace the list of skybox materials with a list of AssetReference's and load them as you need&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Using Unity Addressables is probably the best option to tackle this kind of memory issues.&lt;/p&gt;

&lt;p&gt;One of the reasons it is such a silver bullet is because you can easily migrate from the most popular approaches of managing content such as direct references, resources API, additive scenes and asset bundles.&lt;/p&gt;

&lt;p&gt;Unity Addressables are a simpler way to develop more efficient games.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/wp-content/uploads/2019/09/smiley_neutral.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HKWeTeci--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/smiley_neutral.png%26key%3D722181003ffaa74152470146344cd8e1d3ae10a97bca16d2c42b10bec8f9c2fb" alt="Smiley - Neutral" title="smiley_neutral" width="97" height="104"&gt;&lt;/a&gt; &lt;strong&gt;Decrease the skybox texture sizes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tweaking the texture import settings works up to a point. This has an upper ceiling limit, as you cannot infinitely go lower in memory usage (and quality) without re-categorizing your 3d game into pixel-art. This just doesn't scale well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/unity-addressables-quiz-analysis/"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QmE2AtO5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gamedev.net/applications/core/interface/imageproxy/imageproxy.php%3Fimg%3Dhttps://thegamedev.guru/wp-content/uploads/2019/09/the-gamedev-guru-logo-full-transparent.png%26key%3Db99e9ff10a0cf3fcf522a99da59b87a6b3b23bd6b78cb00a38c006c5b9b35488" alt="the-gamedev-guru-logo-full-transparent.png" width="880" height="82"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Chances are very high that you didn't reach the rank of The Final Boss Guru.&lt;/p&gt;

&lt;p&gt;But that's good, because that means &lt;strong&gt;there's massive room for improving and optimizing the way you develop and ship games&lt;/strong&gt;. And what is more important, your players will appreciate the expertise you build in each of these areas. The only place you want to read 1-star reviews is at the app store of your competitor's game.&lt;/p&gt;

&lt;p&gt;Given the importance of delivering enjoyable experiences to your players, I will share something with you.&lt;/p&gt;

&lt;p&gt;Between you and me: I have a work-in-progress plan for maximizing the potential of your game with Addressables. &lt;strong&gt;In the upcoming weeks, I will be revealing to you more information about the Unity Addressables level-up program I'm developing. That program is going to get you to the production level you need to deliver the games people will deeply enjoy (purchasing and) playing.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To make sure you don't miss on the upcoming content, subscribe now to the newsletter. I'll keep you posted.&lt;/p&gt;

&lt;p&gt;Till then, &lt;strong&gt;comment below on what you would like to learn the most&lt;/strong&gt; and also how you plan to use Unity Addressables in your project.&lt;/p&gt;

&lt;p&gt;See you soon on the &lt;a href="https://thegamedev.guru/unity-addressables/quiz-analysis/"&gt;blog&lt;/a&gt;!&lt;br&gt;&lt;br&gt;
Rubén&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>csharp</category>
    </item>
    <item>
      <title>3 Ways Unity Addressables Will Save Your Game</title>
      <dc:creator>The Gamedev Guru</dc:creator>
      <pubDate>Sun, 29 Sep 2019 14:10:11 +0000</pubDate>
      <link>https://dev.to/thegamedevguru/3-ways-unity-addressables-will-save-your-game-1pak</link>
      <guid>https://dev.to/thegamedevguru/3-ways-unity-addressables-will-save-your-game-1pak</guid>
      <description>&lt;p&gt;&lt;em&gt;[This post on &lt;a href="https://thegamedev.guru/unity-addressables/benefits-for-your-game/"&gt;Unity Addressables Benefits&lt;/a&gt; was originally posted with its original formatting at The Gamedev Guru's Blog]&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you've been following me, you will probably know my interest in Unity Addressables. That is for a reason.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hFP6Dc-O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/3-Ways-Addressables-Will-Save-Your-Game-Thumbnail.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hFP6Dc-O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/3-Ways-Addressables-Will-Save-Your-Game-Thumbnail.jpg" alt="Thumbnail" width="469" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unity Addressables is a powerful Unity package that upgrades the way you and I have been tackling some of the most important challenges in Game Development: &lt;strong&gt;efficient, pain-free content management&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When managing your game assets, it's hard to keep good standards that prevent our project from becoming a disgusting pile of mess. A big issue there is the coupling between the different responsibilities of our asset management systems.&lt;/p&gt;

&lt;p&gt;The way we store the assets in our project has way too much to do with the method we load them, and later use them.&lt;/p&gt;

&lt;p&gt;For instance, you may decide to store an innocent sprite in the Resources folder. This, in turn, will force Unity to build the player in a way that that sprite is put into special archive files. And the fact that it was put there, will corner you into loading it through the Resources API.&lt;/p&gt;

&lt;p&gt;Things get messy quicker than you can realize!&lt;/p&gt;

&lt;p&gt;One choice, multiple long-term consequences.&lt;/p&gt;

&lt;p&gt;A good system will prevent you and me from easily making sloppy mistakes like that. A great system will be that, and also easy to learn and use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With Unity Addressables, we separate the asset management concerns&lt;/strong&gt;. Our goal is to remain flexible and to keep our project maintainable.&lt;/p&gt;

&lt;p&gt;Here are 3 proven ways Unity Addressables will help you and your games:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---fSzo4xo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/RAM.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---fSzo4xo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/RAM.jpg" alt="Thumbnail" width="800" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Reduce Your Game's Memory Pressure
&lt;/h1&gt;

&lt;p&gt;When you publish your game, you'll be required on most platforms to specify the minimum hardware specifications your players must meet to buy and play your game.&lt;/p&gt;

&lt;p&gt;The math is easy here: &lt;strong&gt;the more hardware power you demand, the fewer will buy your game&lt;/strong&gt;. Or, seen from another perspective, the better memory management you do, the higher the amount of content and fun you can offer in your game.&lt;/p&gt;

&lt;p&gt;Unity Addressables helps you in this regard enormously!&lt;/p&gt;

&lt;p&gt;To give you a brief idea, converting this kind of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class CharacterCustomization : MonoBehaviour
{
    [SerializeField] private List&amp;lt;Material&amp;gt; _armorVariations;
    [SerializeField] private MeshRenderer _armorRenderer;

    public void ChangeArmorVariation(int variationId)
    {
        _armorRenderer.material = _armorVariations[variationId];
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Into this other one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using UnityEngine.AddressableAssets;

public class CharacterCustomizationV2 : MonoBehaviour
{
    [SerializeField] private List&amp;lt;AssetReference&amp;gt; _armorVariations;
    [SerializeField] private MeshRenderer _armorRenderer;

    public IEnumerator ChangeArmorVariation(int variationId)
    {
        var loadProcess = _armorVariations[variationId].LoadAssetAsync();
        yield return loadProcess;
        _armorRenderer.material = loadProcess.Result;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Will bring you these results:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wuajkKeU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Unity-Addressables-Memory-Gain.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wuajkKeU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Unity-Addressables-Memory-Gain.jpg" alt="Results" width="474" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Easy gains I'd say.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/unity-addressables/tutorial-learn-the-basics/"&gt;-&amp;gt; Read more on Unity Addressables for better memory management in Unity Addressables: It's Never Too Big to Fit&lt;/a&gt; (opens in a new tab)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hYCrG7lx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Controller.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hYCrG7lx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Controller.jpg" alt="Controller" width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Sell Your Next DLC - Quick and Easy
&lt;/h1&gt;

&lt;p&gt;The fact that &lt;strong&gt;Addessables gives you full control over how, when and where to store and load your game assets&lt;/strong&gt; is incredibly useful for implementing and selling Downloadable Content.&lt;/p&gt;

&lt;p&gt;Even if you are not thinking of releasing DLCs any time soon, just by using Unity Addressables in your project, you will have done already a big chunk of the work ahead.&lt;/p&gt;

&lt;p&gt;Other approaches for selling DLCs, such as Asset Bundles, are a very deprecated way of doing the same thing but at a much higher cost. Maintaining a well-functioning Asset Bundle pipeline is painfully time-consuming and requires a high degree of expensive expertise.&lt;/p&gt;

&lt;p&gt;There are many ways you can approach implementing DLCs in Unity, but for starters, this is a good starting point:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class DlcManager : MonoBehaviour
{
    // ...
    public IEnumerator TryDownloadDlc()
    {
        if (_hasBoughtDlc &amp;amp;&amp;amp; _dlcDownloaded == false)
        {
            var operationHandle = Addressables.DownloadDependenciesAsync("DLC-Content");
            while (operationHandle.IsDone == false)
            {
                _progressText.text = $"{operationHandle.PercentComplete * 100.0f} %";
                yield return operationHandle;
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get the idea.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why would you say no to selling more entertainment for your players at a fraction of the cost?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--px9uctvJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Time.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--px9uctvJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Time.jpg" alt="Iteration times" width="880" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Reduce Your Iteration Times
&lt;/h1&gt;

&lt;p&gt;Using Unity Addressables will reduce the time wasted waiting in several areas.&lt;/p&gt;

&lt;p&gt;Tell me, how frustrating is it to be blocked for half a minute after pressing the Unity play button? And it only gets worse if you deploy your build on another platform, such as mobile or WebGL. This all starts adding minutes and minutes to your iteration times. It gets old so quickly.&lt;/p&gt;

&lt;p&gt;I don't like waiting either.&lt;/p&gt;

&lt;p&gt;But do you know what I like? Unity Addressables, my long-awaited hero. This is how Addressables will help you:&lt;/p&gt;

&lt;h2&gt;
  
  
  A) Reduced Build Size
&lt;/h2&gt;

&lt;p&gt;Your game has a lot of content, I get it. Gamers love enjoying content. Developers love creating content.&lt;/p&gt;

&lt;p&gt;That doesn't mean, however, that every single asset you produced has to be included in the build your players will install. In fact, you should remove as much as possible.&lt;/p&gt;

&lt;p&gt;Players want to start playing ASAP. And they're not happy when your game steals 2GB of their data plan and 30 minutes of their gaming time. They'll just keep downloading Candy Crush kind of games that install well under 50MB.&lt;/p&gt;

&lt;p&gt;One strategy is to include only the assets needed to run your game up to the main menu. Then, you can progressively download the rest of your content in the background, starting of course downloading the first level of your game.&lt;/p&gt;

&lt;p&gt;It's also neat to realize that &lt;strong&gt;your deployment times during development will sink&lt;/strong&gt;. You'll be able to iterate more times each day; this benefit quickly adds up in the long term.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yLNOljTf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Unity-Addressables-Build-Size.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yLNOljTf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Unity-Addressables-Build-Size.jpg" alt="Addressables - Reduced Build Sizes" width="447" height="615"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  B) Reduced Load Times
&lt;/h2&gt;

&lt;p&gt;We, both as game developers and as players, hate waiting. Waiting takes us out of the zone and before you realize it, it is time to go to bed.&lt;/p&gt;

&lt;p&gt;Unity is working hard towards reducing the time it takes us to start playing our games, both in the Unity Editor and in the games we distribute.&lt;/p&gt;

&lt;p&gt;But not hard enough.&lt;/p&gt;

&lt;p&gt;Things look promising in the future, but not without side effects. Avoiding domain reloads in Unity 2019.3 looks promising, but as of today that's still in beta and not everyone can profit from it.&lt;/p&gt;

&lt;p&gt;In the mean-time, we can do better than just being frustrated.&lt;/p&gt;

&lt;p&gt;Let's say you're working on a medieval game. Several months ago, you implemented armor types for your game. You did a pretty damn good job and generated over 100MB of content.&lt;/p&gt;

&lt;p&gt;At some point, it was time to move on and right now you're working on something else, let's say sword fighting.&lt;/p&gt;

&lt;p&gt;Realize that, &lt;strong&gt;every time you press the play button to work on your features, you are loading an insane amount of data coming from all the already developed features, and loading this data takes a massive amount of time&lt;/strong&gt;. You press play to test your sword fighting animations, and you spend 5 seconds waiting due to loading the armor features you implemented.&lt;/p&gt;

&lt;p&gt;The time wasted in loading is mostly spent on I/O (Input/Output), because memory bandwidth is expensive. And, on top of that, your CPU has to process it. You, as a developer, pay this time penalty while developing in the Unity Editor. But your players pay it as well in the games you are distributing.&lt;/p&gt;

&lt;p&gt;Knowing how big of a deal this can be, let's ask ourselves: which shortcuts can we take here?&lt;/p&gt;

&lt;p&gt;It turns out that Unity Addressables can help us here in two ways.&lt;/p&gt;

&lt;h3&gt;
  
  
  Addressables will reduce your Players' Loading Times
&lt;/h3&gt;

&lt;p&gt;We can alleviate some of our players' pain.&lt;/p&gt;

&lt;p&gt;Keeping indirect references to our assets instead of direct references will drastically improve your loading times.&lt;/p&gt;

&lt;p&gt;By using indirect references (AssetReference), Unity will not load everything at once but only what you tell it to. And more importantly, you have direct control over when that happens.&lt;/p&gt;

&lt;h3&gt;
  
  
  Addressables will reduce your Unity Editor Iteration Times
&lt;/h3&gt;

&lt;p&gt;How much do you know about the play mode script in the Unity Addressables Window? The play mode script defines how the Unity Editor should load the content marked as Addressable.&lt;/p&gt;

&lt;p&gt;With Packed Play Mode selected, Unity will directly load your pre-built addressable assets with little to no processing overhead, effectively reducing your Unity Editor iteration times&lt;/p&gt;

&lt;p&gt;Just do not forget to build the player content for this to work&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cY8f01xn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/08/addressables-build-player-content.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cY8f01xn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/08/addressables-build-player-content.png" alt="Addressables - Build Player Content" width="880" height="187"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What if you applied these strategies to your most demanding content?&lt;/p&gt;

&lt;h1&gt;
  
  
  4. Extra: Are You There Yet?
&lt;/h1&gt;

&lt;p&gt;It is true. Unity Addressables is very helpful. But this package will help only those who want to be helped.&lt;/p&gt;

&lt;p&gt;After reading how Addressables will help you producing better and selling more to your players, you probably want to start with it right away. However, starting in this new unknown area may be challenging.&lt;/p&gt;

&lt;p&gt;To make the most of your chance, answer these questions first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where are you standing right now? Are you just starting, or are your skills production-ready?&lt;/li&gt;
&lt;li&gt;When to use indirect references, when to use direct references?&lt;/li&gt;
&lt;li&gt;What's the bigger picture?&lt;/li&gt;
&lt;li&gt;What is your next logical step?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--d2P9u0AM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/unity-addressables/benefits-for-your-game/%23end" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d2P9u0AM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/unity-addressables/benefits-for-your-game/%23end" alt="Foo" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegamedev.guru/unity-addressables/benefits-for-your-game/#end"&gt;→ Take this short quiz now to test your answers ←&lt;/a&gt;&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Unity Immediate and the Art of Automating Playthroughs</title>
      <dc:creator>The Gamedev Guru</dc:creator>
      <pubDate>Tue, 17 Sep 2019 17:50:26 +0000</pubDate>
      <link>https://dev.to/thegamedevguru/unity-immediate-and-the-art-of-automating-playthroughs-3jc</link>
      <guid>https://dev.to/thegamedevguru/unity-immediate-and-the-art-of-automating-playthroughs-3jc</guid>
      <description>&lt;p&gt;If you love developing hard games but aren't a good player yourself, you have a challenge ahead.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9V3ysVSl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Unity-Immediate-Window-Project.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9V3ysVSl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Unity-Immediate-Window-Project.jpg" alt="Unity Immediate Window: Sample Project" width="594" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last week, while working on a game, I noticed that I could not beat my own levels anymore. I wanted to reach the final boss, so to speak, and that single thingy took me longer than I'd be happy to admit. It might be the age, or that the game is simply too hard.&lt;/p&gt;

&lt;p&gt;So I started looking for different ways to save time. As always, cheating was an option. I also thought of making a special, shorter version of my gameplay to avoid playing through the same hard spots every single time. After all, I just wanted to test the final boss!&lt;/p&gt;

&lt;p&gt;As you know, there are many ways of approaching this. But, in my case, &lt;em&gt;I came up with an alternative approach that ended up being surprisingly useful&lt;/em&gt;. This strategy helped me shortening the testing times of my games plus cutting the design iteration times.&lt;/p&gt;

&lt;p&gt;If you are a programmer or designer, this article will give you insight into a second approach for handling these challenges. If you have any other role, well, share this article with the right person.&lt;/p&gt;

&lt;p&gt;To present the use case, I looked for an open-source game on GitHub. And so I found a cute little game called Popcorn that I borrowed from TheAislan (full credits to him!). It's a basic 2d platform game that features simple 2d physics mechanics, perfect for our use case. Check the screenshot above, isn't it adorable?&lt;/p&gt;

&lt;p&gt;I'll start off by telling you how I used to deal with testing...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Sb6T9ACO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Unity-Immediate-Window-Level1-Grinding.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Sb6T9ACO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thegamedev.guru/wp-content/uploads/2019/09/Unity-Immediate-Window-Level1-Grinding.jpg" alt="Unity Immediate Window: Sample Project" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Level 1 Unity Developer: The Grind
&lt;/h1&gt;

&lt;p&gt;A decade ago, grinding was my preferred way of working (oh dear). All the testing  I did was manual, and it was all fun.&lt;/p&gt;

&lt;p&gt;Then, &lt;em&gt;weeks passed and the game got more and more complex&lt;/em&gt;. I started growing frustrated, since now playing every time took me almost 20 minutes. Tweaking the final boss scene transformed from being a pleasant moment to sucking all my mana and burning the entire QA's yearly budget.&lt;/p&gt;

&lt;p&gt;Something had to be done, and so I searched for solutions.&lt;/p&gt;

&lt;p&gt;One workaround was to &lt;em&gt;split each level in multiple, even finer sub-levels&lt;/em&gt;. That way, we could just load the specific sub-level we want to test. This solution might work well for games whose level areas are highly independent of each other, such as platform games. This has some overhead on the programmer when it comes to scene management, but it's quite alright.&lt;/p&gt;

&lt;p&gt;Another possibility is to add custom &lt;em&gt;in-game panels or UI inspectors to enabling cheating&lt;/em&gt; and special actions. Those could allow the developer to skip certain parts, increase stats or just disable annoying ads. These work just well, but some time has to be spent on preparing and maintaining the front-end.&lt;/p&gt;

&lt;p&gt;And here comes the classic: a &lt;em&gt;configuration file&lt;/em&gt; to be loaded in run-time. That sneaky file can be used to choose which features or cheats to enable. That may look like below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "GodMode": true,
  "AllLevelsUnlocked": true,
  "Gold": 500,
  "SkipAds": true,
  "UnlimitedTime": true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can load such a configuration file through a C# script like below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Serializable]
public class Cheats
{
    public bool GodMode;
    public bool AllLevelsUnlocked;
    public int Gold;
    public bool UnlimitedTime;
}
var cheats = JsonUtility.FromJson(File.ReadAllText(Path.Combine(Application.persistentDataPath, "cheats.txt")));
player.Gold = cheats.Gold;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, make sure not to enable that feature in release versions 😉&lt;/p&gt;

&lt;p&gt;These options have one common problem: &lt;em&gt;we have to pre-define what is possible in advance&lt;/em&gt;. We get what we programmed; we don't get what we didn't.&lt;/p&gt;

&lt;p&gt;That can quickly become a time sink:&lt;/p&gt;

&lt;p&gt;During testing, we decide we need X. Therefore, we stop playing and wait for a programmer to implement X.&lt;br&gt;
We then replay till that point and perform X, only to realize we actually wanted to do Y.&lt;/p&gt;

&lt;p&gt;In some situations, we could clearly profit from having more flexibility.&lt;/p&gt;

&lt;p&gt;So I asked myself: can we do better?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...Continue reading the article at &lt;a href="https://thegamedev.guru/unity-immediate-for-automated-playthroughs/"&gt;TheGamedev.Guru&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>unity3d</category>
    </item>
  </channel>
</rss>
