<?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: Trel</title>
    <description>The latest articles on DEV Community by Trel (@tfonnes).</description>
    <link>https://dev.to/tfonnes</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%2F1145480%2F508d3a96-df4f-4daa-9963-662abf0e586c.jpg</url>
      <title>DEV Community: Trel</title>
      <link>https://dev.to/tfonnes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tfonnes"/>
    <language>en</language>
    <item>
      <title>How I Keep My Animator Controllers Organized</title>
      <dc:creator>Trel</dc:creator>
      <pubDate>Wed, 04 Oct 2023 02:29:12 +0000</pubDate>
      <link>https://dev.to/tfonnes/how-i-keep-my-animator-controllers-organized-3pb3</link>
      <guid>https://dev.to/tfonnes/how-i-keep-my-animator-controllers-organized-3pb3</guid>
      <description>&lt;p&gt;The Unity Animator Controller (AC) is often depicted as a complex web of connections between state transitions, making it challenging to manage efficiently. While various solutions exist for this problem, I want to share an approach that has proven effective in my projects. To illustrate this, let's begin by examining the Animator Controller used for my player character:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---fsG_HXe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t8e8wetea8kk95uep4s9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---fsG_HXe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t8e8wetea8kk95uep4s9.png" alt="Image description" width="672" height="423"&gt;&lt;/a&gt;&lt;br&gt;
As you can see, it's simple, well-organized, and each animator state is responsible only for what's necessary for its individual transitions and behaviors. In this article, I'll provide a breakdown of this approach and share insights into keeping your Animator Controllers clean and manageable.&lt;br&gt;
&lt;strong&gt;Transition Management:&lt;/strong&gt; First, this design effectively utilizes enter and exit nodes in the AC. Each animation state transition enters and exits through the respective nodes. Consider the "Move" state as an example. Without delving into the specifics of the state pattern used for the Player Class, when each class is entered via code, it signals the AC with the relevant parameter for entering the corresponding animation state.&lt;br&gt;
For instance, when player input registers a value greater than or less than 0, the AC receives this information and sets a boolean value to true, transitioning to the "Move" state. The transition involves exiting the "Idle" animation state through the exit node, and the enter node detects that the "move" parameter is now true, allowing the "Move" animation state to begin.&lt;br&gt;
This process applies to every animation state, with Player State classes being responsible for sending information to the AC, which in turn adjusts its states accordingly. Each animation state only needs to be aware of its specific parameters/conditions for entering and exiting states, minimizing complexity while adhering to the Player State Pattern.&lt;br&gt;
&lt;strong&gt;Blend Trees:&lt;/strong&gt; Blend Trees can be a complex topic, but they offer extensive possibilities for animation management. Suppose you have a move state in an 8-directional 2D game, each direction requiring a different animation. Instead of creating eight separate animation states, you can employ a Blend Tree within a single "Move" animation state.&lt;br&gt;
Once the "Move" state is entered, the Blend Tree takes charge of selecting the appropriate move animation based on X and Y input parameters received from the Move State class and Player Input class. For example, if the X value is 1 and the Y value is 1, the "Walk Up" animation will play. This approach keeps the AC organized and reduces the complexity of animation transitions for each state.&lt;br&gt;
As a side note, in 2D animations, you can further simplify the process by animating only in one direction on the x-axis and implementing a "Flip()" function within your movement class to flip the game object and animations when x-input is less than 0.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M749gMa8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5jfu5b9u9yp1ticuk01o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M749gMa8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5jfu5b9u9yp1ticuk01o.png" alt="Image description" width="697" height="284"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Handling Attacks:&lt;/strong&gt; You may have noticed that my AC doesn't have a dedicated state for attacks, even though this player character possesses multiple attack options. To manage this, I utilize an "Empty" animation state with a unique condition for entry: the attack parameter/boolean must be true.&lt;br&gt;
This primary Animator Controller collaborates with individual attack Animator Controllers, each with its own set of unique parameters. This approach not only enhances organization and clarity but also facilitates advanced and customized attack functionalities. For instance, you can create an attack Animator Controller that can receive a 'hold' input parameter for charged shots or a 'counter' parameter for combo moves, tailoring each controller to specific attack needs.&lt;br&gt;
Creating separate Animator Controllers for each attack also streamlines the implementation of a weapon swapping system. The required ACs for shooting a gun, swinging a sword, using a shield, or wielding a bow can be referenced within a scriptable object and swapped in and out of the 'weapon' game object as needed. Additionally, this approach allows you to use the same AC for different weapons, displaying visually distinct weapon sprites for each weapon type while maintaining consistent animations.&lt;br&gt;
While explaining my weapon systems and components would require its own article, I hope this sheds light on the efficiency of my Animator Controller design. Unity's Animator Controller, when used in conjunction with game objects and MonoBehaviour classes, offers impressive functionality. It can also leverage animation events and callback functions, providing a wealth of possibilities for game development.&lt;br&gt;
In conclusion, organizing Animator Controllers effectively is crucial for managing complex animations in Unity. By following the principles I've outlined above, you can create clean, organized Animator Controllers that enhance the visual understanding and functionality of your game. Unity's Animator Controller is a powerful tool when used thoughtfully, and it can significantly contribute to the success of your game development projects.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>animation</category>
      <category>csharp</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Crafting an Item-Spawn System</title>
      <dc:creator>Trel</dc:creator>
      <pubDate>Fri, 15 Sep 2023 19:28:46 +0000</pubDate>
      <link>https://dev.to/tfonnes/crafting-an-item-spawn-system-2j0n</link>
      <guid>https://dev.to/tfonnes/crafting-an-item-spawn-system-2j0n</guid>
      <description>&lt;p&gt;In today's discussion, I'm excited to shed light on a fascinating system within my game. Now, I'm still considering ways this can be refactored,so bear with me as I share something functional, understandable, and pretty cool.&lt;/p&gt;

&lt;p&gt;This system encompasses several intriguing topics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Abstraction&lt;/li&gt;
&lt;li&gt;Concrete interfaces&lt;/li&gt;
&lt;li&gt;Singleton pattern&lt;/li&gt;
&lt;li&gt;Scriptable Objects&lt;/li&gt;
&lt;li&gt;Object Pooling&lt;/li&gt;
&lt;li&gt;A mystery topic
(Don't worry, we'll go through it together 😄)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One day, while taking a break from development, I decided to embark on a playthrough of the classic "Legend of Zelda." Since my current project also involves a top-down 2D game, I thought revisiting this iconic game might provide some inspiration. And indeed, it did! As I slashed, bombed, and shot my way through enemies, I noticed that enemies had a chance to drop certain items, but not all the time and not at equal rates. This concept of random item drops reminded me of other Zelda titles and how they would spawn items when, for instance, you broke a pot or cut down grass. You never knew when a green or red rupee might appear. This got me thinking: How could I implement a similar system with comparable behavior in my own game?&lt;/p&gt;

&lt;p&gt;I already had numerous items in my game, each with varying values. So, I decided to start by organizing which items had a chance to spawn and how I could categorize them into different tiers of worth. To achieve this, I employed Scriptable Objects as a means to store data that identified items as Basic, Rare, or Extra Rare. While these labels may sound straightforward, they served as a reasonable naming convention. Additionally, these Scriptable Objects contained references to the items themselves and the spawn rates for each category. This data would later be used by the concrete interface and the ItemSpawnSystem class, respectively.&lt;/p&gt;

&lt;p&gt;Once I had assigned the necessary information within the Scriptable Objects, I created the ItemSpawnSystem class. This class took on the responsibility of managing the data and determining which category of item had a chance to spawn. Now, I'm aware that the Singleton Pattern often carries a less-than-favorable reputation due to potential misuse. However, I firmly believe that it's a suitable choice for classes with a single responsibility that only require one instance in the game. In my eyes, the ItemSpawnSystem fits this description perfectly. It serves as a conduit for receiving, evaluating, and transmitting information, regardless of which game element provides that data. Multiple objects need access to a single instance of it, rather than creating their instances and potentially causing null reference exceptions. Hence, I implemented it as a Singleton.&lt;/p&gt;

&lt;p&gt;However, I adhere to a coding rule I've set for myself: when I have a Singleton or any public reference, I aim to have one script or class mediating what is sent to it. This practice simplifies debugging. In this case, my Game Manager seemed like a natural fit. It already serves as a hub for various systems in my project, making it an ideal candidate. So, after hours of contemplation, I designated the Game Manager as the access point for objects to interact with the Item Spawn system.&lt;/p&gt;

&lt;p&gt;Now, let's dive into the ItemSpawnSystem class's actual functionality. Imagine an enemy has been defeated. As it enters its 'dying' state, just before it's destroyed, deactivated, or returned to its object pool, it sends a call to the Game Manager and ItemSpawnSystem. This call includes its transform.position and the type of item it can potentially spawn, such as Basic, Rare, or Extra Rare. The ItemSpawnSystem uses this information, along with data from the Scriptable Objects, to determine whether an item will spawn. It employs some probability calculations. If the odds align, it sends the information for a Basic Item, for instance, to the concrete interface responsible for spawning. This is where the concept of abstraction enters the picture.&lt;/p&gt;

&lt;p&gt;Interfaces are a common tool for abstraction, but considering the Interface Segregation Principle, we find that having a 'fat' interface containing information for all three item spawn categories forces each respective client to implement what it doesn't need. So, this is where concrete interfaces come into play. These interfaces derive from a common interface, implementing the required functionality, akin to a contract. Now, the specific behavior is divided into three different concrete interfaces, one for each category. This arrangement ensures that each interface is only responsible for its specific implementation. It results in a cleaner and more maintainable solution, as opposed to a monolithic interface script where it's challenging to discern the role of each part.&lt;/p&gt;

&lt;p&gt;Let's delve deeper into what these concrete interfaces do using the example of a Basic Item. Since a 'dying' enemy called for the Basic item, the interface that receives this information and executes the behavior is the IBasicItemSpawn. When active, it utilizes Random.Range to generate an integer. This integer serves as an index to retrieve the corresponding item from the BasicItems list via the Scriptable Object mentioned earlier. The interface scans this list and returns the item matching the result of the Random.Range. So, there are initial odds for reaching this point and another set of odds for determining which item within that category will spawn. The interface then delivers the stored object, which matches the index number, to a SpawnedItemsObjectPool script. This is where the interface proves its worth. The SpawnedItemsObjectPool implements the interface, accepts the information, and activates the designated object at the enemy's 'dying' transform.position. Voila! The item spawns.&lt;/p&gt;

&lt;p&gt;In summary, the system begins with a call from the 'dying' enemy. The Game Manager facilitates this call and selects the item category with a chance to spawn. The ItemSpawnSystem class receives this information, processes it, and passes it to the interface. The concrete interfaces, which receive information from the item spawning class and return objects based on identifiers, provides that information to the item object pool and that item is spawned based on the specific criteria.&lt;/p&gt;

&lt;p&gt;Well, that's about it, and I hope this description has unraveled the mystery topic for you - it's the Factory Method Pattern.&lt;/p&gt;

&lt;p&gt;As always, thank you for reading. I've been thrilled with the versatility of this system. I am contemplating refactoring the contents of the Scriptable Object and the function used in the interface for better clarity. Nevertheless, it marks a promising first implementation of an item spawn system.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Game Dev and AI: How ChatGPT Has Helped</title>
      <dc:creator>Trel</dc:creator>
      <pubDate>Fri, 25 Aug 2023 20:43:57 +0000</pubDate>
      <link>https://dev.to/tfonnes/game-dev-and-ai-how-chatgpt-has-helped-g3m</link>
      <guid>https://dev.to/tfonnes/game-dev-and-ai-how-chatgpt-has-helped-g3m</guid>
      <description>&lt;p&gt;Before we begin, let me make a disclaimer. This post isn't about integrating AI into games, crafting your AI system, or contemplating how AI will replace developer jobs and lead us to a WALL-E-esque future of blob people on a space station, as depicted in Pixar's WALL-E. Instead, I'm here to share personal thoughts and experiences regarding my use of AI, specifically ChatGPT (Chat), as a tool to assist with my projects and expand my understanding of complex concepts. Put shortly, this is not an exploration of grand AI narratives. Now, let's dive into things.&lt;/p&gt;

&lt;p&gt;When ChatGPT entered the scene, I already had a year's worth of coding experience under my belt. While I was still very much a beginner, I was diligently crafting gameplay features within a solo project in Unity. However, my journey with Chat didn't start until several months later. Once I embraced it as a tool, I was pleasantly surprised by its ability not only to comprehend but also to explain concepts at a level that resonated with me, effectively fostering a dialogue for learning.&lt;/p&gt;

&lt;p&gt;My learning journey prior to Chat mostly involved sifting through outdated forums for solutions and scouring YouTube for valuable insights from leaders in the Unity development community. Let me step onto a soapbox for a moment. Personally, I harbor reservations about forums. Please don't brandish pitchforks if you're an ardent forum enthusiast; this is just my take. I often find forums to be less helpful. Typically, frustrated individuals post their problems, already upset by their inability to locate a solution. Their code tends to lack clarity, making it challenging for me to determine if their issues relate to mine. Furthermore, while some responders are genuinely helpful, others adopt a condescending tone, morphing the problem-solving process into a "coding prowess showdown" with a frustrated developer. To put it succinctly, scrolling through forums is time-consuming, distracting, exhausting, and seldom yields useful insights—especially when grappling with the development of unique systems. But I digress; the idea of spending time on a forum merely makes me cringe.&lt;/p&gt;

&lt;p&gt;On the other hand, YouTube has proven more beneficial in my experience. Nonetheless, barring a few exceptions, finding optimal examples of advanced and in-depth concepts in Unity, game development, and C# remains challenging. This is especially true when these concepts are presented in a manner that steps fully into technical jargon and fails to employ relatable, "real-world" examples. I recognize the significance of technical jargon, but it's important to acknowledge that it can be a stumbling block for newcomers attempting self-teaching. To summarize, while I could locate explanations suitable for beginners concerning basic concepts, I struggled to find explanations at the beginner/intermediate level for more advanced concepts. Moreover, comprehensive explanations of concepts on YouTube are often scarce, as most content creators gravitate towards quick-fix solutions ready for implementation in their own projects. So, on one hand you have videos with millions of views showing how to implement a single feature. Then on the other hand you have a video with a few thousand views that is so complex and bland that I’d rather be sitting in an economics class led by Ben Stein.&lt;br&gt;
To cut to the chase, my early learning primarily involved watching videos, applying the concepts to my project, and subsequently dissecting and tinkering with them until I grasped their essence. This approach, while serviceable, yielded a somewhat chaotic project—littered with disorganized functionalities that drove me crazy. I may or may not have closed my laptop a bit too firmly in these instances, and caused a permanent issue with the screen... Nevertheless, I yearned for a firmer grasp of architecture, design patterns, and best practices.&lt;/p&gt;

&lt;p&gt;Coming from an educational background and holding a Master's of Science in Counseling, I understood the process of learning and knowledge advancement. However, I hadn't fully committed to elevating my game development education to the same level. That is, until the persistent itch to learn more got the better of me. I enrolled in a bootcamp, attended game development conferences, and crystallized my understanding of what I needed to learn. And then came ChatGPT, seemingly timed to align with my increasing awareness of coding intricacies. Had Chat entered the picture at the outset of my journey, I might have grown overly dependent on it. If it had appeared after a decade of experience, I might have stubbornly refrained from leveraging it, adopting the common stance of "I had to learn the hard way, so others should too." However, at this juncture, I was grasping design patterns, understanding their purpose, and acquainting myself with technical terms that previously befuddled and discouraged me. My knowledge deepened on Unity's best practices and SOLID principles of object-oriented programming, and I was ready to put theory into action. Admittedly, I could have absorbed these lessons without Chat's aid, but the speed at which I assimilated, implemented, and expanded upon them took me by surprise.&lt;br&gt;
So, how did I harness Chat to achieve this feat? Allow me to preface by stating that I don't advocate asking Chat to generate code and then mindlessly pasting it into my project. Even at my skill level, I can discern that much of the code it produces is sub-optimal and unreliable. In fact, I rarely take code snippets directly from Chat and incorporate them into my project. Instead, I employ Chat as a mentor, a guide, an intellectual sparring partner with whom I can engage. As a solo developer, this resource has proven invaluable. It grants me insights into design patterns, coding conventions, Unity error messages, and even previously unknown Unity features. Now, this wealth of information lies quite literally at my fingertips. In essence, Chat has become my "learning assistant." While I often lament the years spent in a career I ultimately dislike, Chat has expedited my information-seeking capabilities and managed to fill some of the void left by the time that felt wasted. I'm appreciative of the knowledge and enamored with the ability to learn, and it's this facet of AI that truly delights me.&lt;/p&gt;

&lt;p&gt;To illustrate with an example, I frequently share my architectural plans for a system in my project with Chat. Subsequently, I ask for its feedback. I pose questions like, "Does this adhere to X design pattern?" or "Do you have any suggestions for enhancing adherence to X design pattern?" and "How might I manage this class's dependence on another class?" While the solutions it offers are occasionally flawed, I then outline my concerns about a particular solution, prompting Chat to produce a revised suggestion. This iterative exchange mirrors the experience of collaborating with a project teammate, a dynamic that has led to numerous "aha!" moments of comprehension or discovery. In education, it resembles the moment when, through a back-and-forth dialogue, a student experiences an "aha!" moment—an instance of illumination—grasping and being able to apply a concept effectively.&lt;/p&gt;

&lt;p&gt;As alluded to earlier, this post doesn't delve into AI's impending transformations. Rather, it's an account of my experiences with AI as they stand. AI is not the panacea for all programming woes, capable of transforming any ten-year-old with an idea into a master game developer. However, I firmly believe that AI's potential as a potent modern-day learning tool should not be disregarded. Perhaps I'm dwelling on this aspect too affectionately, a reflection of my educational background comes to mind and considers the individuals who aspire greater purpose, but find themselves limited by socioeconomic status or geographic location. For such individuals, Chat holds the power to dismantle barriers to learning. Perhaps that's my educator's sensibility talking, but I hope that the next time an experienced developer scoffs at the use of AI, they pause to contemplate the impact of informational access on those who lack the privilege of a traditional education due to life's circumstances. And I'm not exclusively referring to programming education; throughout history, learning has revolved around absorbing accurate information from individuals who've conducted research, established principles, and made them accessible. AI assumes the mantle of the third aspect—accessibility—and compresses a wealth of knowledge into a condensed, personalized, and comprehensible format.&lt;/p&gt;

&lt;p&gt;As always, thanks for your time and attention. Keep focused in learning, aim your sights on growth, stay persistent, and achieve your learning goals. &lt;/p&gt;

</description>
      <category>ai</category>
      <category>unity3d</category>
      <category>chatgpt</category>
      <category>learning</category>
    </item>
    <item>
      <title>Basic Use of Interfaces in Unity</title>
      <dc:creator>Trel</dc:creator>
      <pubDate>Fri, 25 Aug 2023 14:41:48 +0000</pubDate>
      <link>https://dev.to/tfonnes/basic-use-of-interfaces-in-unity-pdb</link>
      <guid>https://dev.to/tfonnes/basic-use-of-interfaces-in-unity-pdb</guid>
      <description>&lt;p&gt;&lt;strong&gt;Interfaces&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you've followed my previous blog posts, you'll know that I prefer practical explanations over diving into technical jargon. While there's certainly a place for technical terms, I believe in presenting concepts in a relatable manner, providing a more approachable first experience with the subject matter.&lt;br&gt;&lt;br&gt;
In this article, I'll discuss a real-world implementation of interfaces in my project and share my thoughts on using them. This approach should provide a more realistic perspective than the typical online C# examples that often involve finance or accounting scenarios. Seriously, why are the examples always about finance? But I digress, let's jump in!&lt;/p&gt;

&lt;p&gt;What is an Interface?&lt;/p&gt;

&lt;p&gt;In the context of Unity and C#, an interface is a programming construct that establishes a contract for classes to follow. It outlines a specific set of methods, properties, and events that implementing classes must supply. Interfaces enable the creation of standardized behaviors that unrelated classes can share, promoting code consistency and modularity.&lt;/p&gt;

&lt;p&gt;Let's simplify this: Picture two classes that need to communicate without direct awareness of each other. They can do so through an interface. In fact, more than two classes can interact by agreeing to implement the same interface or "contract," but we'll just focus on the two for now.&lt;/p&gt;

&lt;p&gt;This concept is less complicated than it may sound. Consider this example: Imagine a player character in a game. Pressing the A button should allow the character to interact with various objects in the game world, like chests, NPCs, doors, or save points. You've probably even seen games with a dedicated "Interact" button. Think of Kingdom Hearts 2 and its use of the triangle button (yes, I was an adolescent in the 2000s). When near "interactable" objects, like a chest, pressing this button lets the player interact with or open the chest. We can achieve something similar using interfaces in Unity.&lt;/p&gt;

&lt;p&gt;Creating and Implementing Interfaces&lt;/p&gt;

&lt;p&gt;How is this accomplished? Start by defining an interface. Continuing with the "interactable" example, create a new C# script (or add it within your chosen namespace). The script should resemble this:&lt;/p&gt;

&lt;p&gt;public interface IInteractable&lt;br&gt;
{&lt;br&gt;
    // Declare functions, variables, etc. here //for implementing classes to use.&lt;br&gt;
    // This is the 'contract' we discussed //earlier.&lt;br&gt;
     public void Interact();&lt;br&gt;
}&lt;br&gt;
Remember to follow SOLID principles when implementing interfaces. Specifically, adhere to the 'I' in SOLID, which stands for the Interface Segregation Principle. This principle advises against overcrowding interfaces with functions that aren't required by implementing classes. Smaller, more focused interfaces are generally more effective. In the case of IInteractable, include only what's necessary for interaction with any object in your project.&lt;/p&gt;

&lt;p&gt;Implementing the Interface&lt;/p&gt;

&lt;p&gt;Now let's return to our example. We have an interface but can't use it yet. Let's say we want the player to be able to click on a chest and interact with it when the player character is within the chest's collider.&lt;/p&gt;

&lt;p&gt;Ensure that your player's setup allows it to look for the implementation of IInteractable" when a collider is detected. In my projects, I incorporate an "interact state" where the player enters upon pressing the interact button while detecting a collider with the "Interactable" layer tag. Within this state, a function runs to check if the object implements IInteractable. The function might look like this:&lt;/p&gt;

&lt;p&gt;if (HitsToInteract) // Collider found by the //raycast&lt;br&gt;
{&lt;br&gt;
    // Obtain the implementation of the //interface and trigger the interaction.&lt;br&gt;
    HitsToInteract.collider.GetComponent().Interact();&lt;br&gt;
}&lt;br&gt;
An alternative approach that handles null references better could look like this:&lt;/p&gt;

&lt;p&gt;if (HitsToInteract.TryGetComponent(out IInteractable interactable))&lt;br&gt;
{&lt;br&gt;
    interactable.Interact();&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Now that we have the "invoker's" perspective, let's explore the "client's" side.&lt;/p&gt;

&lt;p&gt;Assuming we have a class named Chest, it should implement IInteractable and fulfill the contract like this:&lt;/p&gt;

&lt;p&gt;public class Chest : MonoBehaviour, IInteractable&lt;br&gt;
{&lt;br&gt;
    public void Interact()//The function that &lt;br&gt;
                     //fulfills the "contract"&lt;br&gt;
    {&lt;br&gt;
        // Implement logic for interacting //with the chest, e.g., opening it.&lt;br&gt;
        OpenChest();&lt;br&gt;
    }&lt;br&gt;
}&lt;br&gt;
That's pretty much it! Ensure that:&lt;/p&gt;

&lt;p&gt;The interface is defined.&lt;br&gt;
The "invoker" (in this case, the player) effectively calls it.&lt;br&gt;
The "client" (e.g., the chest) implements the interface and fulfills its contract, providing the logic for the desired behavior (like opening the chest).&lt;br&gt;
During runtime, when the player detects an interactable object, the game checks for the interface implementation, triggering the associated functionality. This process effectively opens the chest or performs the intended action. Now, with this same process, you can simply create more clients for the player to interact with.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Going Deeper: Abstracting Interfaces&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
While interfaces provide a level of abstraction, you can take it further by creating an abstract interface. This allows you to create concrete interfaces derived from the abstract one. This approach enables similar interface contracts with more specific details. For instance, in my item spawn system, I have an abstract interface named ISpawnable. Derived from it are IBasicSpawn, IRareSpawn, and IExtraRareSpawn. This segmentation facilitates clearer and more consistent functionality.&lt;/p&gt;

&lt;p&gt;Thanks for reading! I hope this basic implementation provides a clear example of using interfaces in Unity.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>interfacesegregation</category>
    </item>
    <item>
      <title>Working on the BEST Projectile System for my project... so far :)</title>
      <dc:creator>Trel</dc:creator>
      <pubDate>Thu, 24 Aug 2023 17:00:11 +0000</pubDate>
      <link>https://dev.to/tfonnes/working-on-the-best-projectile-system-for-my-project-so-far--3o3o</link>
      <guid>https://dev.to/tfonnes/working-on-the-best-projectile-system-for-my-project-so-far--3o3o</guid>
      <description>&lt;p&gt;&lt;strong&gt;PROJECTILES&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In today’s post, I want to discuss the way I handle projectiles in my current project. In the past, creating a projectile system that wasn’t tightly coupled to the game object using them was challenging. After some experimentation, I developed an initial system comprised of:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Input Handler&lt;br&gt;
PlayerShootState&lt;br&gt;
Serialized References to the desired projectiles&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While functional, this approach had limitations in terms of flexibility and unnecessary dependencies on classes that didn't require knowledge about projectiles. I was looking for a more adaptable solution, especially since I intended to add projectiles with different types and behaviors.&lt;/p&gt;

&lt;p&gt;Another challenge arose from the fact that in my game design, players could shoot projectiles repeatedly, requiring frequent instantiation of objects during runtime. The most straightforward solution to this is Object Pooling.&lt;/p&gt;

&lt;p&gt;Object Pooling is a topic that deserves its own dedicated discussion, but grasping its basic purpose and functionality is essential to understanding how my projectile system works. Essentially, the object pooling script takes references to my projectile prefabs. It uses adjustable parameters to determine the pool size, i.e., how many instances of a specific projectile prefab will be created at runtime and stored in respective lists. The script includes functionality for 'un-pooling' projectiles, although this function remains private and inaccessible from elsewhere – an interesting aspect of this system.&lt;/p&gt;

&lt;p&gt;Before we continue, I'd like to emphasize that I have various types of projectiles – currently, I have eight different projectiles, each with unique behaviors. My system became more complex when I encountered another issue. For an independent projectile system, how could the Object Pool identify which projectile to 'unpool'? The solution lay in using an identifier paired with a specific projectile. I utilized an Enum as the identifier – a list of all projectile varieties. I created a dictionary associating these Enum types with projectile prefabs. In the Object Pooling script, using the inspector, I assigned an enum, creating a key-value pairing stored in the dictionary for referencing. Instead of retrieving pooled objects from a list, the dictionary allows retrieval by passing in the corresponding enum. This improved the approachability of the pooled projectile objects by the systems needing access.&lt;/p&gt;

&lt;p&gt;However, a question remained: What component would access the Object Pool? I realized that not only the player but also enemies, hazards, and bosses needed to shoot projectiles and might require access to this system. To address this, I kept the Dependency Inversion Principle (DIP) in mind. I required abstraction to ensure that high-level modules requiring a projectile weren't dependent on pooled projectiles or the Object Pooling class. After careful consideration, I introduced a ProjectileHandler class. This class holds functions that can be triggered wherever needed through an observer pattern – primarily, in the Player Weapon class. The Weapon class triggers an event that sends an identifying enum to the Object Pool script to 'un-pool' the corresponding projectile. A second event is raised, passing identifying information such as transform.position, damage amount, Vector2 direction, speed, or any unique data the weapon requires for desired behaviors. The actual projectiles subscribe to this second event.&lt;/p&gt;

&lt;p&gt;While this might appear to result in chaotic projectiles spawning in random directions across the game world, pay attention to the sequence of events and the order in which the ProjectileHandler executes them:&lt;/p&gt;

&lt;p&gt;The Weapon class raises the event to 'un-pool' a specific projectile.&lt;br&gt;
The identifying enum is passed as an argument to this event.&lt;br&gt;
The Object Pooling script, via the ProjectileHandler, receives this information and 'un-pools' the projectile by searching the dictionary and returning the first inactive projectile with that enum (key).&lt;br&gt;
*Note: The pooling script can also create new projectiles if the current pool has no inactive ones.&lt;/p&gt;

&lt;p&gt;Once the correct projectile is un-pooled, the specific projectile class subscribes to the second event raised by the Weapon class. This event contains arguments with behavior-specific data required by the projectile. The projectile uses this data to spawn at the Weapon's location, with a direction matching the Weapon's aim, and other necessary data for desired behavior.&lt;/p&gt;

&lt;p&gt;This process reproduces when the player shoots again, changes weapons, or changes positions. The event is raised with the latest information, ensuring consistent functionality.&lt;/p&gt;

&lt;p&gt;And that's essentially how it works! My system now comprises a Weapon class, an Object Pooling class, a Projectile class, and a ProjectileHandler – all collaborating while remaining separate. Abstraction through the ProjectileHandler makes this possible, providing a channel for essential information to observers. I'm pleased with the evolution of this system; it's modular, decoupled, and capable of expanding to different weapon classes, as well as accommodating new projectile types. Setting it up in the inspector is relatively straightforward, and the use of enums offers clarity and a visual representation of the used projectile.&lt;/p&gt;

&lt;p&gt;Further enhancements are possible, especially for more intricate weapon behaviors or features. One idea I've been considering, which could be valuable for designing boss fights, is combining this system with a command pattern. I'm brainstorming ways the Projectile Handler can receive requests from a boss's specific attack or weapon state based on player behavior. It would store these requests and signal to execute them in sequence when a player meets a certain condition. This approach could create a sequence of different attacks based on player behavior, adding depth to boss battles. Details need refinement, but it holds promise for interesting encounters.&lt;/p&gt;

&lt;p&gt;As always, thank you for reading. If you're just starting out and looking to architect a more optimal design for your projectiles, I hope the insights from my own experience can inspire some creative ideas.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>csharp</category>
      <category>gamedev</category>
      <category>programming</category>
    </item>
    <item>
      <title>State Machine Basics: My Playable Character's State Pattern</title>
      <dc:creator>Trel</dc:creator>
      <pubDate>Thu, 24 Aug 2023 16:36:00 +0000</pubDate>
      <link>https://dev.to/tfonnes/state-machine-basics-my-player-state-pattern-3adm</link>
      <guid>https://dev.to/tfonnes/state-machine-basics-my-player-state-pattern-3adm</guid>
      <description>&lt;p&gt;State Machine Pattern&lt;/p&gt;

&lt;p&gt;In the world of game development, creating lifelike and interactive experiences often requires managing complex behaviors and transitions. Enter the State Machine pattern, a powerful architectural concept that offers a structured approach to handling dynamic behavior in Unity using the versatile capabilities of C#. A well-implemented State Machine empowers your game objects to seamlessly shift between different states, responding intelligently to player input, environmental changes, and internal triggers. In this article, I’ll do my best to describe my understanding of the State Machine Pattern and how I’ve implemented it in my own projects. By the end, hopefully, you'll have a good idea of my implementation and perhaps be able to draw on some of its ideas.&lt;/p&gt;

&lt;p&gt;First, I must acknowledge the many great developers on YouTube who are leading the way in enabling formerly inexperienced developers, such as myself, to learn and understand efficiently. This implementation of the State Machine Pattern is an accumulation of examples I have adapted to fit the needs of my personal projects.&lt;/p&gt;

&lt;p&gt;Now, let's delve into the details. There are several classes involved in setting up the framework of the state machine. They are as follows:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Player Class:&lt;/strong&gt;&lt;br&gt;
This class is attached to the Player Character Game Object. It initializes the state machine and stores references to each state. It also holds references to components needed by the state machine, passing these references at initialization via a constructor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;State Machine Class:&lt;/strong&gt;&lt;br&gt;
This is the class containing functions for initializing and changing the states. Each function takes a parameter of type PlayerState. This data is sent via the Player class calling the function and passing in the desired state. Notably, in the ChangeState function, the state.Exit() function is called first, allowing the previous state to execute any "ending" logic before the transition. The current state is then set to the received parameter, and the Enter() function is called to execute any "beginning" logic for the newly entered state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PlayerState:&lt;/strong&gt;&lt;br&gt;
The base class that all state classes derive from. It has a constructor that receives and sets all protected variables the states will need and receive via references from the Player class. These variables could include components attached to the Player game object such as InputHandler, Animator, collision detections, PlayerData, Movement Control, Particle Controller, etc. PlayerState defines common functions for all states, including LogicUpdate, Enter, Exit, and DoChecks. Functions can be added as required by all states, or unique functions can be implemented in deriving states.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SuperStates:&lt;/strong&gt;&lt;br&gt;
The state classes that derive from PlayerState. They are organized based on common functionality. For example, in-air behaviors, touching wall behaviors, swimming behaviors, and grounded behaviors. SuperStates can be organized according to game functionality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SubStates:&lt;/strong&gt;&lt;br&gt;
Substate classes derive from their respective superstate and implement the unique logic and checks required for a single behavior. For instance, "MoveState" derives from the superstate "Grounded State" and applies velocity and direction to the game object.&lt;/p&gt;

&lt;p&gt;You might be wondering, how does this state system gain access to an update method? This is a crucial requirement, especially if the states are responsible for moving a game object. The implementation is quite straightforward. As mentioned earlier, the Player class utilizes its update method for this system. By calling StateMachine.currentState.LogicUpdate within its update method, each currentState (the currently active state) can utilize their common method called "LogicUpdate," which provides access to the functionality of an Update Method found in a MonoBehaviour.&lt;/p&gt;

&lt;p&gt;Remember, LogicUpdate is a function found in the base PlayerState class. By generating overrides for these inherited functions, each substate gains access to the same Player class' Update function. The implementation looks like this:&lt;br&gt;
//Player Class&lt;br&gt;
void Update()&lt;br&gt;
{&lt;br&gt;
StateMachine.CurrentState.LogicUpdate();&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;//The LogicUpdate() called in the PlayerState&lt;br&gt;
// To be derived by all states.&lt;br&gt;
protected override void LogicUpdate() &lt;br&gt;
{&lt;br&gt;
    base.LogicUpdate();&lt;br&gt;
}&lt;br&gt;
With an understanding of how LogicUpdate works, it's a good time to discuss the DoChecks function. DoChecks is also derived from PlayerState. It's where all collision checks occur, allowing access to individual raycasts, colliders, etc., found in the scene from the CollisionChecks Core component. Typically, in the appropriate SuperState, I have stored the reference in local protected variables for the deriving SubStates to utilize. To enable continuous updates and collision detection, DoChecks is called in LogicUpdate in the base PlayerState class. These checks are vital as they often trigger state transitions and must be handled effectively.&lt;/p&gt;

&lt;p&gt;It's essential to recognize the critical relationship between the StateMachine system and the core components. While the "Core" system won't be discussed in detail here, it's important that the states set references to them in a way that prevents "race conditions" between core initialization and the states storing references to them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Input Handling:&lt;/strong&gt;&lt;br&gt;
The input handler is another crucial system for the state machine, although it isn't the focus here. Like collisions, SuperStates also detect various 'playerInput' to switch states. Input checks are stored in local variables and examined via LogicUpdate to fulfill conditions that trigger state transitions. For example, detecting 'moveX' input transitions the player from idle state to move state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Working with the Animator:&lt;/strong&gt;&lt;br&gt;
Each state requires a graphical representation of the corresponding state. To achieve this, you need an Animator Controller containing conditions for state transitions. If the State Machine concept is challenging to grasp, the Animator and Animator Controller can provide a useful visual representation. Unity's animation system is powerful and can become quite complex with features like blend trees, conditions, and additional layers within states. While I haven't extensively explored these advanced features, I've hand-drawn my 2D sprites for my project. However, our focus here is solely on the relationship between the animator and the State Pattern.&lt;/p&gt;

&lt;p&gt;Consider the entire State Pattern as branching from the Player class. The monobehaviour initializes the system, stores references, and offers its update() method to power the system. Therefore, the animator required by the state system is found on the Player Game Object. The Player class stores a reference to the animator, much like it does for Core Components. Then, in the constructor for each state, it provides the animator with a matching string to set a boolean value to true or false. In essence, each state has its own animator value that it passes to the animator controller. For example, when the character is standing idle, the animator controller's 'idle' boolean is set to true. When the state changes to MoveState via XInput detection, the MoveState sets the Animator's 'move' value to true, and the idle value is set to false. This consistent transition of the player character's animations aligns with the respective state transitions.&lt;/p&gt;

&lt;p&gt;To wrap up, this overview provides a basic description of the State Machine Pattern I use for my Player classes. As you can tell, it's effective in keeping code clean, organized, and easily debuggable. Furthermore, it's highly expandable, able to connect and work in coordination with various other systems in your game. Otherwise, I hope that explanation was a clear and somewhat simplified description of the basic structure and concept of my State Machine Pattern. For myself, being able to wrap my head around its basic concept was difficult, so hopefully this is an article that achieves simplicity and understanding. If you want to see a more complex expansion of the system and how it works with other aspects of my project, feel free to check out my portfolio for details.  &lt;/p&gt;

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