<?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>Forem: Rahul Barate</title>
    <description>The latest articles on Forem by Rahul Barate (@rahul_barate_e965377330fe).</description>
    <link>https://forem.com/rahul_barate_e965377330fe</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%2F3465775%2F966606fa-16b4-4b7f-9aac-82b6f9c6924e.jpg</url>
      <title>Forem: Rahul Barate</title>
      <link>https://forem.com/rahul_barate_e965377330fe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rahul_barate_e965377330fe"/>
    <language>en</language>
    <item>
      <title>🐞Bug Resistant Development: Fail Fast – Part 3 (Compile Time Safety)</title>
      <dc:creator>Rahul Barate</dc:creator>
      <pubDate>Thu, 12 Mar 2026 16:19:54 +0000</pubDate>
      <link>https://forem.com/rahul_barate_e965377330fe/bug-resistant-development-fail-fast-part-3-compile-time-safety-52n7</link>
      <guid>https://forem.com/rahul_barate_e965377330fe/bug-resistant-development-fail-fast-part-3-compile-time-safety-52n7</guid>
      <description>&lt;p&gt;In the last blog we talked about Data Validation attributes like Min, Range, etc. These attributes help us Fail Fast. Fail Fast means detecting problems early rather than when the game is running.&lt;/p&gt;

&lt;p&gt;In this blog we’ll talk about &lt;strong&gt;compile-time safety measures&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤔What are Compile-Time Safety Measures?
&lt;/h2&gt;

&lt;p&gt;Compile-time safety measures are simple tips and techniques that help catch errors during compilation, instead of Unity throwing them at you at runtime.&lt;/p&gt;

&lt;p&gt;The earlier an error appears, the easier it is to fix.&lt;/p&gt;

&lt;p&gt;Let’s look at some techniques I personally use.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✏️1. Enums &amp;gt; Strings
&lt;/h2&gt;

&lt;p&gt;Now, what does this mean?&lt;/p&gt;

&lt;p&gt;In your journey as a Game Developer you must have come across this scenario. Let’s say you have a state system that uses strings like &lt;code&gt;"GameOver"&lt;/code&gt;, &lt;code&gt;"GameWon"&lt;/code&gt;, etc. to set or get different states of the game.&lt;br&gt;
Once the game is over you want to display a UI to restart the game, and you wrote the logic something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"GamesOver"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="n"&gt;gameOverUI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetActive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if you have a keen eye then you might have noticed what’s wrong. If you didn’t, then you must have pulled your hair debugging this type of bug.&lt;/p&gt;

&lt;p&gt;Just know that a simple spelling mistake might cost you hours of debugging.&lt;/p&gt;

&lt;p&gt;But I have a solution — Enums.&lt;/p&gt;

&lt;p&gt;Enum is a value type similar to &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;float&lt;/code&gt;, etc. Enum allows us to define named constants that hold numerical values behind the scenes.&lt;/p&gt;

&lt;p&gt;If you are not familiar with enum then check out the official documentation for more details.&lt;/p&gt;

&lt;p&gt;Instead of using a string-based state system we can use an enum-based state system.&lt;/p&gt;

&lt;p&gt;Take a look at the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;GameWon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;GameOver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;GamePaused&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;gameState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ReduceHealth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;health&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;health&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;gameState&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GameOver&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gameState&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GameOver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;gameOverUI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetActive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might be wondering how this is different from a string-based system.&lt;/p&gt;

&lt;p&gt;In the string-based system your code will simply keep hitting the &lt;code&gt;else&lt;/code&gt; block without telling you what went wrong. But in the enum example, if you mistype a value like &lt;code&gt;State.GameOvr&lt;/code&gt;, the compiler (or even your IDE) will immediately show an error.&lt;/p&gt;

&lt;p&gt;This saves you hours of debugging by failing fast.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✏️2. Avoid Magic Strings — Use nameof
&lt;/h2&gt;

&lt;p&gt;Yes, this one is also about strings, and this will also save you from debugging for hours because of a simple spelling mistake.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nameof&lt;/code&gt; is an expression that returns the name of a variable, type, or method as a string value.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nameof&lt;/code&gt; specifically becomes useful when you need to provide the name of a method as a parameter, which opens the room for spelling mistakes.&lt;/p&gt;

&lt;p&gt;Take a look at the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// bad&lt;/span&gt;
&lt;span class="nf"&gt;Invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ResetGame"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// using string again.&lt;/span&gt;

&lt;span class="c1"&gt;// good&lt;/span&gt;
&lt;span class="nf"&gt;Invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ResetGame&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="m"&gt;2f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// using method name directly&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem with the "bad" example is that if you change the method name and forget to update the string value, then you won’t even know what went wrong.&lt;/p&gt;

&lt;p&gt;But if you use &lt;code&gt;nameof&lt;/code&gt;, the compiler will throw an error immediately if the method name changes.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✏️3. private &amp;gt; public
&lt;/h2&gt;

&lt;p&gt;This one is simple.&lt;/p&gt;

&lt;p&gt;Keep your class members private unless you really need to access them outside the class. This reduces the chances of accidental modifications.&lt;/p&gt;

&lt;p&gt;Take a look at the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// bad&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;health&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// good&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;health&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the "bad" example, any script can access the &lt;code&gt;health&lt;/code&gt; variable and change its value.&lt;/p&gt;

&lt;p&gt;Imagine your AudioManager having access to the player's health. You tried to change the volume but somehow your player's health goes up and down.&lt;/p&gt;

&lt;p&gt;Nightmare scenario, isn’t it?&lt;/p&gt;

&lt;p&gt;Keeping members private helps prevent such accidental access and modifications.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✏️4. readonly and const
&lt;/h2&gt;

&lt;p&gt;To stop mutation or modification of values we use readonly or const.&lt;/p&gt;

&lt;p&gt;We use const for compile-time constants like int, float, bool, etc. because the value is known at compile time and cannot be changed at runtime.&lt;/p&gt;

&lt;p&gt;We can assign the value only during declaration.&lt;/p&gt;

&lt;p&gt;We use readonly to stop reassignment of a reference type like List, Dictionary, etc.&lt;/p&gt;

&lt;p&gt;With readonly, you can only assign the reference once during declaration or inside the constructor.&lt;/p&gt;

&lt;p&gt;We cannot use const with types like List or Dictionary because their values are determined at runtime.&lt;/p&gt;

&lt;p&gt;Take a look at the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// bad&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;Dictionary&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Dictionary&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;maxHealth&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Dictionary&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt; &lt;span class="c1"&gt;// reassignment&lt;/span&gt;
    &lt;span class="n"&gt;maxHealth&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// easily changed even though it should be fixed&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// good&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;Dictionary&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Dictionary&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;maxHealth&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Dictionary&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt; &lt;span class="c1"&gt;// will throw error&lt;/span&gt;
    &lt;span class="n"&gt;maxHealth&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// will throw error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚠️Note: readonly prevents reassignment of the reference, but the contents of the object can still be modified.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡Key Takeaway
&lt;/h2&gt;

&lt;p&gt;Compile Time Safety helps catch problems before the game even runs.&lt;/p&gt;

&lt;p&gt;Using enums instead of strings, avoiding magic strings with &lt;code&gt;nameof&lt;/code&gt;, keeping members private, and using &lt;code&gt;const&lt;/code&gt; or &lt;code&gt;readonly&lt;/code&gt; where appropriate can significantly reduce the chances of runtime bugs.&lt;/p&gt;

&lt;p&gt;The earlier a bug appears, the easier it is to fix.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>csharp</category>
      <category>programming</category>
    </item>
    <item>
      <title>🐞Bug Resistant Development: Fail Fast – Part 2 (💾Data Validation Attributes – Min, Range, etc.)</title>
      <dc:creator>Rahul Barate</dc:creator>
      <pubDate>Thu, 26 Feb 2026 13:53:43 +0000</pubDate>
      <link>https://forem.com/rahul_barate_e965377330fe/bug-resistant-development-fail-fast-part-2-data-validation-attributes-min-range-etc-1h3i</link>
      <guid>https://forem.com/rahul_barate_e965377330fe/bug-resistant-development-fail-fast-part-2-data-validation-attributes-min-range-etc-1h3i</guid>
      <description>&lt;p&gt;In the last blog post we talked about RequireComponent and OnValidate, which help you fail fast.&lt;br&gt;
Fail fast means detecting problems early rather than when the game is already running.&lt;/p&gt;

&lt;p&gt;In this blog we’ll talk about Unity attributes used for data validation that help us catch issues in the Inspector itself.&lt;/p&gt;


&lt;h2&gt;
  
  
  🤔What are Attributes?
&lt;/h2&gt;

&lt;p&gt;An attribute tells the Editor how to behave with the fields, classes, or methods to which it is attached, without writing extra code.&lt;/p&gt;

&lt;p&gt;There are many attributes for different purposes such as:&lt;/p&gt;

&lt;p&gt;reference safety&lt;/p&gt;

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

&lt;p&gt;Inspector visualization&lt;/p&gt;

&lt;p&gt;In this blog we’ll focus only on the ones used for data validation and safer data entry.&lt;/p&gt;


&lt;h2&gt;
  
  
  ⚠️Important Note
&lt;/h2&gt;

&lt;p&gt;These attributes do not enforce rules at runtime.&lt;/p&gt;

&lt;p&gt;They only validate data inside the Inspector.&lt;/p&gt;

&lt;p&gt;If you change values through code, these attributes will not stop invalid data.&lt;br&gt;
For runtime safety, you still need validation logic in your scripts.&lt;/p&gt;


&lt;h2&gt;
  
  
  ✏️Data Validation Attributes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1) [Min()]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This attribute restricts an int or float to a minimum value in the Inspector.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Min(0)] public int health; //prevents negative values from being entered through the Inspector.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2) [Range()]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This attribute restricts a value to a specific range and also shows it as a slider in the Inspector.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Range(0, 100)] public float volume; // No negative values and nothing above 100.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3) [Tooltip()]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This displays a message when you hover over a field in the Inspector.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Tooltip("Represents the current health of the enemy")]
public int enemyHealth = 100;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4) [Header()]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Adds a header to group related fields.&lt;br&gt;
This improves readability and reduces the chances of assigning wrong values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Header("General Popup settings")]
public float popupAppearDuration = 0.5f;
public float popupStayDuration = 2f;
public float popupDisappearDuration = 0.5f;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5) [Space()]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Adds spacing between fields to make the Inspector cleaner.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public AudioMixer audioMixer;

[Space(20)]
public AudioMixerSnapshot muteSnapshot;
public AudioMixerSnapshot defaultSnapshot;

[Space(20)]
public AudioSource gameWonAudio;
public AudioSource gameOverAudio;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🖼️Checkout these screenshots of inspector window
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgu3nh6v8p7vxdxd96qtm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgu3nh6v8p7vxdxd96qtm.png" alt="Above attributes in action" width="749" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzdajit6lchj1w2uhz6ad.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzdajit6lchj1w2uhz6ad.png" alt="Above attributes in action" width="746" height="342"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  💡Key Takeaway
&lt;/h2&gt;

&lt;p&gt;These attributes won’t stop bad code, but they will stop bad data from being entered in the Inspector and that alone prevents a lot of bugs.&lt;/p&gt;

&lt;p&gt;Fail Fast is not just about catching null references.&lt;br&gt;
It’s also about guiding the user so wrong values are never entered in the first place.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>csharp</category>
      <category>programming</category>
    </item>
    <item>
      <title>🐞Bug Resistant Development: Fail Fast – Part 1 (RequireComponent &amp; OnValidate)</title>
      <dc:creator>Rahul Barate</dc:creator>
      <pubDate>Wed, 18 Feb 2026 06:10:24 +0000</pubDate>
      <link>https://forem.com/rahul_barate_e965377330fe/bug-resistant-development-fail-fast-part-1-requirecomponent-onvalidate-4h6m</link>
      <guid>https://forem.com/rahul_barate_e965377330fe/bug-resistant-development-fail-fast-part-1-requirecomponent-onvalidate-4h6m</guid>
      <description>&lt;p&gt;It’s been a while since I last posted a blog. I was busy with a few things, I had a deadline to meet for my new game which is now in the closed testing phase and will be available to download next month.&lt;/p&gt;

&lt;p&gt;Apart from this, I also have some good news to share, I am now a &lt;strong&gt;Unity Certified Associate Game Developer&lt;/strong&gt; 🎉&lt;/p&gt;

&lt;p&gt;Anyways, with that said, let’s start with today’s blog.&lt;/p&gt;

&lt;p&gt;With this post we are starting a new blog series where we’ll learn techniques that make your development process bug resistant, systems that fail early and tell you what went wrong, instead of throwing errors at runtime.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤔What does Fail Fast mean?
&lt;/h2&gt;

&lt;p&gt;Fail fast means detecting problems during development or in the Editor rather than discovering them while the game is running.&lt;/p&gt;

&lt;p&gt;The earlier something breaks, the easier it is to fix.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚠️The problem with GetComponent()
&lt;/h2&gt;

&lt;p&gt;While writing gameplay logic in C#, you must have used GetComponent().&lt;br&gt;
It is used to get a reference to another component on the same GameObject.&lt;br&gt;
But if you forget to add that required component…&lt;/p&gt;

&lt;p&gt;💥 NullReferenceException&lt;/p&gt;

&lt;p&gt;So, what if we could make sure that component is never missing?&lt;/p&gt;


&lt;h2&gt;
  
  
  🗝️RequireComponent
&lt;/h2&gt;

&lt;p&gt;This is where RequireComponent comes into the picture.&lt;/p&gt;

&lt;p&gt;RequireComponent is an attribute that automatically adds the required component when the script is attached to a GameObject.&lt;/p&gt;

&lt;p&gt;You don’t have to remember to add it manually.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[RequireComponent(typeof(Rigidbody))]
public class PlayerMovement : MonoBehaviour
{
}

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

&lt;/div&gt;



&lt;p&gt;Now whenever this script is added, Unity will also add a Rigidbody.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📝Note:&lt;/strong&gt;&lt;br&gt;
This does not cache the reference. You still need to call GetComponent() in your script but now you are safe because the component will always exist.&lt;/p&gt;


&lt;h2&gt;
  
  
  🤔What about other types of data?
&lt;/h2&gt;

&lt;p&gt;RequireComponent works for components.&lt;/p&gt;

&lt;p&gt;But what about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;integers&lt;/li&gt;
&lt;li&gt;floats&lt;/li&gt;
&lt;li&gt;strings&lt;/li&gt;
&lt;li&gt;optional references&lt;/li&gt;
&lt;li&gt;value validation?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where OnValidate() comes in.&lt;/p&gt;


&lt;h2&gt;
  
  
  🗝️OnValidate()
&lt;/h2&gt;

&lt;p&gt;OnValidate() is an Editor-only method.&lt;br&gt;
It is called when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;values change in the Inspector&lt;/li&gt;
&lt;li&gt;the script is recompiled&lt;/li&gt;
&lt;li&gt;entering Play mode&lt;/li&gt;
&lt;li&gt;the scene loads&lt;/li&gt;
&lt;li&gt;It does not run in builds.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can use it to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;perform null checks&lt;/li&gt;
&lt;li&gt;clamp values&lt;/li&gt;
&lt;li&gt;auto-assign references&lt;/li&gt;
&lt;li&gt;validate scene-only usage&lt;/li&gt;
&lt;li&gt;keep serialized data in sync&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;RequireComponent is for mandatory components.&lt;br&gt;
OnValidate is for data validation and smart auto-setup.&lt;/p&gt;

&lt;p&gt;Example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private void OnValidate()
    {
        if (canvasGroup == null)
        {
            canvasGroup = GetComponent&amp;lt;CanvasGroup&amp;gt;();
            if (canvasGroup == null)
            {
                canvasGroup = gameObject.AddComponent&amp;lt;CanvasGroup&amp;gt;();
                Debug.Log($"Added missing CanvasGroup to {gameObject.name}");
            }
        }

        if (masterVolume &amp;lt; -80f) masterVolume = -80f;
        if (masterVolume &amp;gt; 0f) masterVolume = 0f;

        if (uiElement == null)
        {
            Debug.LogWarning($"[Validation] {gameObject.name}: UI Element is not assigned!", gameObject);
        }

        if (sceneSpecificLight != null)
        {
            // Check if the object being validated is a Prefab or a Scene Instance
            bool isPrefab = EditorUtility.IsPersistent(this);
            bool isLightInScene = !EditorUtility.IsPersistent(sceneSpecificLight);

            if (isPrefab &amp;amp;&amp;amp; isLightInScene)
            {
                Debug.LogError($"[Validation] {gameObject.name}: You cannot assign a Scene object (Light) to a Prefab asset! Please clear this field.");
                sceneSpecificLight = null; // Force clear to prevent broken references
            }
        }

        if (actionButton != null &amp;amp;&amp;amp; !actionButton.interactable)
        {
            Debug.Log($"{gameObject.name}: Action Button is currently set to Non-Interactable.");
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  💡Key Takeaway
&lt;/h2&gt;

&lt;p&gt;Don’t wait for runtime errors to tell you something is wrong.&lt;/p&gt;

&lt;p&gt;Using RequireComponent and OnValidate, you can detect problems in the Editor itself and make your scripts far more reliable. This is the first step towards a bug resistant development workflow.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>programming</category>
      <category>csharp</category>
    </item>
    <item>
      <title>What is Time.deltaTime and how does it work?</title>
      <dc:creator>Rahul Barate</dc:creator>
      <pubDate>Wed, 10 Dec 2025 14:42:15 +0000</pubDate>
      <link>https://forem.com/rahul_barate_e965377330fe/what-is-timedeltatime-and-how-does-it-work-2mgn</link>
      <guid>https://forem.com/rahul_barate_e965377330fe/what-is-timedeltatime-and-how-does-it-work-2mgn</guid>
      <description>&lt;p&gt;If you are a beginner Game Developer or Programmer in Unity, you must have come across the term &lt;strong&gt;Time.deltaTime&lt;/strong&gt;. You might even know what it does, but have you ever wondered how it actually works?&lt;/p&gt;

&lt;p&gt;Let’s break it down in a simple way.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔What is Time.deltaTime?
&lt;/h2&gt;

&lt;p&gt;To understand Time.deltaTime, you first need to know what the &lt;strong&gt;Update()&lt;/strong&gt; method is.&lt;/p&gt;

&lt;p&gt;The Update method is the main player loop method in Unity. The Update() method is called &lt;strong&gt;every frame&lt;/strong&gt;. Whatever tasks you define in the Update method will run every frame. One of the very first things you learn to do inside Update is to make your character move in the world.&lt;/p&gt;

&lt;p&gt;Now let’s say you wrote some code that makes your character move &lt;strong&gt;1 unit&lt;/strong&gt; when you press a button. You save the code, Unity compiles it, and your character starts moving. Excited, you send the build to your friend who has a potato PC.&lt;/p&gt;

&lt;p&gt;Now on his PC, the character moves &lt;strong&gt;slower&lt;/strong&gt; and travels &lt;strong&gt;less distance&lt;/strong&gt; than on your PC.&lt;/p&gt;

&lt;p&gt;Why does this happen?&lt;/p&gt;

&lt;h2&gt;
  
  
  🔴The Real Problem: FPS
&lt;/h2&gt;

&lt;p&gt;The issue here is &lt;strong&gt;Frames Per Second (FPS)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You have a powerful PC, so your game runs at a high FPS. This means your Update method gets called &lt;strong&gt;more times per second&lt;/strong&gt;. So your character gets moved many more times.&lt;/p&gt;

&lt;p&gt;Your friend’s PC is slower, giving fewer FPS. That means Update runs fewer times per second, so your character moves fewer times.&lt;/p&gt;

&lt;p&gt;Result:&lt;br&gt;
 Higher FPS → Faster movement&lt;br&gt;
 Lower FPS → Slower movement&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;Time.deltaTime comes to the rescue&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Time.deltaTime gives us the &lt;strong&gt;time (in seconds) passed since the last frame&lt;/strong&gt;. When we multiply our movement with Time.deltaTime, it converts movement from &lt;strong&gt;per-frame movement to per-second movement&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So now, no matter how fast or slow the computer is, the character will travel the &lt;strong&gt;same distance in the same amount of real time&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  ⚙️How does it work?
&lt;/h2&gt;

&lt;p&gt;Let’s understand it with numbers.&lt;br&gt;
Let’s say:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your PC runs at 120 FPS&lt;/li&gt;
&lt;li&gt;Your friend’s PC runs at 60 FPS&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Example 1: WITHOUT Time.deltaTime.
&lt;/h3&gt;

&lt;p&gt;Movement each frame = 1 unit.&lt;/p&gt;

&lt;p&gt;On 60 FPS machine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update runs 60 times per second&lt;/li&gt;
&lt;li&gt;Movement per frame = 1 unit&lt;/li&gt;
&lt;li&gt;Movement per second = 60 × 1 = 60 units&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On 120 FPS machine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update runs 120 times per second&lt;/li&gt;
&lt;li&gt;Movement per frame = 1 unit&lt;/li&gt;
&lt;li&gt;Movement per second = 120 × 1 = 120 units.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Result: Faster machines move the character faster — BAD.&lt;/p&gt;
&lt;h3&gt;
  
  
  Example 2: WITH Time.deltaTime.
&lt;/h3&gt;

&lt;p&gt;Movement each frame = 1 unit × Time.deltaTime&lt;/p&gt;

&lt;p&gt;On 60 FPS machine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Time.deltaTime ≈ 1 / 60 = 0.01666 seconds&lt;/li&gt;
&lt;li&gt;Movement per frame = 1 × 0.01666 = 0.01666 units&lt;/li&gt;
&lt;li&gt;Movement after 60 frames (1 second): 0.01666 × 60 = 1 unit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On 120 FPS machine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Time.deltaTime ≈ 1 / 120 = 0.00833 seconds&lt;/li&gt;
&lt;li&gt;Movement per frame = 1 × 0.00833 = 0.00833 units&lt;/li&gt;
&lt;li&gt;Movement after 120 frames (1 second): 0.00833 × 120 = 1 unit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Result: Consistent character movement, regardless of FPS.&lt;/p&gt;
&lt;h2&gt;
  
  
  🌠How to use it?
&lt;/h2&gt;

&lt;p&gt;Using Time.deltaTime is very simple.&lt;br&gt;
Just multiply your movement value with Time.deltaTime.&lt;br&gt;
Take a look at following code snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;transform.Translate(Vector3.forward * 1f * Time.deltaTime);
// or
transform.position += movementSpeed * Time.deltaTime * transform.forward;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  💡Key Takeaway
&lt;/h2&gt;

&lt;p&gt;If you want to perform operations in the Update method and you want them to be frame-rate independent, then Time.deltaTime is your best buddy. Never do time-based movement in Update without it, unless you truly want different behavior on different machines.&lt;/p&gt;

&lt;h2&gt;
  
  
  💝Note
&lt;/h2&gt;

&lt;p&gt;If you like what do, please hit a like, drop a comment and share this blog. This will help me stay motivated and bring you folks more interesting blogs like this. Thank You!&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>unity3d</category>
      <category>programming</category>
      <category>fps</category>
    </item>
    <item>
      <title>Saving Game Data in Unity — Part 4: SQLite</title>
      <dc:creator>Rahul Barate</dc:creator>
      <pubDate>Thu, 20 Nov 2025 14:12:13 +0000</pubDate>
      <link>https://forem.com/rahul_barate_e965377330fe/saving-game-data-in-unity-part-4-sqlite-4mdd</link>
      <guid>https://forem.com/rahul_barate_e965377330fe/saving-game-data-in-unity-part-4-sqlite-4mdd</guid>
      <description>&lt;p&gt;In the last blog, we talked about how you can store data using ScriptableObjects. ScriptableObjects are great for storing static or design-time data.&lt;br&gt;
But what if your game needs to store huge amounts of data?&lt;br&gt;
I’m talking hundreds or thousands of records — dialogues, inventories, quest data, item lists, etc. JSON or XML will start slowing down at that point.&lt;br&gt;
And that’s exactly what we’re going to talk about today.&lt;/p&gt;
&lt;h2&gt;
  
  
  🤔What is SQLite?
&lt;/h2&gt;

&lt;p&gt;SQLite is a free and open-source &lt;strong&gt;relational database&lt;/strong&gt;. It’s lightweight, self-contained, and perfect for storing large amounts of structured, queryable data. It’s also cross-platform and works extremely well inside Unity.&lt;br&gt;
SQLite is a great choice when you want to store data that is both &lt;strong&gt;huge&lt;/strong&gt; and &lt;strong&gt;queryable&lt;/strong&gt;, for example:&lt;/p&gt;

&lt;p&gt;➡️Item lists&lt;br&gt;
 ➡️Inventories&lt;br&gt;
 ➡️Dialogue trees&lt;br&gt;
 ➡️NPC data&lt;br&gt;
 ➡️Quest systems&lt;br&gt;
 ➡️Any dataset you need fast search/filter operations on&lt;/p&gt;
&lt;h2&gt;
  
  
  ⚙️Setting up SQLite in Unity
&lt;/h2&gt;

&lt;p&gt;Setting up SQLite is not as straightforward as PlayerPrefs or ScriptableObjects, but don’t worry — I’ll walk you through everything. Just follow the steps exactly.&lt;/p&gt;
&lt;h2&gt;
  
  
  ⚠️Prerequisites
&lt;/h2&gt;

&lt;p&gt;You should know the very basics of SQL — what a table is, what a query is, and how SELECT/INSERT work.&lt;/p&gt;
&lt;h2&gt;
  
  
  ⚙️Initial Setup
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;➡️Download or clone the &lt;a href="https://github.com/robertohuertasm/SQLite4Unity3d/tree/master?tab=readme-ov-file" rel="noopener noreferrer"&gt;repo&lt;/a&gt;: on your PC.&lt;/li&gt;
&lt;li&gt;➡️Create a new Unity project. &lt;/li&gt;
&lt;li&gt;➡️Copy the following folders/files from the repo into your project in the exact same locations:&lt;/li&gt;
&lt;li&gt;- ➡️Assets/Plugins folder&lt;/li&gt;
&lt;li&gt;- ➡️Scripts/DataService.cs and Scripts/SQLite.cs&lt;/li&gt;
&lt;li&gt;- ➡️StreamingAssets folder&lt;/li&gt;
&lt;li&gt;➡️Download and install DB Browser for SQLite.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  🤔What are the DataService and SQLite scripts?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;✏️DataService&lt;/strong&gt;&lt;br&gt;
This class creates a connection to your database using SQLite’s methods. Once the connection is open, you can query or store data just by calling DataService methods. You mainly need its constructor and the helper functions inside it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✏️SQLite script&lt;/strong&gt;&lt;br&gt;
This is the interface that provides low-level methods for opening/closing connections, creating tables, inserting data, deleting data, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💡Note:&lt;/strong&gt;&lt;br&gt;
You don’t need to understand how the full implementation works internally. You only need to know how to use the DataService to interact with your database.&lt;/p&gt;
&lt;h2&gt;
  
  
  🤔What are the .db files inside StreamingAssets?
&lt;/h2&gt;

&lt;p&gt;These are the actual SQLite database files.&lt;br&gt;
Unity keeps everything inside StreamingAssets as-is, meaning the database file is copied exactly into the build. SQLite then opens this file and reads/writes data during gameplay.&lt;/p&gt;
&lt;h2&gt;
  
  
  🚀Creating Your Own Database
&lt;/h2&gt;

&lt;p&gt;You can do this in two ways:&lt;br&gt;
&lt;strong&gt;➡️Option A:&lt;/strong&gt;&lt;br&gt;
 Duplicate any .db file from StreamingAssets, rename it, open it in DB Browser, and clear the existing data so you can add your own later.&lt;br&gt;
&lt;strong&gt;➡️Option B:&lt;/strong&gt;&lt;br&gt;
 Rename one of the existing .db files and delete all the data inside it. You will write fresh data using Unity scripts.&lt;/p&gt;
&lt;h2&gt;
  
  
  🔗Setting up a Connection
&lt;/h2&gt;

&lt;p&gt;To connect to your database, create an instance of the DataService class in your main script:&lt;br&gt;
&lt;code&gt;DataService dataService = new DataService("YourDatabaseName.db");&lt;/code&gt;&lt;br&gt;
This opens the connection and prepares everything for inserting or reading data.&lt;/p&gt;
&lt;h2&gt;
  
  
  📑Creating a Table
&lt;/h2&gt;

&lt;p&gt;First, define the structure of your table using a C# class.&lt;br&gt;
 For example, here is a simple Word table:&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 Word
{
    public string Text { get; set; }
    public int IsUsed { get; set; }
    public int TextLength { get; set; }
}

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

&lt;/div&gt;



&lt;p&gt;Once your class is ready, you need to write a method inside DataService that creates the table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void CreateTable()
    {
        try
        {
            _connection.CreateTable&amp;lt;Word&amp;gt;();
        }
        catch (System.Exception e)
        {
            Debug.LogError(e.Message);
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, you can then use the _connection object inside DataService to access all SQLite methods. You can check the SQLite class to see what methods are provided or paste the file into ChatGPT (or any AI) to understand the available functions.&lt;br&gt;
Below is a basic example of DataService class to get you started:&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 DataService
{

    private SQLiteConnection _connection;
        // constructor will be here; I removed to keep the script simple. Make sure you have it.
    public void CreateTable()
    {
        try
        {
            _connection.CreateTable&amp;lt;Word&amp;gt;();
        }
        catch (System.Exception e)
        {
            Debug.LogError(e.Message);
        }
    }
    public void AddWordsToDatabase(List&amp;lt;Word&amp;gt; words)
    {
        try
        {
            _connection.InsertAll(words);
        }
        catch (System.Exception e)
        {
            Debug.LogError(e.Message);
        }
    }
    public IEnumerable&amp;lt;Word&amp;gt; GetAllWords()
    {
        return _connection.Table&amp;lt;Word&amp;gt;();
    }
    public List&amp;lt;Word&amp;gt; GetWords(int wordLength, int numberOfWords)
    {
        List&amp;lt;Word&amp;gt; words = new List&amp;lt;Word&amp;gt;();
        try
        {
            TableQuery&amp;lt;Word&amp;gt; result = _connection.Table&amp;lt;Word&amp;gt;()
            .Where(x =&amp;gt; x.TextLength == wordLength &amp;amp;&amp;amp; x.IsUsed == 0)
            .Take(numberOfWords);

            foreach (Word word in result)
                words.Add(word);

            return words;
        }
        catch (System.Exception e)
        {
            Debug.LogError($"Error fetching words from database: {e.Message}");
        }
        return words;
    }
    public void DropTable()
    {
        try
        {
            _connection.DropTable&amp;lt;Word&amp;gt;();
        }
        catch (System.Exception e)
        {
            Debug.LogError(e.Message);
        }
    }


}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  🗝️Key Takeaway
&lt;/h2&gt;

&lt;p&gt;SQLite is perfect when your game needs to store large, structured, searchable data.&lt;br&gt;
 If your data grows beyond what JSON/XML or ScriptableObjects can handle easily, SQLite gives you a fast and scalable solution right inside Unity.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>unity3d</category>
      <category>sql</category>
      <category>programming</category>
    </item>
    <item>
      <title>Saving Game Data in Unity — Part 3: ScriptableObjects</title>
      <dc:creator>Rahul Barate</dc:creator>
      <pubDate>Wed, 12 Nov 2025 13:47:00 +0000</pubDate>
      <link>https://forem.com/rahul_barate_e965377330fe/saving-game-data-in-unity-part-3-scriptableobjects-2ob7</link>
      <guid>https://forem.com/rahul_barate_e965377330fe/saving-game-data-in-unity-part-3-scriptableobjects-2ob7</guid>
      <description>&lt;p&gt;In the last blog, we talked about how you can store data using &lt;strong&gt;JSON/XML&lt;/strong&gt; files. JSON and XML are excellent choices for saving &lt;strong&gt;structured data at runtime&lt;/strong&gt;, like player progress or save files.&lt;/p&gt;

&lt;p&gt;On the other hand, &lt;strong&gt;ScriptableObjects&lt;/strong&gt; are great for storing &lt;strong&gt;static&lt;/strong&gt; or &lt;strong&gt;design-time data&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Static data means information that has only one copy (shared by multiple scripts) — for example, base weapon stats, character attributes, or item definitions.&lt;br&gt;
 Design-time data means data you create beforehand while designing your game — something you write once and rarely update during gameplay.&lt;/p&gt;

&lt;p&gt;One thing I like about ScriptableObjects is that &lt;strong&gt;they exist as assets in your project&lt;/strong&gt;, so they retain their values even when you close and reopen Unity. They also help you separate data from logic, making your code cleaner and more modular.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Use ScriptableObjects?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;They’re more &lt;strong&gt;memory efficient&lt;/strong&gt; than duplicating MonoBehaviour data.&lt;/li&gt;
&lt;li&gt;Multiple objects can share the same ScriptableObject instance.&lt;/li&gt;
&lt;li&gt;Perfect for &lt;strong&gt;storing configuration or reference data&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;They keep your &lt;strong&gt;project organized&lt;/strong&gt;, especially when working with designers.&lt;/li&gt;
&lt;li&gt;Values are &lt;strong&gt;serialized&lt;/strong&gt; and saved as &lt;code&gt;.asset&lt;/code&gt; files, so they persist across editor sessions.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  How to Create a ScriptableObject
&lt;/h2&gt;

&lt;p&gt;Unlike MonoBehaviours, &lt;strong&gt;you don’t attach ScriptableObjects to GameObjects&lt;/strong&gt;.&lt;br&gt;
 Instead, you create a custom class that inherits from &lt;code&gt;ScriptableObject&lt;/code&gt;, and then you can create instances of it as project assets.&lt;br&gt;
To do that, use the &lt;code&gt;CreateAssetMenu&lt;/code&gt; attribute — it lets you create ScriptableObject instances directly from the Unity Editor’s right-click menu.&lt;br&gt;
Take a look at following example structure&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;

[CreateAssetMenu(fileName = "NewWeaponData", menuName = "Game/Weapon Data")]
public class WeaponData : ScriptableObject
{
    public string weaponName;
    public int damage;
    public float range;
    public float fireRate;
    public Sprite icon;
}

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

&lt;/div&gt;



&lt;p&gt;Now, you can create an instance by right-clicking in your Project window:&lt;br&gt;
 &lt;strong&gt;Create&lt;/strong&gt; → &lt;strong&gt;Game&lt;/strong&gt; → &lt;strong&gt;Weapon Data&lt;/strong&gt;&lt;br&gt;
Unity will create a &lt;code&gt;.asset&lt;/code&gt; file in your project folder that holds your weapon data.&lt;br&gt;
 You can then drag and drop this asset into any script field in the Inspector, just like any other reference.&lt;/p&gt;

&lt;p&gt;The following is an example use case.&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;

public class Weapon : MonoBehaviour
{
    public WeaponData weaponData;

    private void Start()
    {
        if (weaponData != null)
        {
            Debug.Log($"Equipped: {weaponData.weaponName} | Damage: {weaponData.damage} | Range: {weaponData.range}");
        }
        else
        {
            Debug.LogWarning("No WeaponData assigned!");
        }
    }

    public void Fire()
    {
        if (weaponData == null) return;

        Debug.Log($"{weaponData.weaponName} fired! Damage: {weaponData.damage}");
        // Add shooting logic here
    }
}

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

&lt;/div&gt;



&lt;p&gt;Attach this script to Weapon GameObject, assign your created WeaponData asset in the Inspector, and you’re done!&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaway
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ScriptableObjects&lt;/strong&gt; are perfect for storing static, shared, or configuration data in Unity.&lt;br&gt;
 They keep your code modular, improve memory efficiency, and make it easy to manage data outside of scenes.&lt;br&gt;
If you find yourself copying the same data into multiple prefabs or scripts, it’s time to consider moving that data into a ScriptableObject.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>csharp</category>
      <category>programming</category>
    </item>
    <item>
      <title>Saving Game Data in Unity — Part 2: JSON/XML files</title>
      <dc:creator>Rahul Barate</dc:creator>
      <pubDate>Wed, 05 Nov 2025 13:34:48 +0000</pubDate>
      <link>https://forem.com/rahul_barate_e965377330fe/saving-game-data-in-unity-part-2-jsonxml-files-9gp</link>
      <guid>https://forem.com/rahul_barate_e965377330fe/saving-game-data-in-unity-part-2-jsonxml-files-9gp</guid>
      <description>&lt;p&gt;Hello folks!&lt;br&gt;
 Sorry for not posting anything over the last few weeks — I was away for Diwali holidays and caught up with some other work. But I’m back now!&lt;br&gt;
In my last blog post, we talked about &lt;strong&gt;PlayerPrefs&lt;/strong&gt;, which was the first entry in my “Different Ways of Storing Game Data” series. Today, we’ll look at another way to store data in Unity — using &lt;strong&gt;JSON&lt;/strong&gt; and &lt;strong&gt;XML files&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is JSON?
&lt;/h2&gt;

&lt;p&gt;For those who don’t know, JSON stands for &lt;strong&gt;JavaScript Object Notation&lt;/strong&gt;. It’s a lightweight text format that’s easy for both humans and machines to read and write. Because of its simplicity, JSON has become the standard for transferring and storing data across different systems.&lt;br&gt;
JSON is &lt;strong&gt;language-independent&lt;/strong&gt;, meaning you can use it with almost any programming language once you understand its structure. It stores data as &lt;strong&gt;key-value pairs&lt;/strong&gt;, separated by commas. JSON supports numbers, booleans, strings, arrays, objects, and null values.&lt;br&gt;
Here’s a simple example of JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "firstName": "John",
  "lastName": "Doe",
  "isEmployed": true,
  "skills": ["JavaScript", "Python", "SQL"],
  "address": {
    "street": "123 Main St",
    "city": "Anytown"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(I’ll leave some useful links at the end where you can learn more about JSON and XML.)&lt;/p&gt;

&lt;h2&gt;
  
  
  What is XML?
&lt;/h2&gt;

&lt;p&gt;XML stands for &lt;strong&gt;Extensible Markup Language&lt;/strong&gt;. It’s similar to HTML in structure but unlike HTML, XML is extensible — meaning you can define your own custom tags to describe the data.&lt;br&gt;
XML doesn’t “do” anything by itself; it’s just a structured way of storing and describing information using tags. It’s also widely used for data storage and transfer, though it’s typically more verbose than JSON.&lt;br&gt;
Here’s an example of what XML looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;bookstore&amp;gt;
  &amp;lt;book category="cooking"&amp;gt;
    &amp;lt;title lang="en"&amp;gt;Everyday Italian&amp;lt;/title&amp;gt;
    &amp;lt;author&amp;gt;Giada De Laurentiis&amp;lt;/author&amp;gt;
    &amp;lt;year&amp;gt;2005&amp;lt;/year&amp;gt;
    &amp;lt;price&amp;gt;30.00&amp;lt;/price&amp;gt;
  &amp;lt;/book&amp;gt;
  &amp;lt;book category="children"&amp;gt;
    &amp;lt;title lang="en"&amp;gt;Harry Potter&amp;lt;/title&amp;gt;
    &amp;lt;author&amp;gt;J. K. Rowling&amp;lt;/author&amp;gt;
    &amp;lt;year&amp;gt;2005&amp;lt;/year&amp;gt;
    &amp;lt;price&amp;gt;29.99&amp;lt;/price&amp;gt;
  &amp;lt;/book&amp;gt;
&amp;lt;/bookstore&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to Use JSON in Unity
&lt;/h2&gt;

&lt;p&gt;Using JSON in Unity is straightforward.&lt;br&gt;
To &lt;strong&gt;store data&lt;/strong&gt; in JSON format, you first need to convert your data into a JSON string using &lt;code&gt;JsonUtility.ToJson()&lt;/code&gt;.&lt;br&gt;
 To &lt;strong&gt;read or parse&lt;/strong&gt; that data, you can use &lt;code&gt;JsonUtility.FromJson()&lt;/code&gt; to convert it back into your desired C# type (either a built-in type or a custom class).&lt;br&gt;
JSON files are typically stored in &lt;code&gt;Application.persistentDataPath&lt;/code&gt;, so they persist between sessions. You can also create subfolders inside that path to organize your saves.&lt;br&gt;
Here’s the structure of what it might look like in code:&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;
using System.IO;

[System.Serializable]
public class PlayerData
{
    public int level;
    public int coins;
    public string playerName;
}

public class JsonSaveSystem : MonoBehaviour
{
    private string savePath;

    private void Awake()
    {
        savePath = Path.Combine(Application.persistentDataPath, "playerSave.json");
    }

    public void SaveGame()
    {
        PlayerData data = new PlayerData()
        {
            level = 5,
            coins = 200,
            playerName = "Rahul"
        };

        string json = JsonUtility.ToJson(data, true);
        File.WriteAllText(savePath, json);
        Debug.Log("Game saved to: " + savePath);
    }

    public void LoadGame()
    {
        if (File.Exists(savePath))
        {
            string json = File.ReadAllText(savePath);
            PlayerData data = JsonUtility.FromJson&amp;lt;PlayerData&amp;gt;(json);
            Debug.Log($"Loaded: Level {data.level}, Coins {data.coins}, Name {data.playerName}");
        }
        else
        {
            Debug.LogWarning("No save file found!");
        }
    }
}

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

&lt;/div&gt;



&lt;p&gt;💡&lt;strong&gt;Note:&lt;/strong&gt; Unity’s built-in JsonUtility is fast but limited. It doesn’t handle nested lists or dictionaries well.&lt;br&gt;
For more advanced cases, you can use the &lt;strong&gt;Newtonsoft JSON&lt;/strong&gt; package (Json.NET), which supports more complex data structures.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to Use XML in Unity
&lt;/h2&gt;

&lt;p&gt;To work with XML in Unity, you’ll use the XmlSerializer class.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create an &lt;code&gt;XmlSerializer&lt;/code&gt; instance for your data type.&lt;/li&gt;
&lt;li&gt;Create a &lt;code&gt;FileStream&lt;/code&gt; to write your data to disk.&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;Serialize()&lt;/code&gt; method to write your object as XML to the file.&lt;/li&gt;
&lt;li&gt;To read data, do the same but call &lt;code&gt;Deserialize()&lt;/code&gt; instead.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just like JSON, XML files are stored inside &lt;code&gt;Application.persistentDataPath&lt;/code&gt; so your data remains saved between sessions.&lt;br&gt;
Here’s a simple structure for XML in code:&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;
using System.IO;
using System.Xml.Serialization;

[System.Serializable]
public class PlayerDataXML
{
    public int level;
    public int coins;
    public string playerName;
}

public class XmlSaveSystem : MonoBehaviour
{
    private string savePath;

    private void Awake()
    {
        savePath = Path.Combine(Application.persistentDataPath, "playerSave.xml");
    }

    public void SaveGame()
    {
        PlayerDataXML data = new PlayerDataXML()
        {
            level = 5,
            coins = 200,
            playerName = "Rahul"
        };

        XmlSerializer serializer = new XmlSerializer(typeof(PlayerDataXML));
        using (FileStream stream = new FileStream(savePath, FileMode.Create))
        {
            serializer.Serialize(stream, data);
        }

        Debug.Log("Game saved (XML) to: " + savePath);
    }

    public void LoadGame()
    {
        if (File.Exists(savePath))
        {
            XmlSerializer serializer = new XmlSerializer(typeof(PlayerDataXML));
            using (FileStream stream = new FileStream(savePath, FileMode.Open))
            {
                PlayerDataXML data = (PlayerDataXML)serializer.Deserialize(stream);
                Debug.Log($"Loaded (XML): Level {data.level}, Coins {data.coins}, Name {data.playerName}");
            }
        }
        else
        {
            Debug.LogWarning("No XML save file found!");
        }
    }
}

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

&lt;/div&gt;



&lt;p&gt;⚠️ &lt;strong&gt;Note:&lt;/strong&gt; XML is great for readability and structured data but is generally heavier and slower compared to JSON.&lt;br&gt;
Use it when you specifically need hierarchical tagging or compatibility with systems that expect XML.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaway
&lt;/h2&gt;

&lt;p&gt;JSON and XML are both excellent choices for saving structured data in Unity.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;JSON&lt;/strong&gt; when you want lightweight, human-readable data with quick serialization and deserialization.&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;XML&lt;/strong&gt;when your data needs a more descriptive structure or you’re working with systems that rely on XML.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both methods are great for saving &lt;strong&gt;player progress, inventory data, or custom level information&lt;/strong&gt; — especially when you want control over your save files.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>unity3d</category>
      <category>csharp</category>
      <category>programming</category>
    </item>
    <item>
      <title>Saving Game Data in Unity — Part 1: PlayerPrefs</title>
      <dc:creator>Rahul Barate</dc:creator>
      <pubDate>Tue, 07 Oct 2025 13:02:52 +0000</pubDate>
      <link>https://forem.com/rahul_barate_e965377330fe/saving-game-data-in-unity-part-1-playerprefs-22hb</link>
      <guid>https://forem.com/rahul_barate_e965377330fe/saving-game-data-in-unity-part-1-playerprefs-22hb</guid>
      <description>&lt;p&gt;When it comes to storing game data in Unity, there are several ways to do it — and choosing the right one is important. The data storage method you pick can directly affect your game’s efficiency, speed, and overall performance.&lt;/p&gt;

&lt;p&gt;If you want to store &lt;strong&gt;static data&lt;/strong&gt; like item stats, lists, or character configs, &lt;strong&gt;ScriptableObjects&lt;/strong&gt; are a great choice.&lt;br&gt;
 If you want to store &lt;strong&gt;game saves, player progress, or structured runtime data, JSON/XML files&lt;/strong&gt; are better.&lt;br&gt;
 If you’re dealing with &lt;strong&gt;large, queryable datasets, SQLite databases&lt;/strong&gt; are ideal.&lt;br&gt;
 When you want to &lt;strong&gt;bundle data or assets&lt;/strong&gt; with your build, &lt;strong&gt;Resources or Addressables&lt;/strong&gt; are useful.&lt;br&gt;
 And if you want to &lt;strong&gt;prototype data storage&lt;/strong&gt; or save &lt;strong&gt;non-sensitive information&lt;/strong&gt; such as settings, control layouts, or the last completed level — &lt;strong&gt;PlayerPrefs&lt;/strong&gt; is the best option.&lt;/p&gt;

&lt;p&gt;One by one, we’ll explore each of these in upcoming blogs. Today, let’s start with PlayerPrefs.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is PlayerPrefs?
&lt;/h2&gt;

&lt;p&gt;PlayerPrefs is a Unity class that allows you to store &lt;strong&gt;small and simple pieces of data&lt;/strong&gt; locally. It’s best used for quick, lightweight saves — not full save files or complex objects.&lt;br&gt;
Internally, PlayerPrefs stores data in the &lt;strong&gt;local registry or system-specific storage&lt;/strong&gt;, without any encryption. It’s great for prototyping or saving basic settings, but you should avoid using it for sensitive or large-scale game data.&lt;br&gt;
You can store &lt;strong&gt;int&lt;/strong&gt;, &lt;strong&gt;float&lt;/strong&gt;, and &lt;strong&gt;string&lt;/strong&gt; values directly. You can also serialize objects into &lt;strong&gt;JSON strings&lt;/strong&gt; if needed.&lt;/p&gt;
&lt;h2&gt;
  
  
  When to Use PlayerPrefs
&lt;/h2&gt;

&lt;p&gt;Use PlayerPrefs when you need to save:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Game settings (volume, graphics quality, key bindings)&lt;/li&gt;
&lt;li&gt;Last level completed&lt;/li&gt;
&lt;li&gt;Player name or preferences&lt;/li&gt;
&lt;li&gt;Control layouts&lt;/li&gt;
&lt;li&gt;Other lightweight data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Avoid using it for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inventories, save files, or complex structured data&lt;/li&gt;
&lt;li&gt;Sensitive information like login details or in-game purchases&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Common Methods
&lt;/h2&gt;

&lt;p&gt;PlayerPrefs exposes several static methods to handle data operations. Here’s an example script that demonstrates how to use them:&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;
public class GameSettingsManager : MonoBehaviour
{
    // Example game settings
    private float masterVolume = 0.8f;
    private float brightness = 1.0f;
    private int difficultyLevel = 2; // 0 = Easy, 1 = Medium, 2 = Hard

    private void Start()
    {
        // Load settings on start
        LoadSettings();
    }

    public void SaveSettings()
    {
        // Save individual settings
        PlayerPrefs.SetFloat("MasterVolume", masterVolume);
        PlayerPrefs.SetFloat("Brightness", brightness);
        PlayerPrefs.SetInt("DifficultyLevel", difficultyLevel);

        // Ensure data is written to disk
        PlayerPrefs.Save();

        Debug.Log("Settings saved!");
    }

    public void LoadSettings()
    {
        // Check if a key exists before reading
        if (PlayerPrefs.HasKey("MasterVolume"))
            masterVolume = PlayerPrefs.GetFloat("MasterVolume");

        if (PlayerPrefs.HasKey("Brightness"))
            brightness = PlayerPrefs.GetFloat("Brightness");

        if (PlayerPrefs.HasKey("DifficultyLevel"))
            difficultyLevel = PlayerPrefs.GetInt("DifficultyLevel");

        Debug.Log($"Settings loaded:\nVolume: {masterVolume}\nBrightness: {brightness}\nDifficulty: {difficultyLevel}");
    }

    public void ResetSettings()
    {
        // Delete a single key
        PlayerPrefs.DeleteKey("MasterVolume");
        PlayerPrefs.DeleteKey("Brightness");
        PlayerPrefs.DeleteKey("DifficultyLevel");

        Debug.Log("Individual settings deleted!");
    }

    public void DeleteAllSettings()
    {
        // Delete everything saved by PlayerPrefs
        PlayerPrefs.DeleteAll();
        Debug.Log("All PlayerPrefs cleared!");
    }

    // Example for toggling between difficulty levels
    public void CycleDifficulty()
    {
        difficultyLevel = (difficultyLevel + 1) % 3;
        SaveSettings();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Where Unity Stores PlayerPrefs
&lt;/h2&gt;

&lt;p&gt;Unity stores PlayerPrefs in different locations depending on the operating system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows: Registry — HKEY_CURRENT_USER\Software[CompanyName][ProductName]&lt;/li&gt;
&lt;li&gt;MacOS: ~/Library/Preferences/com.[CompanyName].[ProductName].plist&lt;/li&gt;
&lt;li&gt;Android: /data/data/[pkg-name]/shared_prefs/[pkg-name].v2.playerprefs.xml&lt;/li&gt;
&lt;li&gt;iOS: Uses [NSUserDefaults standardUserDefaults] API&lt;/li&gt;
&lt;li&gt;Linux: ~/.config/unity3d/[CompanyName]/[ProductName]&lt;/li&gt;
&lt;li&gt;WebGL: Stored in the browser’s IndexedDB, up to 1MB&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Takeaway
&lt;/h2&gt;

&lt;p&gt;PlayerPrefs is a quick and easy way to store small pieces of data in Unity. It’s perfect for prototyping, player settings, and preferences — but not ideal for complex or sensitive data. In the next part, we’ll explore other data storage methods like JSON files and ScriptableObjects to handle larger or more structured data.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>gamedev</category>
      <category>programming</category>
      <category>unity3d</category>
    </item>
    <item>
      <title>Making Your Unity UI Come Alive with Videos</title>
      <dc:creator>Rahul Barate</dc:creator>
      <pubDate>Tue, 30 Sep 2025 14:42:58 +0000</pubDate>
      <link>https://forem.com/rahul_barate_e965377330fe/making-your-unity-ui-come-alive-with-videos-49cb</link>
      <guid>https://forem.com/rahul_barate_e965377330fe/making-your-unity-ui-come-alive-with-videos-49cb</guid>
      <description>&lt;h2&gt;
  
  
  Intro:
&lt;/h2&gt;

&lt;p&gt;In my previous games, I’ve always used images and buttons to create the Level/Mission selection menu. But this time, I wanted players to feel the game was more alive instead of staring at static pictures. That’s when I thought — why not add videos?&lt;br&gt;
Each selection button could play a short looping clip of that level or mission, giving players a glimpse of what’s ahead before they dive in. This not only makes the UI more dynamic but also helps players connect with the game world earlier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-requisites:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Have your videos ready and imported into Unity.&lt;/li&gt;
&lt;li&gt;Make sure they don’t have blank frames at the start or end (for smooth looping).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Steps (Method 1: RawImage + VideoPlayer + RenderTexture):
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Import your videos into the Unity Project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a RenderTexture for each video:&lt;br&gt;
a) Right-click in the Project window → Create → Rendering → Render Texture.&lt;br&gt;
b) Set Dimension to &lt;strong&gt;2D&lt;/strong&gt;.&lt;br&gt;
c) Adjust the size based on your aspect ratio (I used &lt;strong&gt;640x360&lt;/strong&gt; for 16:9).&lt;br&gt;
d) Other settings are optional — check Unity docs if you want to tweak.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inside your Canvas, create a Raw Image:&lt;br&gt;
a) Right-click in the Hierarchy → UI → Raw Image.&lt;br&gt;
b) Set its Width/Height (I matched my RenderTexture size).&lt;br&gt;
c) Assign the RenderTexture you created to the Raw Image’s &lt;strong&gt;Texture&lt;/strong&gt; &lt;br&gt;
field.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a Video Player:&lt;br&gt;
a) Right-click the Raw Image in the Hierarchy → Video → Video Player.&lt;br&gt;
b) Set &lt;strong&gt;Source&lt;/strong&gt; to Video Clip.&lt;br&gt;
c) Assign the video you imported.&lt;br&gt;
d) Enable &lt;strong&gt;Play On Awake&lt;/strong&gt; and &lt;strong&gt;Loop&lt;/strong&gt; (if you want looping).&lt;br&gt;
e) Set Render Mode to Render Texture and assign the RenderTexture you created.&lt;br&gt;
f) Adjust settings like playback speed, mute, or volume as needed.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And that’s it — you’ve added video to your UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Approach?
&lt;/h2&gt;

&lt;p&gt;This RawImage + RenderTexture + VideoPlayer setup is reliable and works well for menus, previews, or even background animations. It keeps your UI flexible, since you can use multiple videos across different slots or buttons.&lt;br&gt;
There are other approaches too — such as directly assigning a video to a material or using Unity’s UI Toolkit (if you’re on newer versions). But for most UI menus, this method strikes the right balance of simplicity and control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaway:
&lt;/h2&gt;

&lt;p&gt;Adding videos to your Unity UI isn’t complicated. With a simple RenderTexture setup, you can replace static images with dynamic clips that make your menus feel alive and give players a preview of what’s coming.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>csharp</category>
      <category>programming</category>
    </item>
    <item>
      <title>Unlock More FPS with Object Pooling</title>
      <dc:creator>Rahul Barate</dc:creator>
      <pubDate>Tue, 23 Sep 2025 18:02:06 +0000</pubDate>
      <link>https://forem.com/rahul_barate_e965377330fe/unlock-more-fps-with-object-pooling-3e3f</link>
      <guid>https://forem.com/rahul_barate_e965377330fe/unlock-more-fps-with-object-pooling-3e3f</guid>
      <description>&lt;p&gt;I’m starting a new series of blogs where I’ll share the tips and tricks I use to optimize games for better FPS. I’ll only share the techniques that I learn myself or actually use in my projects.&lt;/p&gt;

&lt;p&gt;Today, let’s talk about one of the biggest game optimization techniques in Unity: &lt;strong&gt;Object Pooling&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem: Instantiate and Destroy Everywhere
&lt;/h2&gt;

&lt;p&gt;For reference, here’s a scenario from one of my games.&lt;/p&gt;

&lt;p&gt;I was working on a bombing and cannon fire mechanism. Bombs drop from above at fixed intervals but from random locations, and cannons fire cannonballs at fixed intervals sequentially. I wrote a script where I assigned the bomb/cannonball prefab, instantiated it at runtime, and fired it. Once the bomb/cannonball touched anything, it would self-destruct using the Destroy method.&lt;/p&gt;

&lt;p&gt;On PC, this worked fine — I was getting around 200 FPS. But when I built the APK and ran it on my mobile, FPS dropped to barely 30 and my phone was heating a lot.&lt;/p&gt;

&lt;p&gt;After some research, I learned why: instantiation and destruction are among the heaviest operations you can perform at runtime. And since I was doing this every 3–5 seconds, it was tanking mobile performance.&lt;/p&gt;

&lt;p&gt;Every time you &lt;strong&gt;instantiate&lt;/strong&gt; an object Unity allocates memory for: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The GameObject itself&lt;/li&gt;
&lt;li&gt;All its components&lt;/li&gt;
&lt;li&gt;Meshes, colliders, scripts, etc. &lt;/li&gt;
&lt;li&gt;Clone all component data&lt;/li&gt;
&lt;li&gt;Initialize references&lt;/li&gt;
&lt;li&gt;Register it with the physics system (if it has Rigidbody/Collider)&lt;/li&gt;
&lt;li&gt;Register it with a rendering system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every time you &lt;strong&gt;destroy&lt;/strong&gt; an object using Unity it has to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remove it from the Scene hierarchy&lt;/li&gt;
&lt;li&gt;Clean up references&lt;/li&gt;
&lt;li&gt;Free memory&lt;/li&gt;
&lt;li&gt;Unregister physics/rendering data.
(This might be cheaper than instantiation however, GC spikes can happen later, which adds hidden cost.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Solution: Reuse Instead of Recreate
&lt;/h2&gt;

&lt;p&gt;There are two main ways to solve this problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Approach 1: Enable/Disable&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the bomb or cannonball object to the scene and keep it hidden.&lt;/li&gt;
&lt;li&gt;When needed, place it in the correct location, enable it, and fire/drop it.&lt;/li&gt;
&lt;li&gt;When it collides, disable it instead of destroying it.&lt;/li&gt;
&lt;li&gt;Repeat the process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This works great if you only need one object at a time. For example, in my scenario, only one cannon fires at a time, so I could reuse the same cannonball.&lt;/p&gt;

&lt;p&gt;But I plan to add multiple cannons and bomb drops later, so this approach wouldn’t scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Approach 2: Object Pooling&lt;/strong&gt;&lt;br&gt;
This is where pooling comes in.&lt;br&gt;
In pooling, we create a “pool” of objects at the start. When we need an object, we fetch it from the pool. When we are done using the object, we return it to the pool instead of destroying it.&lt;br&gt;
There are different ways to implement pooling in Unity. Let’s look at two common ones.&lt;/p&gt;
&lt;h2&gt;
  
  
  Example 1: Pooling with a Queue
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create a &lt;code&gt;Queue&lt;/code&gt; of the object type you want to pool.&lt;/li&gt;
&lt;li&gt;Decide the pool size (total number of objects in the pool).&lt;/li&gt;
&lt;li&gt;Instantiate that many objects at startup, do the setup, disable them, and enqueue them.&lt;/li&gt;
&lt;li&gt;When needed, dequeue an object, enable it, and use it.&lt;/li&gt;
&lt;li&gt;When done, disable it and enqueue it back.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This works well for simple pooling cases. (I used this for cannonballs — I’ve attached the example below in my project code.)&lt;/p&gt;
&lt;h2&gt;
  
  
  Example 2: Pooling with Unity’s ObjectPool (Unity 2021+)
&lt;/h2&gt;

&lt;p&gt;Unity also provides a built-in ObjectPool class. It’s more powerful and flexible.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create an &lt;code&gt;ObjectPool&lt;/code&gt; for the type you want to pool.&lt;/li&gt;
&lt;li&gt;In &lt;code&gt;Start&lt;/code&gt; or &lt;code&gt;Awake&lt;/code&gt;, set up the pool. Provide callback functions for:&lt;/li&gt;
&lt;li&gt;- Creating an object&lt;/li&gt;
&lt;li&gt;- Getting an object from the pool&lt;/li&gt;
&lt;li&gt;- Releasing an object back to the pool&lt;/li&gt;
&lt;li&gt;- Destroying an object&lt;/li&gt;
&lt;li&gt;- Setting pool parameters (capacity, max size, etc.)&lt;/li&gt;
&lt;li&gt;Call &lt;code&gt;Get()&lt;/code&gt; when you need an object.&lt;/li&gt;
&lt;li&gt;Call &lt;code&gt;Release()&lt;/code&gt; when the object’s done.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(I used this approach for bombs — example attached below.)&lt;/p&gt;
&lt;h2&gt;
  
  
  A Note on Collection Check
&lt;/h2&gt;

&lt;p&gt;When you create an &lt;code&gt;ObjectPool&lt;/code&gt;, there’s a &lt;code&gt;collectionCheck&lt;/code&gt; parameter. By default, it’s true.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If &lt;code&gt;true&lt;/code&gt;, Unity checks if the object you’re trying to release is already in the pool. If so, it throws an exception to prevent double releases.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;false&lt;/code&gt;, Unity skips the check. If you accidentally release the same object twice, it’ll silently add it again, which can cause bugs later when calling &lt;code&gt;Get()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This check adds a bit of overhead. It’s O(1), but it’s still extra work. For small pools, leaving it true is fine. For large pools with frequent releases, you might want it off — but only if you’re confident in managing releases correctly.&lt;/p&gt;
&lt;h2&gt;
  
  
  Key Takeaway:
&lt;/h2&gt;

&lt;p&gt;Instantiation and destruction are heavy operations. If you have objects that appear frequently (bullets, bombs, enemies, projectiles), don’t instantiate/destroy them every time.&lt;/p&gt;

&lt;p&gt;Instead, reuse them with enable/disable or pooling.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For simple cases, enable/disable works.&lt;/li&gt;
&lt;li&gt;For larger or frequent spawns, use pooling (Queue or Unity’s ObjectPool).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pooling won’t make your logic faster, but it will prevent FPS drops and heating on mobile devices. In my case, using pooling fixed my performance issue — from 30fps on mobile back to smooth gameplay.&lt;br&gt;
&lt;/p&gt;

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


public class CannonHandler : MonoBehaviour
{


    [SerializeField] GameObject cannonBallCopy;
    [SerializeField] GameObject cannonBallSpawnPoint;
    [SerializeField] float forceAmount = 500f;
    [SerializeField] int poolSize = 10; // total pool size
    Queue&amp;lt;GameObject&amp;gt; cannonBallPool = new Queue&amp;lt;GameObject&amp;gt;(); // pool to store objects


    void Start()
    {
        for (int i = 0; i &amp;lt; poolSize; i++)
        {
            // instantiate object
            GameObject obj = Instantiate(cannonBallCopy);


            // perform required operation [can vary based on your game]
            obj.SetActive(false);
            Rigidbody rb = obj.AddComponent&amp;lt;Rigidbody&amp;gt;();
            rb.isKinematic = true;


            // Add them to the queue
            cannonBallPool.Enqueue(obj);
        }
    }
    // This method is called by another class after given interval
    public void FireCannon()
    {
        if (cannonBallPool.Count &amp;gt; 0)
        {
            // remove from the queue
            GameObject ball = cannonBallPool.Dequeue();


            // perform required operations [can vary based on your game]
            ball.transform.position = cannonBallSpawnPoint.transform.position;
            ball.transform.rotation = Quaternion.identity;
            ball.transform.localScale = new Vector3(27f, 27f, 27f);
            ball.SetActive(true);
            Rigidbody rb = ball.GetComponent&amp;lt;Rigidbody&amp;gt;();
            rb.isKinematic = false;
            rb.velocity = Vector3.zero;
            rb.angularVelocity = Vector3.zero;
            ball.GetComponent&amp;lt;CannonBallHandler&amp;gt;().cannonHandler = this;
            Vector3 localForce = new Vector3(0f, 0f, forceAmount);
            Vector3 worldForce = transform.TransformDirection(localForce);
            rb.AddForce(worldForce, ForceMode.Impulse);
        }
    }
    // This method is called by the cannon ball itself when it comes into contact with anything.
    public void ReturnToPool(GameObject obj)
    {
        // perform required operations [can vary based on your game]
        obj.SetActive(false);
        Rigidbody rb = obj.GetComponent&amp;lt;Rigidbody&amp;gt;();
        rb.isKinematic = true;
        CannonBallHandler handler = obj.GetComponent&amp;lt;CannonBallHandler&amp;gt;();
        handler.meshRenderer.enabled = true;
        handler.sphereCollider.enabled = true;


        // Add it back to the queue
        cannonBallPool.Enqueue(obj);
    }
}

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Pool;
using UnityEngine.UIElements;

public class BombDropper : MonoBehaviour
{
    [SerializeField] GameObject bombCopy;
    [SerializeField] float delayInBombing;
    [SerializeField] GameDataSave gameDataSave;
    bool isLevelCompleted = false;

    private ObjectPool&amp;lt;GameObject&amp;gt; bombPool;

    MeshFilter meshFilter;
    Vector3[] vertices;

    void Start()
    {
        // Get mesh filter
        meshFilter = GetComponent&amp;lt;MeshFilter&amp;gt;();
        vertices = meshFilter.mesh.vertices;
        gameDataSave.E_LevelCompleted += SetIsLevelCompleted;

        // create pool and add callback functions 
        bombPool = new ObjectPool&amp;lt;GameObject&amp;gt;(
            createFunc: () =&amp;gt; Instantiate(bombCopy),
            actionOnGet: (obj) =&amp;gt; {
                obj.SetActive(true);
                //perform required set of operations [can vary based on your game]
                var handler = obj.GetComponent&amp;lt;BombHandler&amp;gt;();
                handler.ResetForPool();
                handler.pool = bombPool;
            },
            actionOnRelease: (obj) =&amp;gt; obj.SetActive(false), // Release() is called when bomb collides with anything.
            actionOnDestroy: (obj) =&amp;gt; Destroy(obj),
            collectionCheck: false,
            defaultCapacity: 10,
            maxSize: 100
        );

        StartCoroutine(DropBombs());

    }

    private void SetIsLevelCompleted()
    {
        isLevelCompleted = true;
    }
    private void OnDisable()
    {
        gameDataSave.E_LevelCompleted -= SetIsLevelCompleted;
    }

    IEnumerator DropBombs()
    {
        while (!isLevelCompleted)
        {
            int randomVertexIndex = UnityEngine.Random.Range(0, vertices.Length);
            Vector3 vertexPos = transform.TransformPoint(vertices[randomVertexIndex]);

            GameObject bomb = bombPool.Get(); // fetch the object when needed.

            bomb.transform.position = vertexPos;
            bomb.transform.rotation = Quaternion.Euler(0f, 0f, 180f);
            yield return new WaitForSeconds(delayInBombing);

        }
    }
}

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

&lt;/div&gt;



</description>
      <category>gamedev</category>
      <category>csharp</category>
      <category>unity3d</category>
      <category>programming</category>
    </item>
    <item>
      <title>How a Bi-Dictionary Simplified My Unity Inventory System</title>
      <dc:creator>Rahul Barate</dc:creator>
      <pubDate>Tue, 09 Sep 2025 16:20:40 +0000</pubDate>
      <link>https://forem.com/rahul_barate_e965377330fe/how-a-bi-dictionary-simplified-my-unity-inventory-system-2ejo</link>
      <guid>https://forem.com/rahul_barate_e965377330fe/how-a-bi-dictionary-simplified-my-unity-inventory-system-2ejo</guid>
      <description>&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt;&lt;br&gt;
In my ongoing project Last Light, I’m building an inventory system. The inventory UI has different slot sections: backpack weapons, backpack consumables, equipped weapons, equipped consumables, etc.&lt;br&gt;
The InventorySystem handles the data and logic, while InventoryUIController handles the UI. To make them work together, I initially used a dictionary that maps slot sections to item types. This works when displaying items from the system to the UI. But the problem shows up in reverse — when the player clicks a slot, I need to know the section type. With a normal dictionary, I’d have to traverse the entire dictionary to find the type, which isn’t efficient.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;br&gt;
This is where a Bi-Dictionary comes in.&lt;br&gt;
A Bi-Dictionary is a data structure that supports two-way lookups: you can find a value from a key, and a key from a value — both in O(1) time. Most programming languages don’t provide this out of the box, so I wrote my own.&lt;br&gt;
The idea is simple: maintain two dictionaries internally — one mapping key → value, and another mapping value → key. Then, create methods like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GetValue(key) → returns the value.&lt;/li&gt;
&lt;li&gt;GetKey(value) → returns the key.&lt;/li&gt;
&lt;li&gt;Add(key, value) and Remove(key/value) to keep both dictionaries in sync.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example Use Cases:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inventory System (my case): Helps map item types to UI slots and back.&lt;/li&gt;
&lt;li&gt;Action ↔ Sound Effect: Example: GunshotAction ↔ GunshotSound. One script can play the sound given the action, another can detect the sound and resolve it back to the action.&lt;/li&gt;
&lt;li&gt;Localization: Word ↔ Translation mappings (when you need to resolve both ways).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key takeaway:&lt;/strong&gt;&lt;br&gt;
A Bi-Dictionary is a handy data structure for cases where you need fast, two-way lookups. Many developers don’t know about it because it’s not built into most languages, but it can save time and complexity in the right scenarios.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Collections.Generic;

public class BiDictionary&amp;lt;TKey, TValue&amp;gt;
{
    private Dictionary&amp;lt;TKey, TValue&amp;gt; keyToValue = new Dictionary&amp;lt;TKey, TValue&amp;gt;();
    private Dictionary&amp;lt;TValue, TKey&amp;gt; valueToKey = new Dictionary&amp;lt;TValue, TKey&amp;gt;();

    public void Add(TKey key, TValue value)
    {
        if (keyToValue.ContainsKey(key) || valueToKey.ContainsKey(value))
            throw new ArgumentException("Duplicate key or value.");

        keyToValue.Add(key, value);
        valueToKey.Add(value, key);
    }

    public TValue GetValue(TKey key)
    {
        return keyToValue[key];
    }

    public TKey GetKey(TValue value)
    {
        return valueToKey[value];
    }

    public bool TryGetValue(TKey key, out TValue value)
    {
        return keyToValue.TryGetValue(key, out value);
    }

    public bool TryGetKey(TValue value, out TKey key)
    {
        return valueToKey.TryGetValue(value, out key);
    }

    public bool RemoveByKey(TKey key)
    {
        if (!keyToValue.TryGetValue(key, out var value)) return false;
        keyToValue.Remove(key);
        valueToKey.Remove(value);
        return true;
    }

    public bool RemoveByValue(TValue value)
    {
        if (!valueToKey.TryGetValue(value, out var key)) return false;
        valueToKey.Remove(value);
        keyToValue.Remove(key);
        return true;
    }
}

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

&lt;/div&gt;



</description>
      <category>unity3d</category>
      <category>csharp</category>
      <category>gamedev</category>
      <category>programming</category>
    </item>
    <item>
      <title>When You Have a Golden Hammer, Everything Looks Like a Nail</title>
      <dc:creator>Rahul Barate</dc:creator>
      <pubDate>Tue, 02 Sep 2025 05:42:10 +0000</pubDate>
      <link>https://forem.com/rahul_barate_e965377330fe/when-you-have-a-golden-hammer-everything-looks-like-a-nail-4nh5</link>
      <guid>https://forem.com/rahul_barate_e965377330fe/when-you-have-a-golden-hammer-everything-looks-like-a-nail-4nh5</guid>
      <description>&lt;p&gt;A while ago I came across this awesome tool called Assembly Definitions from Unity3D. As indie developers, we love finding new tools that promise to save time. Unity’s Assembly Definition sounded like a game-changer when I first discovered it. But after trying it in a small project, I realized: just because a tool is powerful doesn’t mean it’s right for every situation.&lt;/p&gt;

&lt;p&gt;Assembly Definitions allow you to split your scripts into multiple assemblies for modularity and faster compile times. First you separate your scripts into multiple folders like Player, NPCs, Environment, and create Assembly Definition for each. Now, when you change a script in one folder, Unity only recompiles that assembly instead of the entire project. This saves a lot of time—if your project is large enough.&lt;/p&gt;

&lt;p&gt;Now you might be thinking, isn’t that such a wonderful feature? Yes, you’re right. It is a wonderful feature but only if you use it right. The catch is Assembly Definitions enforce a strict rule: no circular dependencies. For example, if Player Assembly references NPCs Assembly, NPCs Assembly cannot reference Player Assembly. This helps prevent spaghetti code, but in small projects, it can slow development. I tried solving this using C# events but tracking how events flowed through my project quickly became a nightmare.”&lt;/p&gt;

&lt;p&gt;I used Assembly Definitions in my small project, which barely had 10 to 15 scripts. The compile time improvement was so small I barely noticed it. And just to dodge that Circular Dependency issue, I used to many Events that after a while it became so painful for me to backtrack how the control is flowing through my scripts. I eventually realized Assembly Definitions are great for large, team-driven projects, but unnecessary for small solo projects. So, from my experience, I’ll state the Pros and Cons of Assembly Definitions and discuss when I think they are useful and when to avoid them.&lt;/p&gt;

&lt;p&gt;Pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster compile times in large projects.&lt;/li&gt;
&lt;li&gt;Better modularity and maintainability.&lt;/li&gt;
&lt;li&gt;Useful for platform-specific builds.&lt;/li&gt;
&lt;li&gt;Helps avoid tightly coupled, spaghetti code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No runtime performance improvement.&lt;/li&gt;
&lt;li&gt;Adds complexity to small projects.&lt;/li&gt;
&lt;li&gt;Circular dependency restrictions require careful planning.&lt;/li&gt;
&lt;li&gt;When to Use Assembly Definitions:&lt;/li&gt;
&lt;li&gt;Large projects with 1,000+ scripts.&lt;/li&gt;
&lt;li&gt;Multiple teams working on different modules.&lt;/li&gt;
&lt;li&gt;Platform-specific builds or reusable systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When to Use Assembly Definitions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large projects with 1,000+ scripts.&lt;/li&gt;
&lt;li&gt;Multiple teams working on different modules.&lt;/li&gt;
&lt;li&gt;Platform-specific builds or reusable systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When to Avoid:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Small, solo projects.&lt;/li&gt;
&lt;li&gt;Projects with tightly interconnected systems.&lt;/li&gt;
&lt;li&gt;When compile times are already fast.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Conclusion:&lt;br&gt;
Assembly Definitions are powerful, but like any tool, they solve specific problems. When you see a good feature, that doesn’t mean you need to immediately start using it in your project. Always weigh the pros and cons before adopting a new feature—because when you have a golden hammer, not everything is a nail.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>unity3d</category>
      <category>beginners</category>
      <category>csharp</category>
    </item>
  </channel>
</rss>
