Level up your code with game programming patterns: Factory pattern | Tutorial

Поделиться
HTML-код
  • Опубликовано: 25 дек 2024

Комментарии •

  • @MrShadow274
    @MrShadow274 Год назад +70

    I think this is a good route for Unity to take, understanding of patterns is very important for something more advanced than a school project or something like that. We need more of this!

  • @iHeartGameDev
    @iHeartGameDev Год назад +31

    Another pattern tutorial in such a short amount of time! Unity coming in with the presents like Santa for Christmas! 🎅

    • @monkey7218
      @monkey7218 Год назад +1

      Absolutely love your stuff! Your jump tutorials (espeically the stuff about verlet integration) got me back into coding again and taking it seriously for the first time, and really shows how important it is to understand some concepts on a deeper level. Thank you so much!

  • @prometheus1100
    @prometheus1100 9 месяцев назад +2

    These videos on programming patterns are awesome. Please keep them coming!

  • @alextrollip7707
    @alextrollip7707 5 месяцев назад +1

    This is a great idea to teach.
    Especially with the disclaimer up front that this is the ideal at the end work.
    I always try only abstract once I find it's needed.
    A sort of three or more rule that applies.
    And only if it makes the code simpler to use.

  • @paufenollosa
    @paufenollosa Год назад +5

    Implementing programming patterns is a time saver. Even if you feel that is too hard to apply, once you have learned it, your quality of life improves.😁

  • @dreamisover9813
    @dreamisover9813 Год назад +3

    Very appreciated series

  • @thepokekid01
    @thepokekid01 Год назад +9

    This feels like a great lesson on beginner object oriented coding

    • @magnusm4
      @magnusm4 Год назад

      JOBS and ECS: Am I a joke to you?

  • @firedragongamestudio
    @firedragongamestudio Год назад +3

    Love the explanations, especially the stand-up comedian theme ^^

    • @HomeMech
      @HomeMech 10 месяцев назад +1

      Thank you, we appreciate it!! 😊

  • @pythooonuser
    @pythooonuser Год назад +13

    Not sure at 3:54 why we need these two different factories. They look identical. A joke is essentially only an `IJokeTeller` so we could use that as the prefab? It's even returned by `CreateJoke` 🙃

    • @HomeMech
      @HomeMech Год назад +1

      You are correct they look similar, but there is a difference in the types of jokes they produce.
      WalksIntoABarJokeFactory creates instances of WalksIntoABarJoke; WhyDidTheChickenJokeFactory creates instances of WhyDidTheChickenJoke.
      Though both of these factories produce objects that adhere to the IJokeTeller interface, they have unique implementations of the TellJoke method that correspond to the specific style of joke. Each joke has its own timing and content nuances which a generic prefab couldn't accommodate effectively.
      An underlying concept here is that we are anticipating that joke types have some kind of gameplay importance. We don't want all IJokeTellers to be lumped together. If it helps, I imagined something fun like chickens being offended by chicken jokes but salesmen love knock knock jokes. The gameplay might involve trying to understand the audience, so the player may eventually choose the type of joke. I don't know, I kept it vague because that's how ideas start, haha.
      My main motivation with the example is to illustrate how factories empower the creation of diverse modular behaviors. Thanks for keeping a close eye on things!

    • @AlnixDigital
      @AlnixDigital 7 месяцев назад

      Or just using a generic would do the trick

    • @etistyle96
      @etistyle96 6 месяцев назад

      i think it's because the player might chose what kind of joke he want the character to do and then the game chose one of this type into a list.

  • @page0809
    @page0809 Год назад +5

    Thank you for the e-book, example project, and the videos. I'm happy to go through these examples to expand my knowledge and practice :D

    • @HomeMech
      @HomeMech 10 месяцев назад

      Our pleasure! ☺

  • @benjaminlehmann
    @benjaminlehmann Год назад +3

    This is great. Thanks for putting these together. Keep them coming :D

  • @PrajwalArtist-p4d
    @PrajwalArtist-p4d Год назад +2

    we need more - this is epic keep coming - makes me feel like using unity over unreal

  • @lakemonstergames32
    @lakemonstergames32 Год назад +1

    Beautiful, keep them coming!

  • @Kusanagi64
    @Kusanagi64 Год назад +8

    Design patterns! Woot!

  • @edward3190
    @edward3190 Год назад +4

    5:55 asset store has one called Serializable Dictionary, which shows dictionary in inspector, very helpful ;)

    • @HomeMech
      @HomeMech Год назад +2

      Definitely! Serializable dictionaries are really helpful for mapping joke type to joke factory in a flexible, easy way.
      For example, a Halloween joke type is more about the theme of the joke rather than the version of joke. So with serializable dictionaries, "Halloween" can be flexibly mapped to appropriate bar joke, knock knock joke, and chicken joke factories. Especially handy when performing for a crowd of spooky skeletons.

  • @tarutso
    @tarutso Год назад +2

    Awesome video, thank you for this! Really well explained and set ou

  • @MarekNijaki
    @MarekNijaki Год назад +3

    More videos like this

  • @bomberest0
    @bomberest0 Год назад +1

    The Joker is so cute!

  • @Ahsmic
    @Ahsmic Год назад +2

    Unity i forgive you cause you have a cool animated fish and i want it

  • @jacobs.7925
    @jacobs.7925 Год назад +1

    Thanks again!!! Outstanding content!! As many examples as possible please :)

  • @spider853
    @spider853 Год назад +3

    Can't we get rid of the factory class (another file) and just implement it as part of the Joke? (the creation). Just have a list like you have here of Jokes class prefab refs and the rest is simple. Or... I'm missing something? I always have this feeling that patterns sometimes overcomplicate things thank making them better. Correct me if I'm wrong with this case

    • @SyntaxAlex69
      @SyntaxAlex69 Год назад +1

      Agreed, I would do the same. This feels like unnecessary abstraction which causes the code to become much harder to follow.
      At least in the example given.

    • @HomeMech
      @HomeMech Год назад +5

      Thanks for your comment! Embedding the creation logic directly within the Joke class itself and using a list of prefabs is a straightforward approach. And if this is some background ambient behavior or a cut scene in a narrative game, honestly, that's perfect.
      However, the framing of this example is that we’re in an early concept stage of a game centered around stand-up comedy. It's not just about getting the fish to tell some jokes, we want to eventually build novel gameplay systems and give shape to our vague idea.
      In that case, the factory pattern offers some important advantages. The power-up example covers flexibility/extensibility, so here are a couple other key aspects:
      Separation of concerns:
      Utilizing a factory allows us to cleanly separate the joke-creation logic from the Joke class. This allows the Joke class to focus solely on what a joke is and how it behaves, while the factory is responsible for the creation of the jokes.
      You might want to try prompting gpt/bard/muse with a system idea, ask to see versions with and without the factory pattern, and just see how it plays out as you throw ideas out there.
      Dynamic creation:
      Imagine gameplay where the player gets to experiment with joke construction on the fly. The player can choose jokes and then learn things about the audience from the response. The player then is able to tailor jokes to the audience.
      For example, an audience of sloths tends to prefer a long pause before a punchline, skeletons love Halloween jokes, etc. The Factory Pattern handles this kind of dynamic, context-specific complexity more gracefully than if we were to integrate creation logic directly into each individual joke class.
      Consider games like Dwarf Fortress or Rimworld where the attributes and even mood of your colonists influence the quality of the crafts they produce. In our comedy game, the level, rizz stat, or even outfit of a comedian could influence the creation/delivery of jokes.
      In these cases, something simple like Factory.CreateThing(myCharacterAttributes) allows the factory to handle all the creation details, while the resulting created product can just be what it is or perform whatever function it performs.
      The main idea is to establish a foundation that supports the creativity and potential complexity of your idea as it takes shape and evolves. I hope that helps clarify things! ☺

    • @dreamisover9813
      @dreamisover9813 Год назад +3

      It really depends. I don't think the very first example in the video seems very useful, the later ones seem more useful - but this video also seems to be made to be accessible so there are a few decisions you might not take like that in production. I agree that people sometimes just use patterns without evaluating if they really have the problem that it solves, that should be avoided. In this case, you have an added abstraction on object creation, you can extend and change behaviour of it without having to modify the class that consumes the created thing. For very simple games such abstractions might be overkill, but it can make it easier to add/extend/modify behaviour in more complex projects. For factory specifically, you just defer the responsibility and implementation of object creation to another class. Maybe a more practical usage is if you define jokes in a scriptable object, or even just a spreadsheet, and some code parses this and feeds it to the joke consumption code, so you can design jokes in the editor or even outside, and don't have to hardcode them in. Another way to look at this is if you have multiple classes or places that consume a thing and you always create it by making a new object, and then assigning values. Somewhere down the line you notice that you want that object to behave a bit differently, or have different default values. If you used a factory or some other abstraction for object creation, you could just make a single change in the class responsibly for creating the object, instead of having to adjust the code everywhere where a new object of that type is used.

  • @kylemichiels1467
    @kylemichiels1467 Год назад +10

    Its a great pattern, but I feel like the example here is too complicated. You could achieve relatively the same with scriptable objects in this case.

    • @HomeMech
      @HomeMech Год назад +5

      I chose the stand-up example to highlight that factories aren't limited to just creating game objects. They can also be used to create products that are behaviors, interactions, or abstract concepts like a set of rules.
      Behavior in games can be very complex. I wanted to use jokes as an example because, as behaviors, they are essentially just words and timing. Yet, there is a huge variety of jokes. The example then showcases the Factory Pattern's ability to create variations in behavior. And it highlights how the pattern makes it easy for the comedian to access and use the different behavior products.
      I would love to do some behavior-oriented scriptable object videos though, so thanks for your input! It really helps us figure out how to better present advanced materials.

  • @nickicool
    @nickicool Год назад +1

    Very good video. You must create more tutorials for Unity nobles. This very important for popularity engine!

  • @ramvenkat9191
    @ramvenkat9191 Год назад +25

    simple topics but he made them too much complex with those examples..

    • @supapaw
      @supapaw Год назад +6

      I came here to say this. Why not just stick to game concepts that are so well-known to gamers? Power-ups please, forget the jokes nonsense.

    • @HomeMech
      @HomeMech Год назад +1

      You are absolutely right--the Factory Pattern is simple: factories create products. The ebook example is simple and a great starting point.
      A "product" however isn't restricted to just objects--they can be behaviors, interactions, or even abstract concepts (like a particular set of rules).
      A "factory" in this sense is broader than our everyday notion of factories making stuff.
      What's great about this pattern is that you can start creating your ideas even if they are vague or incomplete. You may not know what power ups you want or how they each function in the game, but with the factory pattern you can still build something and make progress as your vision takes shape.
      The stand-up comedian then is a modular behavioral example + a demonstration of using the factory pattern to start building out a vague game idea.

    • @leandrew8024
      @leandrew8024 2 месяца назад

      omg same thoughts :"< why? just do it with power ups

  • @shvets.gamedev
    @shvets.gamedev Год назад +2

    thanks, Unity! now I am better at humour.

  • @AIAdev
    @AIAdev Год назад +1

    But seriously... why DID the chicken cross the road?

  • @ilypavan
    @ilypavan Год назад +3

    Very hard to understand what is actually going on in this video. :(

    • @HomeMech
      @HomeMech Год назад

      Let me try using an analogy from games like Dwarf Fortress and Rimworld. In these games, colonists create crafts.
      When a colonist creates an item, they might use a command like ItemFactory.CreateItem(myCharacterAttributes).
      The quality of the resulting item is influenced by factors like the colonist's skills and mood (i.e. myCharacterAttributes). The Factory Pattern simplifies the process - the colonist doesn't need to know the details of item creation; they simply provide their character attributes. Similarly, the item (the product of the factory) isn't burdened with its own creation logic; it exists purely as an item.
      In the comedian example, the "product" is a behavior, not a physical game item. Different joke factories produce a variety of jokes, each capable of being told or performed. The comedian can tell any of the jokes without needing to know specifics of each joke. This is possible because all jokes implement the "TellJoke" method required by the "IJokeTeller" interface. Back to the colony sim example, if the crafted item (the product of the item factory) is a tool, each tool could have the ability to be used because they implement an interface like "IToolUsable" that requires a "UseTool" method.
      Let me know if that helps!

  • @omegablender
    @omegablender 10 месяцев назад

    these design patterns have highlighted my incompetence, i still struggle implementing the observer pattern

  • @hernanescudero6620
    @hernanescudero6620 Год назад +1

    OMG YES

  • @0darkwings0
    @0darkwings0 10 месяцев назад

    Hi, the link to the e-book not working :(

  • @ldgamedeveloper4438
    @ldgamedeveloper4438 Год назад

    A ghot walks into a bar the bartender says "Sorry, we don't serve spirits here."

  • @yfchan543
    @yfchan543 5 месяцев назад

    im getting so confused with the examples here. Mainly on why create a type of factory just to produce a type of IJoke? If we don't do that, what problem will we face?

    • @HomeMech
      @HomeMech 5 месяцев назад

      Consider instead a situation like a colony sim character writing a book or crafting something. We don't want the creation details (e.g. determining the quality of the book) to be a part of the character or the book. The book is an item, and we don't want to clutter the character AI with item creation logic. Instead, we make a book factory that takes in details about the character, and the factory uses that info to make the book.
      The standup example allows us to experiment with what a joke is (is there a joke effect on the audience like a spell?) without needing to change the comedian script.
      If we did a follow-up, I'd make comedian stats and pass them into the factory and use that to determine the quality of the joke. The more creation details there are, the more the factory handles, and the more obvious it becomes that we want the creation logic focused where it is. So it makes sense that you are confused because there aren't many creation details right now.

  • @geri4367
    @geri4367 Год назад +1

    This is the way

  • @kardahaspindal
    @kardahaspindal Год назад +1

    Wow 😮
    How exactly this is more robust and maintainable than, let's say having an array of elements (here, jokes) in a form of prefabs which have data (text, sequences, etc.) and optionally an override for some method? You want to add a joke? Just create a prefab and assign it to the array. It is now available for instantiation. No additional switch statement required. Want a more complex behaviour for the joke? Do the same but add a script which overrides the default joke behaviour. And that's using more of Unity and doing less coding.

    • @Th3-Mast3rmind
      @Th3-Mast3rmind Год назад

      This is just a demonstration. You would most likely not use this for anything that's the same scale as what's shown in the video. This is meant for large, complex projects

    • @kardahaspindal
      @kardahaspindal Год назад +1

      @@Th3-Mast3rmind I'll need to see it to believe it. Sometimes I think that project's complexity is just an excuse for coders to realize their wet dreams of coding for the sake of coding :)

    • @HomeMech
      @HomeMech 11 месяцев назад

      @@kardahaspindal if you like you could tell me a little about a game you are making or would like to make, and I'll suggest where and why the factory pattern might be helpful to consider

  • @marksteinburg4726
    @marksteinburg4726 Год назад +1

    The video was a bit hard to for me to follow because of the naming and coding conventions chosen. A lot of the variable, class, method and interface names are too similar to each other. The ebook was much easier to follow.

    • @HomeMech
      @HomeMech Год назад

      Thank you for the feedback!
      Please do highlight a specific example of what you mean.
      I tried to make the naming conform to how the pattern would read in the wild. That is, there's a benefit in seeing the tidy example (the e-book) vs an in-game example.
      I'll be curious to hear your opinion of the naming in our final "Pattern combo" video with the Street Fighter/Mortal Kombat style attack combos. 😅

    • @sima19995
      @sima19995 Год назад +1

      For me Joke prefabs inheriting from IJokeTeller was confusing at first because I was subconsciously thinking of inheriting interfaces as an "is a" relationship. Thinking this way raised the question: "How is a joke a joke teller? Shouldn't the comedian be the teller?". Reading the book and watching the video several times finally flipped my mind and now I correctly think about inheriting an interface as a "how it does something" instead of an "is a" relationship. That being said the word "tell" is still confusing for me. Maybe IJokeGetter and GetJoke() would make more sense to me.
      Maybe this relationship between interfaces and MonoBehaviours could have been explained better. I know the concept of interfaces was beyond the cope of this video, but if I was asked what was confusing about the naming conventions used, that would be my answer.
      *EDIT*
      Now that I think about it TellJoke() is not just getting a joke, but it implements how to display it, so I guess it really does tell a joke. Anyway, still a bit confusing, not sure what would make it clear for me.

    • @HomeMech
      @HomeMech Год назад

      Thank you for this@@sima19995 Your feedback is so helpful, it really gives me some things to think about in how I approach future tutorials.
      I completely understand the initial confusion. This is a behavioral implementation of the factory pattern where the product is a behavior and not a physical game object, so the interface is meant to indicate the ability or action something has -- in this case, "has the ability to be told."
      The term "tell" here was chosen to reflect not just the retrieval of the joke, as you point out, but its delivery and presentation (TextMeshPro component).
      When I'm working on a game, I definitely have mixed feelings about what certain things are called. As I work with it, the feeling resolves as it makes more sense, or things change. What starts as "IJokeTeller" might morph into "IDisplayJoke" and "IAffectAudience." Or something still feels a bit off, and I can't think of a better name. In that case, I just shrug and say, well, the most important thing is that the little fish is pretty cute up there ☺

  • @Bankoru
    @Bankoru Год назад +1

    Java PTSD

  • @dharmeshkumar2763
    @dharmeshkumar2763 Год назад +6

    Too advance for me to understand

    • @HomeMech
      @HomeMech Год назад +6

      That's ok! Something to work towards☺

    • @batty251
      @batty251 Год назад

      Its basically creating a parent script and subscripts which the subscripts can be used in the parent script just as the same as creating the one script but doing it this way makes it more easier to implement new subscripts.

  • @Dbl_Plus_Good
    @Dbl_Plus_Good 8 месяцев назад +1

    I feel like this moves too quickly.

    • @HomeMech
      @HomeMech 8 месяцев назад +1

      I appreciate the feedback! I'll move slower in future videos. Thank you for being patient with me figuring out how to cover more advanced topics😅

    • @Charan_Vendra
      @Charan_Vendra 5 месяцев назад

      @@HomeMechbro this is not your video

    • @HomeMech
      @HomeMech 5 месяцев назад

      @Charan_Vendra I made the video with Unity, but it's easier to respond to devs through my account. I want people to know their feedback helps. ☺️

    • @Charan_Vendra
      @Charan_Vendra 5 месяцев назад

      @@HomeMech oh got it

  • @kraemer-raimund
    @kraemer-raimund 10 дней назад

    A design decision I disagree with in this video: Jokes don't tell themselves, so a joke implementing `IJokeTeller` is very unexpected. Also, a JokeFactory would be expected to create jokes, not joke tellers. The joke teller is the comedian. That way the example would still be suitable for explaining the pattern while at the same time possibly avoiding some confusion. I would expect the joke factory to create a joke, and the comedian to tell it. The joke should not be coupled to the UI element that displays the joke, but rather the comedian could use the UI element as the means to "tell" the joke.

  • @alekseyrastegaev3077
    @alekseyrastegaev3077 4 месяца назад +1

    Sorry but explanation is really bad. Example is waaay too far from real life…

    • @HomeMech
      @HomeMech 2 месяца назад

      Thanks for the feedback! Everyday examples are great, but sometimes it's hard to know where to start with building a new idea... so I wanted to try to do an example where you have a vague novel concept, which I think that fits this pattern--admittedly, challenging to attempt 🙂If we ever do this again, I'd like to do a situation where a character creates an item and sends along their stats (and materials, maybe) to the factory for the creation of the item. That's the scenario where I first found this pattern really helpful.

  • @XtroTheArctic
    @XtroTheArctic Год назад +2

    🤮🤮

  • @RuffledF
    @RuffledF Год назад

    .... You are making a game, not a generic API. You should write code for what you need, not for what you'll think you need down the line.
    This video only teaches you how to make your code more complex and obfuscated...
    In my experience working on indie and AAA games, they always end up as organised chaos. The code isn't neat, but at least you know it works and what it does....

  • @IberianInteractive
    @IberianInteractive Год назад +10

    i didn't understand a thing

  • @zxcaaq
    @zxcaaq Год назад +3

    bad advice