Discover millions of audiobooks, ebooks, and so much more with a free trial

From $11.99/month after trial. Cancel anytime.

Learning Design Patterns with Unity: Learn the secret of popular design patterns while building fun, efficient games in Unity 2023 and C#
Learning Design Patterns with Unity: Learn the secret of popular design patterns while building fun, efficient games in Unity 2023 and C#
Learning Design Patterns with Unity: Learn the secret of popular design patterns while building fun, efficient games in Unity 2023 and C#
Ebook1,448 pages7 hours

Learning Design Patterns with Unity: Learn the secret of popular design patterns while building fun, efficient games in Unity 2023 and C#

Rating: 0 out of 5 stars

()

Read preview
LanguageEnglish
Release dateMay 31, 2024
ISBN9781805124160
Learning Design Patterns with Unity: Learn the secret of popular design patterns while building fun, efficient games in Unity 2023 and C#
Author

Harrison Ferrone

Harrison Ferrone was born in Chicago, IL. Most days, you can find him creating instructional content for LinkedIn Learning or trying to learn something new. He holds various fancy looking pieces of paper from the University of Colorado at Boulder and Columbia College Chicago, and despite being a proud alumnus, most of these are stored in a basement somewhere. After a few years as an iOS developer at small start-ups, and one Fortune 500 company, he fell into a teaching career and never looked back. Throughout all this, he's bought many books, acquired a few cats, worked abroad, and continually wondered why Neuromancer isn't on more course syllabi

Related to Learning Design Patterns with Unity

Related ebooks

Programming For You

View More

Reviews for Learning Design Patterns with Unity

Rating: 0 out of 5 stars
0 ratings

0 ratings0 reviews

What did you think?

Tap to rate

Review must be at least 10 words

    Book preview

    Learning Design Patterns with Unity - Harrison Ferrone

    cover.png

    Contents

    Preface

    Who this book is for

    What this book covers

    To get the most out of this book

    Get in touch

    Priming the System

    A word about software architecture

    What are design patterns?

    The Gang of Four

    Pattern categories

    Creational patterns

    Behavioral patterns

    Structural patterns

    Why use design patterns?

    When to use design patterns

    Common pitfalls

    About the example projects

    Client code

    Old vs new input system

    Art assets

    Summary

    Further reading

    Managing Access with the Singleton Pattern

    Technical requirements

    Breaking down the pattern

    Diagramming the pattern

    Pros and cons

    Updating a MonoBehavior into a persistent singleton

    Persisting the singleton between scenes

    Testing for duplicate managers

    Creating a generic singleton

    Adding thread safety to the generic singleton

    Thread locking during lazy instantiation

    Creating singletons as ScriptableObjects

    Summary

    Further reading

    Spawning Enemies with the Prototype Pattern

    Technical requirements

    Breaking down the Prototype pattern

    Diagraming the pattern

    Pros and cons

    Implementing shallow and deep object copying

    Adding a prototype interface

    Making shallow object copies

    Making deep object copies

    Adding a prototype factory

    Cloning prefabs

    Creating a generic prototype component

    Summary

    Further reading

    Join our community on Discord

    Creating Items with the Factory Method Pattern

    Technical requirements

    Breaking down the Factory Method pattern

    Diagramming the pattern

    Pros and cons

    Declaring our inventory products

    Adding a product interface

    Creating concrete products

    Working with different factory class variations

    Adding an abstract factory class

    Building a concrete factory

    Creating a concrete factory class

    Building a parameterized factory

    Creating a parameterized factory class

    Scaling factories with reflection and LINQ

    Adding GameObjects to the mix

    Updating the Item class

    Updating the Abstract Creator class

    Updating the concrete factory

    Updating the reflection factory

    Extending products and factories with Scriptable Objects

    Summary

    Further reading

    Join our community on Discord

    Building a Crafting System with the Abstract Factory Pattern

    Technical requirements

    Breaking down the Abstract Factory pattern

    Diagramming the pattern

    Pros and cons

    Creating related but independent products

    Scripting product interfaces

    Adding concrete products

    Creating abstract and Concrete Factory classes

    Writing a client class using only interfaces

    Creating related and dependent products

    Writing dependent product abstract classes

    Creating concrete products

    Adding abstract and Concrete Factory classes

    Updating the client

    Optional factory variations

    Parameterized factories

    Creating a factory of factories

    Summary

    Further reading

    Join our community on Discord

    Assembling Support Characters with the Builder Pattern

    Technical requirements

    Breaking down the Builder pattern

    Diagramming the pattern

    Pros and cons

    Creating a base ally and builder interface

    Scripting the product class

    Declaring a common builder interface

    Adding concrete builders

    Using a director class

    Integrating GameObjects

    Transitioning to a Fluent Builder structure

    Summary

    Further reading

    Managing Performance and Memory with Object Pooling

    Technical requirements

    Breaking down the Object Pool pattern

    Diagramming the pattern

    Pros and cons

    Writing an Object Pool class

    Creating objects and filling the pool

    Retrieving pooled objects

    Releasing pooled objects

    Resetting pooled objects

    Object Pooling customizations

    Queues over lists

    Thread-safe pools

    Managing different pooled objects

    Leveraging Unity’s ObjectPool class

    Summary

    Further reading

    Join our community on Discord

    Binding Actions with the Command Pattern

    Technical requirements

    Breaking down the Command pattern

    Diagramming the pattern

    Reusable versus single-use commands

    Pros and cons

    Building a basic Command structure

    Creating reusable commands

    Adding a receiver

    Adding an invoker class

    Using an input listener

    Updating the client

    Creating coupled commands

    Implementing an undo/redo system

    Stacking commands

    Adding an undo feature

    Adding a redo feature

    Confirming and clearing commands

    Summary

    Further reading

    Join our community on Discord

    Decoupling Systems with the Observer Pattern

    Technical requirements

    Breaking down the Observer pattern

    Diagramming the pattern

    Pros and cons

    Creating a basic Observer structure

    Writing the abstract base objects

    Making the UI an observer

    Subscribing observers and publishing events

    Pattern strategies and optimizations

    Choosing a communication strategy

    Listening for different state changes

    Cleaning up hanging resources

    Using C# event types

    Delegates and events

    Updating to Action types

    UnityEvents and the Inspector

    Adding Unity events

    Adding UnityEvent parameters

    Persistent versus non-persistent events

    The final boss – drag-and-drop system

    Writing a ScriptableObject event

    Creating listeners

    Creating ScriptableObject event assets

    Invoking the SOEvent

    Connecting the system

    Performance considerations

    Picking the right implementation

    Summary

    Further reading

    Join our community on Discord

    Controlling Behavior with the State Pattern

    Technical requirements

    Breaking down the State pattern

    A little automata theory

    Diagramming the pattern

    Pros and cons

    Creating a turn-based battle system

    Defining abstract and base states

    Creating a state machine

    Protecting transitioning states

    Subclassing state machines

    Creating concrete states

    Base state

    Setup state

    Player state

    Enemy state

    Ending state

    Putting it all together

    Initializing concrete states

    Updating the client

    Using a hierarchical state machine

    Adapting for concurrent state machines

    Unrelated concurrent states

    Related concurrent states

    Storing state history

    Pushing new states

    Reverting to previous states

    Summary

    Further reading

    Adding Features with the Visitor Pattern

    Technical requirements

    Breaking down the Visitor pattern

    Diagramming the pattern

    Pros and cons

    Creating a save system

    Structuring the interfaces

    Adding a concrete visitors

    Adding concrete elements

    Adding an object structure

    Working with composite elements

    Accounting for selective visitation

    Summary

    Further reading

    Join our community on Discord

    Swapping Algorithms with the Strategy Pattern

    Technical requirements

    Breaking down the Strategy pattern

    Diagramming the pattern

    Pros and cons

    Creating a sorting system

    Defining a strategy interface

    Adding concrete strategies

    Creating a context

    Optimizing your strategies

    Adding interchangeable strategies

    Using default strategies

    Strategies the Unity way

    Upgrading to ScriptableObjects

    Summary

    Further reading

    Join our community on Discord

    Making Monsters with the Type Object Pattern

    Technical requirements

    Breaking down the Type Object pattern

    Diagramming the pattern

    Pros and cons

    Creating monsters

    Adding a Type Object

    Configuring monsters

    Optimization, inheritance, and behavior

    Controlling allocation and initialization

    Adding parent type objects

    Sharing behavior isn’t easy

    Creating ScriptableObject monsters

    Summary

    Further reading

    Taking Data Snapshots with the Memento Pattern

    Technical requirements

    Breaking down the Memento pattern

    Diagramming the pattern

    Pros and cons

    Creating and restoring data snapshots

    Adding the memento class

    Setting up the caretaker

    Updating the originator

    Wiring up the client

    Working with MonoBehaviours

    Memento pattern variations

    Storing memento history

    Bundling originator and caretaker

    Managers and ScriptableObject snapshots

    Persisting data

    Summary

    Further reading

    Join our community on Discord

    Dynamic Upgrades with the Decorator Pattern

    Technical requirements

    Breaking down the Decorator pattern

    Diagramming the pattern

    Pros and cons

    Building a simple Decorator

    Adding a Component interface

    Creating a concrete Component

    Using a base Decorator

    Building a concrete Decorator

    Chaining multiple Decorators

    Adding customized behaviors

    Using ScriptableObject Decorators

    Static vs dynamic decoration in action

    Summary

    Further reading

    Join our community on Discord

    Converting Incompatible Classes with the Adapter Pattern

    Technical requirements

    Breaking down the Adapter pattern

    Diagramming the pattern

    Pros and cons

    Building a controller adapter

    Defining a target

    Adding the class adapter

    Creating an object adapter class

    Mapping properties in separate hierarchies

    Summary

    Further reading

    Simplifying Subsystems with the Façade Pattern

    Technical requirements

    Breaking down the Façade pattern

    Diagramming the pattern

    Pros and cons

    Building a subsystem Façade

    Defining subsystem objects

    Initializing subsystems

    Adding a public Façade method

    Adding multiple Façade methods

    Upgrading Façades

    Summary

    Further reading

    Join our community on Discord

    Generating Terrains with the Flyweight Pattern

    Technical requirements

    Breaking down the Flyweight pattern

    Diagramming the pattern

    Pros and cons

    Creating shareable terrains

    Adding a Flyweight interface

    Extracting extrinsic state

    Building a concrete Flyweight

    Adding a Flyweight factory

    Working with unshared Flyweights

    Upgrading to ScriptableObjects

    Flyweight or Type Object?

    Summary

    Further reading

    Global Access with the Service Locator Pattern

    Technical requirements

    Breaking down the Service Locator pattern

    Diagramming the pattern

    Pros and cons

    Creating services and contracts

    Logging and saving contracts

    Planning for missing services

    Building a Service Locator class

    The Null Object pattern

    Adding a generic solution

    Extending locator functionality

    Initializing services

    Explicitly registering services

    Unregistering services

    A word on scope

    Singleton Service Locators

    Grouping services

    A service for every level

    Summary

    Further reading

    Join our community on Discord

    The Road Ahead

    SOLID principles and you

    The patterns left out (but not forgotten)

    Resourceful resources

    Getting involved

    Summary

    Other Books You May Enjoy

    Index

    Landmarks

    Cover

    Index

    Learning Design Patterns with Unity

    Learn the secret of popular design patterns while building fun, efficient games in Unity 2023 and C#

    Harrison Ferrone

    Learning Design Patterns with Unity

    Copyright © 2024 Packt Publishing

    All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

    Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.

    Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

    Senior Publishing Product Manager: Larissa Pinto

    Acquisition Editor – Peer Reviews: Gaurav Gavas

    Project Editor: Meenakshi Vijay

    Content Development Editor: Tanya D’cruz

    Copy Editor: Safis Editing

    Technical Editor: Tejas Mhasvekar

    Proofreader: Safis Editing

    Indexer: Pratik Shirodkar

    Presentation Designer: Rajesh Shirsath

    Developer Relations Marketing Executive: Sohini Ghosh

    First published: May 2024

    Production reference: 2080724

    Published by Packt Publishing Ltd.

    Grosvenor House

    11 St Paul’s Square

    Birmingham

    B3 1RB, UK.

    ISBN 978-1-80512-028-5

    www.packt.com

    Contributors

    About the author

    Harrison Ferrone was born in Chicago, Illinois, and was raised all over the U.S. He’s worked at Microsoft, PricewaterhouseCoopers, and a handful of small start-ups, but most days you can find him creating instructional content for LinkedIn Learning or working on new projects. He holds various fancy-looking pieces of paper from the University of Colorado Boulder and Columbia College Chicago. Despite being a proud alumnus, these are stored in a basement somewhere. After a few years as a full-time iOS and Unity developer, he fell into a teaching career and never looked back. Throughout all this, he’s bought many books, been owned by several cats, worked abroad, and continually wondered why Neuromancer isn’t on more course syllabi.

    Completing this book wouldn’t have been possible without the loving support of Kelsey, my wife and partner in crime on this journey.

    About the reviewers

    Charles Haché, also known as Oz, is a seasoned game development teacher with extensive experience at both the high school and university levels. As a technical mentor for graduates and individuals seeking to upskill, he specializes in Unity, C# OOP, architecture, design patterns, VR, AR, instructional design, and leadership. In addition to his teaching roles, Oz has contributed to various game development projects and has been instrumental in shaping curricula that bridge the gap between academic theory and practical application. He has worked with several esteemed organizations, including the University of Victoria as a Unity Certified Instructor, Mastered Studios Inc. as a technical mentor, and Pearson as a subject mattter expert in Unity. His expertise has been sought after for technical reviews and consultations on several notable publications within the game development community.

    In working on this book, I would like to extend my heartfelt gratitude to my wife, Kari, for all the support she has given me over the past 12 years. I look forward to sitting on a porch with her, holding hands, now that this book is finished.

    Luiz Henrique Bueno, also known as Rick Good, began his career in Brazil, focusing on smart home and IoT projects. This laid the groundwork for his expertise in software architecture and design patterns, leading to proficiency across iOS, macOS, Windows, and XR platforms. By 2016, he had become one of Brazil’s first Unity Certified Developers, showcasing his depth in game development. After moving to the USA in 2017, he founded Toodoo Studio, where he successfully launched several game titles, including Global Destruction VR, Blondie on the Road, Thomas’ Tales, and Food Chase, using Unity and Unreal Engine. His contributions extend to authoring and technically reviewing Unity books and creating educational content on Unity and Unreal development. His technical skills span from C++ and C# to Swift, React, and Node.js. He has ventured into XR applications for Apple Vision Pro and Meta Oculus devices, continuing to push the boundaries of interactive technology. For a closer look at his projects and achievements, visit his portfolio at https://rickgood.me.

    Join our community on Discord

    Join our community’s Discord space for discussions with the author and other readers:

    https://packt.link/gamedevelopment_packt

    Preface

    Design patterns have been around for a very, very long time (decades in fact), lighting the way through dark and troubled waters where scale, flexibility, access, communication, and optimization try to capsize your best coding efforts at every turn. You’ll see these concepts taught and embedded in most, if not all, Computer Science curriculums around the world, but they’re conspicuously missing from many a young game programmers toolkit (mine included when I first started out).

    Maybe these skills are traditionally taught by more experienced developers and mentors over the course of a programmer’s career. Maybe games are supposed to be fun to make, leaving the more serious work to the engineers who specialize in creating large accounting systems, traffic monitoring algorithms, or global trading platforms. Maybe this skill gap has simply been overlooked in favor of game mechanics and amazing animations (not that those aren’t important bits – we’d be nowhere without them).

    Whatever the reason, we need to break the current pattern of sending young developers off into the wilds with swords but no potions and start training for reality – a reality where games are still only play, but the underlying game systems need to be just as complex, flexible, and well architected as the software products we use in our daily lives!

    Who this book is for

    I’m going to daringly assume that you’re a programmer, hobbyist, software engineer, game designer, or unicorn hybrid of all the above. You might be looking to advance your C# and/or game programming knowledge, getting ready for a promotion, or just trying to make your code more reusable, flexible, and professional.

    The goal of this book isn’t to specifically teach you how to build applications, games, the ins-and-outs of the Unity engine, or even C# for that matter; it’s to teach you how to think, problem-solve, and implement systems in your code. C# is a great Object-Oriented language,

    Unity is an engaging visual environment, and games are a fun way to learn, but these are all tools for us to learn and design better systems (with the help of design patterns).

    Even though design patterns aren’t for complete programming beginners, once you have a basic competency in C# and Unity, it’s never too early to start thinking and learning about good software architecture. Chances are that the way you’re writing code right now could use a boost of optimization, flexibility, and efficiency. And that’s why you’re here, right?

    What this book covers

    Chapter 1, Priming the System, starts off with a brief trip into software architecture, software design, and design pattern categories, all while getting comfortable with the why and when of implementing these solutions. We’ll also go over the common pitfalls of using design patterns for the first time and the example projects used throughout the book.

    Chapter 2, Managing Access with the Singleton Pattern, begins by laying the groundwork for uses-cases where globally accessible classes are needed (like persistent game managers) and moves on to generic singleton classes, thread-safety, and converting singletons into ScriptableObjects.

    Chapter 3, Spawning Enemies with the Prototype Pattern, takes a deep dive into efficiently creating objects without the memory overhead by copying instead of instantiating new instances. We’ll also cover the differences between shallow and deep object copying in C#, clone prefab objects, and build a generic cloning script component.

    Chapter 4, Creating Items with the Factory Method Pattern, introduces the concept of object factories that can produce a variety of products, different factory variations we can use to make our code more efficient and flexible, and scale factory production with Reflection and LINQ.

    Chapter 5, Building a Crafting System with the Abstract Factory Pattern, details the process for creating factories of factories, working with families of related and independent (or dependent) products, and finally exploring Abstract Factory variations for niche scenarios.

    Chapter 6, Assembling Support Characters with the Builder Pattern, delves into an assembly line approach to creating complex objects using the same construction processes to pump out different products. We’ll also add GameObjects to the mix and use the fluent Builder pattern variation for cleaner code.

    Chapter 7, Managing Performance and Memory with Object Pooling, introduces the concept of recycling batches of objects for reuse instead of creating new instances from scratch while incorporating thread-safety and Unity’s own generic

    ObjectPool

    class.

    Chapter 8, Binding Actions with the Command Pattern, starts with an overview of actionable requests and pre-packaging everything a command may need to be executed. We’ll also dive into the differences between coupled and uncoupled commands, their respective use cases, and how to build a complete undo/redo system from scratch.

    Chapter 9, Decoupling Systems with the Observer Pattern, takes a more in-depth look at communication strategies between objects, how to effectively separate message senders from receivers, and the performance pros and cons of using native C# events versus Unity events.

    Chapter 10, Controlling Behavior with the State Pattern, dives into the concept of managing an objects’ state, transitioning between states, and the basic theory behind state machines. We’ll also explore different configurations of state machines, including Finite state machines, Hierarchical state machines, and Concurrent state machines, as well as how to track and store state history.

    Chapter 11, Adding Features with the Visitor Pattern, gets you ready to add new behaviors to existing objects without changing the underlying object in any way by creating a simple saving system. We’ll also learn how to deal with composite elements (objects with children) and how to convert our save system to use ScriptableObjects.

    Chapter 12, Swapping Algorithms with the Strategy Pattern, explores how to configure classes and objects with interchangeable behaviors (or algorithms) at runtime by building a simple turn-based battle team example. We’ll also learn how to optimize these strategies for efficiency and update them to use ScriptableObjects.

    Chapter 13, Making Monsters with the Type Object Pattern, takes a deep dive into separating common data that a group of related objects share and then creating different configurations of those objects with the least amount of classes using a flat hierarchy. We’ll also look at memory allocation and inheritance optimizations and learn how to incorporate ScriptableObjects as configurable data containers.

    Chapter 14, Taking Data Snapshots with the Memento Pattern, introduces a system for storing, managing, and restoring an object’s internal state at any point in time using data snapshots without breaking the object’s encapsulation by building a character builder UI example.

    Chapter 15, Dynamic Upgrades with the Decorator Pattern, offers solutions for dynamically adding behaviors to existing objects without subclassing, making a completely optional opt-in system for new upgrades and features.

    Chapter 16, Converting Incompatible Classes with the Adapter Pattern, dives into creating shared interfaces for two or more classes that aren’t part of any shared hierarchies to work together. We’ll also touch on two variations (class and object adapters) and how to map properties in mismatched hierarchies.

    Chapter 17, Simplifying Subsystems with the Façade Pattern, details a common solution for creating a wall between client code and complex (and often interdependent) subsystems by creating a simple auto-save feature. We’ll also get hands-on experience with adding multiplefaçade methods for clients to access and talk about creating abstract façade classes for certain scenarios.

    Chapter 18, Generating Terrains with the Flyweight Pattern, introduces the concept of shareable state, which makes object creation (especially in large quantities) more computationally efficient if objects don’t have to store duplicate data. We’ll also discuss adding factories to this design pattern and how to correctly chose between the Flyweight and Type Object patterns.

    Chapter 19, Global Access with the Service Locator Pattern, details a centralized solution for storing and locating systems in your projects that need to be globally accessible. Like singletons, these services may need to be persistent and accessible from anywhere, which means putting them into a single registry not only makes initialization easier, but it also makes them less prone to abuse.

    Chapter 20, The Road Ahead, finishes with a look at the SOLID design principles, the design patterns we didn’t cover, and resources to take your programming skills to the next level.

    To get the most out of this book

    My north star is always making my content accessible to as many people as possible, which means I naturally try and keep prerequisites and barriers to entry fairly low or non-existent. However, design patterns are an intermediate programming topic, which means you need some foundational competencies to get going and feel confident with the material being presented.

    Whatever brought you here, we need to lay out some basic requirements for getting the best possible experience from reading this book, so we’re all on the same page. Here’s what you’ll need before getting started:

    Know how to write C# and its basic language components like variables, types, access modifiers, and control flow.

    Understand and use Object-Oriented Programming concepts like classes, objects, interfaces, generics, events, delegates, inheritance, and encapsulation.

    Be comfortable with Unity and the Unity editor, including navigation, creating scripts, and adding objects to the scene. You should also be comfortable with coroutines and basic Unity events like Awake, Start, and Update.

    I don’t want all of this to sound discouraging, so just know that if you’ve been playing around with Unity and C# for a few months, maybe watched some tutorials, or even made a simple playable prototype or two - you can absolutely continue reading. This book is a reference, which means you’ll likely need to revisit chapters more than once to get things cemented in your mind. Don’t feel obligated to read the book in sequence either – the right tool for the job is the mainstay of everything you’ll learn here.

    You’ll also need the current version of Unity installed on your computer—2023 or later is recommended. All code examples have been tested with Unity 2023.1 and should work with future versions without issues.

    Before starting, check that your computer setup meets the Unity system requirements at https://docs.unity3d.com/2023.1/Documentation/Manual/system-requirements.html.

    Download the example code files

    The code bundle for the book is hosted on GitHub at https://github.com/PacktPublishing/C-Design-Patterns-with-Unity-First-Edition. We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!

    Download the color images

    We also provide a PDF file that has color images of the screenshots/diagrams used in this book. You can download it here: https://packt.link/gbp/9781805120285.

    Conventions used

    There are a number of text conventions used throughout this book.

    Code In Text

    : Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. For example: "

    Manager.cs

    stores our score and loads the next scene."

    A block of code is set as follows:

    using

    System.Collections;

    using

    System.Collections.Generic;

    using

    UnityEngine;

    public

    class

    Item

    :

    MonoBehaviour

    {

    void

    OnCollisionEnter

    (

    Collision collision

    )

    {

    if

    (collision.gameObject.tag ==

    Player

    ){

    // 1

    Manager.Instance.score++; Destroy(

    this

    .gameObject); Debug.Log(

    Item collected!

    ); } } }

    When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:

    public

    class

    Item

    :

    MonoBehaviour

    {

    void

    OnCollisionEnter

    (

    Collision collision

    )

    {

    if

    (collision.gameObject.tag ==

    Player

    ) {

    // 1

    GenericManager

    .Instance.score++; Destroy(

    this

    .gameObject); Debug.Log(

    Item collected!

    ); } } }

    Bold: Indicates a new term, an important word, or words that you see on the screen. For instance, words in menus or dialog boxes appear in the text like this. For example: "Navigate to Assets | Scenes, and double-click on SplashScreen."

    Warnings or important notes appear like this.

    Tips and tricks appear like this.

    Get in touch

    Feedback from our readers is always welcome.

    General feedback: Email

    [email protected]

    and mention the book’s title in the subject of your message. If you have questions about any aspect of this book, please email us at

    [email protected]

    .

    Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you reported this to us. Please visit http://www.packtpub.com/submit-errata, click Submit Errata, and fill in the form.

    Piracy: If you come across any illegal copies of our works in any form on the internet, we would be grateful if you would provide us with the location address or website name. Please contact us at

    [email protected]

    with a link to the material.

    If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit http://authors.packtpub.com.

    Share your thoughts

    Once you’ve read Learning Design Patterns with Unity, we’d love to hear your thoughts! Please click here to go straight to the Amazon review page for this book and share your feedback.

    Your review is important to us and the tech community and will help us make sure we’re delivering excellent quality content.

    Download a free PDF copy of this book

    Thanks for purchasing this book!

    Do you like to read on the go but are unable to carry your print books everywhere?

    Is your eBook purchase not compatible with the device of your choice?

    Don’t worry, now with every Packt book you get a DRM-free PDF version of that book at no cost.

    Read anywhere, any place, on any device. Search, copy, and paste code from your favorite technical books directly into your application.

    The perks don’t stop there, you can get exclusive access to discounts, newsletters, and great free content in your inbox daily.

    Follow these simple steps to get the benefits:

    Scan the QR code or visit the link below:

    https://packt.link/free-ebook/9781805120285

    Submit your proof of purchase.

    That’s it! We’ll send your free PDF and other benefits to your email directly.

    1

    Priming the System

    As programmers, our job is to design, build, and integrate software features into cohesive products that are useful and hopefully bring joy to our users. And somewhere in all of that, the software has to work. Our job can be anything from building a login feature or networking layer to a subscription and payment portal. In games, we’re thinking of moving a playable character, building an adaptive AI enemy, or adding a random level generator. The big idea that should pop out at you is that these elements don’t exist in a vacuum. In fact, they tend to wither and die of boredom if they’re not connected to each other.

    When you think of the code powering your applications and games, you’re thinking about a collection of systems built around specific features or mechanics, but more importantly, around specific problems that come with making those features work as expected. If I could manage it, I’d have the word systems jump off the page and do a little dance to get your attention, because that’s what this entire book is about: games (and applications) are made up of systems – the more these systems grow and interact with each other, the more complicated things get.

    Systems may not be anything new to you, and they’re certainly not new to the programming industry, but there are problems that you’ll repeatedly run into that are directly related to systems running and interacting. And that’s really what I want to drive home before we get started: design patterns provide reusable solutions to problems we face in our everyday software lives and offer a common vocabulary for understanding and talking about best practices.

    Now the real work starts – how do we identify the parts of our code that could benefit from a design pattern? How does all this relate to software architecture? How can I adapt these patterns for game development in Unity?

    These are big questions, which is why we’re spending this first chapter getting a holistic feel for the following topics:

    Software architecture vs software design

    Design patterns and the categories they belong to (creational, structural, and behavioral)

    Why use design patterns at all?

    When to use design patterns

    Common pitfalls

    Starter projects for this book

    By the end of the chapter, you’ll have the necessary foundation to dive into design pattern implementations and a big-picture view of the flexibility, reusability, and structure they can add to your projects. But first, let’s make sure you know what to expect from this book and that you’re coming to the table with the prerequisites for getting the most out of the experience.

    At the time of writing, all chapter examples and project files were built using Unity 2023.1.5f1. Unity is the visual tool we’re using to make the learning process more inviting, but the bones of the design pattern content are still 100% applicable to C# projects. The main differences that come into play between Unity, C#, and design patterns are how objects are created (new classes vs MonoBehaviours) and assembled (inheritance vs GameObjects and Components). Don’t worry, we’ll cover these variations in each pattern. Learning how each design pattern works as a system doesn’t depend on a specific platform or language – it’s all problem-solving skills!

    A word about software architecture

    Software architecture is a big topic and shouldn’t be confused with software design even though they both deal with patterns. When we talk about architectural patterns, we’re talking about big-picture solutions to problems that are typically focused on how multiple components work together at the application level, as well as conventions, best practices, and principles that guide the overall development process. When we talk about software design patterns, we’re talking about problems that crop up when you’re building those internal components. Figure 1.1 provides a simplified example of the key difference we’re talking about: Process A is made up of multiple internal components (the software design portion) while managing and organizing how these internal components fit together (the architectural portion).

    Diagram Description automatically generated

    Figure 1.1: Example diagram of software architecture vs design

    Clear as mud? OK, let’s take a more relatable example: if we think about building a house, the architectural patterns are focused on how the entire house fits together and how the component parts (electrical, plumbing, insulation, etc.) come together into a functioning structure you can live in. Think LEGO (because that always helps me): architectural patterns deal with problems affecting the overall structure you’re building, while design patterns focus on the individual LEGO blocks that make up the final structure. You ideally need both types of solutions in a great application or game, but they solve fundamentally different problems, which is why I bring this distinction up so early in our journey. We’ll be focused on the software design aspect of things, but you can (and should) continue your journey into architectural waters after or in conjunction with this book.

    In your everyday life, when you open Twitter (or whatever app you go to first thing in the morning), you’re involved in what’s called the Client-Server architectural pattern – the client (the app on your phone) consumes information from a server somewhere in a basement and displays it to you in a way you can understand. But it’s not concerned with how the app remembers your login credentials or uses face recognition to log you in. Those are software design problems because they focus on the internal features of the application.

    Before we get to the why, when, and how of design patterns, we need to agree on a basic understanding of what good software design is to see the benefits of design patterns. Books on software design are everywhere. Amazon thinks you want them, and your co-workers probably have a few gathering dust on their desks right now. Hell, your computer monitor might be sitting on a few of them at this very moment. This isn’t one of those books.

    I like to think of software design as a tool that might make things harder in the moment but easier in the long run, like going to the gym. It’s a pain to use the Stairmaster every day, but being healthy has far-reaching benefits throughout a lifetime. The same is true of approaching a project with an eye to software design. With that in mind, let’s set up a simple definition for ourselves as a kind of guiding light for what we mean by good software design:

    A codebase that is flexible, maintainable, and reusable is the product of good software design.

    This is easier said than done no matter how well-intentioned you or your team start off developing your game. Decoupling your code can speed up your development process, but it adds overhead and maintenance time. On the other hand, interdependent code can be costly when you want to make changes, big or small. It’s all about balance, even if you can’t have everything you want all the time. Fast, good, or cheap – you can only ever have two.

    With a working definition of good software design, we can move on to talking about what design patterns are, how they’re categorized, and how they fit into Unity projects.

    What are design patterns?

    If I haven’t harped on this point enough, I want you to keep thinking to yourself Design Patterns are systems over and over. Let’s say that again, design patterns are systems, and systems are designed to solve specific problems. It doesn’t matter if it’s the brake system in your car, the biological systems that run our bodies, or the banking system in Figure 1.2. They’re all systems and they’re all trying to solve a problem or keep their respective system organized and balanced (and sometimes both).

    Diagram Description automatically generated

    Figure 1.2: Diagram of how bank accounts work using credit and debit

    More than anything, design patterns focus on making code more flexible and reusable, two tenets we’ll hammer away at throughout this book. Just keep repeating our mantra every time we dive into a new pattern: design patterns are systems!

    The Gang of Four

    Back in 1994, a group of four daring engineers banded together to better tackle OOP practices and recurring problems that kept popping up in their programs; Design Patterns: Elements of Reusable Object-Oriented Software written by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides is the product of that team-up. The book covers 23 design patterns split into three categories according to their core functions, with examples written in C++ and Smalltalk. While the book was and continues to be an important resource, these patterns have been adapted and expanded since 1994, leaving some more (and some less) relevant depending on your chosen programming language and environment.

    There are also those who have pointed out that a fair few of the patterns are replacements for perceived missing features in the C++ language. However, this argument has never resonated with me when I look at my code in other languages (whether it’s C# or something like Swift) because wearing my systems-thinking glasses has always made me think more critically and write code more intentionally.

    You’ve likely heard the phrase Gang of Four whispered with quiet reverence (or loud and angry fist-shaking, depending on who you’re talking to), but with topics like this, I’ve found it’s best to learn design patterns as a skill before making judgments. There are impassioned programmers on both sides of the aisle, which means getting your hands dirty is the best thing you can do for yourself. A lot of the debate gets lost in theoretical or pedagogical minutiae (and personalities) but the core skillset behind design patterns has always been a useful tool for programming.

    Pattern categories

    There are three categories that all original design patterns fall into – Creational, Behavioral, and Structural. As with all things, additional patterns have evolved since 1994, resulting in useful patterns that were not included in the original Gang of Four book that we’ll cover on our journey and a few honorable mentions (because we can’t cover every design pattern in a single book).

    Before we get into the category details, I feel it’s important to address a problem that crops up at the beginning of most journeys into design patterns – how do I find the right pattern for the problem I’m facing? Do I need to read and memorize every pattern, or is there a better way to navigate this topic?

    The answer might surprise you, but no, this isn’t a memorization game and you don’t get extra points for knowing everything about every design pattern – systems thinking is a learned skill, not a closed-book test. It’s almost a detective game: first, knowing what problems each pattern category addresses is super important because it narrows the field you have to search. Second, reading the first few pages of each chapter in the applicable category will show you pretty quickly if you’re in the right place. From there, the more you use design patterns, the more you’ll get a feel for the problems and effective solutions out in the wild. As you’ll see, design patterns offer solutions to well-documented problems, but they’re not set in stone; it’s up to you to adapt them to your project.

    Now that we know the basics, let’s dive into the nitty-gritty of each design pattern category and what specific problems they aim to solve.

    Creational patterns

    Creational patterns deal with creating objects that are uniquely suited to a given situation or use case. More specifically, these patterns deal with how to hide object and class creation logic, so the calling instance doesn’t get bogged down with the details. As your object and class creation needs become more complex, these patterns will help move you away from hardcoding fixed behaviors toward writing smaller behavior sets that you can use to build up more complex features (think LEGO). A good creational pattern black-boxes the creation logic and simply hands back a utility tool to control what, who, how, and when an object or class is created.

    The creational patterns we’ll cover are listed in the following table:

    Table 1.1: List of creational design patterns with descriptions

    Behavioral patterns

    Behavioral patterns are concerned with how classes and objects communicate with each other. More specifically, these patterns concentrate on the different responsibilities and connections objects have with each other when they’re working together. Like structural patterns, behavioral patterns use inheritance to divvy up behaviors between classes, which gives you the freedom to let go of any white-knuckled control flow responsibilities and focus on how objects can work together.

    The behavioral patterns we’ll cover are listed in the following table:

    Enjoying the preview?
    Page 1 of 1