When to use Factory and Abstract Factory Programming Patterns

  Рет қаралды 9,057

git-amend

git-amend

Күн бұрын

Unity C# Architecture: Factory and Abstract Factory Programming Patterns in Unity C# using expert Software Engineering Principles.
🔔 Subscribe for more Unity Tutorials / @git-amend
#unity3d #gamedev #indiedev
▬ Contents of this video ▬▬▬▬▬▬▬▬▬▬
0:00 Code Smells
0:38 Static Factory Method
2:01 Factory Pattern
6:50 Abstract Factory Pattern
Assets Shown In This Video (Affiliate Links)
Odin: assetstore.unity.com/publishe...
Dungeon Mason Tiny Hero Duo: (FREE): assetstore.unity.com/packages...
Chromisu: Handpainted Forest MEGA Pack assetstore.unity.com/packages...
SineVFX: Better Crystals assetstore.unity.com/packages...
Follow me!
linktr.ee/gitamend

Пікірлер: 59
@git-amend
@git-amend 9 ай бұрын
24 hour challenge! See if you can find a spot in your current project where you can refactor a section of code to a Factory pattern! Hit the bell to keep up with new videos!
@stevehamilton321
@stevehamilton321 7 ай бұрын
I struggled to find a spot where I couldn't : )
@Lago06
@Lago06 9 ай бұрын
Thank you so much for sharing your knowledge and covering these advanced topics of game architecture and clean code! In terms of game development there are not much videos out there that target more experienced game developers (I guess mainly because the audience is much smaller). Please don't stop making them, they are very much needed and appreciated!
@git-amend
@git-amend 9 ай бұрын
You're very welcome!
@Aliberation
@Aliberation 9 ай бұрын
Awesome! Thank you for this lecture. For a Game Designer trying to get deeper into code like me, this is treasure. ❤
@git-amend
@git-amend 9 ай бұрын
Great to hear! More on the way!
@gabrijel9129
@gabrijel9129 7 ай бұрын
Thank you a whole lot for covering these high level patterns and situations!
@git-amend
@git-amend 7 ай бұрын
You're welcome!
@derboss66
@derboss66 8 ай бұрын
Thank you very much for creating this video. After watching it, I tidied up a portion of my project :)
@git-amend
@git-amend 8 ай бұрын
Fantastic!
@Broudy001
@Broudy001 9 ай бұрын
Another amazing video, I need to think about how I apply these to my game
@git-amend
@git-amend 9 ай бұрын
Awesome! I'm sure you'll find a place for a factory!
@dustintaub
@dustintaub 9 ай бұрын
These are such great, advanced topics.
@git-amend
@git-amend 9 ай бұрын
Thanks! Glad you are getting a lot out of the videos!
@shayshay8295
@shayshay8295 5 ай бұрын
Thanks, Love it!
@git-amend
@git-amend 5 ай бұрын
Glad you like it!
@hoaxygen
@hoaxygen 9 ай бұрын
Excellent series
@git-amend
@git-amend 9 ай бұрын
Thank you!
@bhaktijpatil
@bhaktijpatil 2 ай бұрын
this was sooo helpful jesus
@git-amend
@git-amend 2 ай бұрын
Glad to hear that!
@pimor2315
@pimor2315 7 ай бұрын
Thank you for the video. I really like factory pattern. I just wonder, in the first example, you are creating factory for each weapon, like SwordFactory and BowFactory and assign one to the Soldier/Knight. Why can't we just have sword and bow as a scriptable objects and assign them directly to the knight? I find it hard to see the benefits of the factory here.
@git-amend
@git-amend 7 ай бұрын
Thank you for your insightful question. While it's possible to have Sword and Bow as Scriptable Objects and assign them directly, the Factory pattern introduces a layer of abstraction that allows for more complex creation logic that can be easily modified or extended - for instance, if creating a weapon involves setting up multiple parameters or state, a factory can handle this complexity in one place and you won't need a different Scriptable Object for every type of Sword or Bow in your game. In the example in the video, the Sword and Bow are very simple, but you might want your Weapon Factory to have a reference to a secondary Factory which produces a Strategy for calculating damage or for targeting. And if the Factory becomes fairly complex, I would add an internal Builder to it as well.
@rStarStudio
@rStarStudio 9 ай бұрын
nice video!
@git-amend
@git-amend 9 ай бұрын
Thank you! Cheers!
@modiKuts
@modiKuts 5 ай бұрын
mate, epic video. I created a whole status effect system using this method by just passing in the equipped weapon into the Create method to define which status to use. very cool and modular and extensible!
@git-amend
@git-amend 5 ай бұрын
Right on, that's what I like to hear!
@modiKuts
@modiKuts 5 ай бұрын
Hi mate, One thing i did run into implementing this method (i'm still fairly beginner), is that interfaces and scriptable objects cannot implement monobehaviour. Which also means no Coroutines. I managed to find a workaround by creating a static class which you can pass a coroutine onto and it creates a single empty object to instantiate it. I was just wondering if there was any other strategies to implement monobehaviour using an abstract method like this pattern? My use example was trying to implement a burn over time with 'ticks' over the duration? Otherwise would a concrete abstract class that inherits scriptable objects as triggers for the effects be a better solution? Love your content mate, still getting across it but its the best videos of design patterns with actual unity examples i've come across! keep doing your thing.
@git-amend
@git-amend 5 ай бұрын
@@modiKuts For me personally, I tend to roll my own timers. You'll see that in other videos, but you can also see the code here: github.com/adammyhre/3D-Platformer/blob/master/Assets/_Project/Scripts/Utils/Timer.cs Alternatively, there is a very good free asset you can use for Coroutines that gives you a lot more control and does not require monobehaviours: assetstore.unity.com/packages/tools/animation/more-effective-coroutines-free-54975
@modiKuts
@modiKuts 5 ай бұрын
amazing. Thanks mate, i'll get across it today. legend.@@git-amend
@modiKuts
@modiKuts 5 ай бұрын
One last question, Can you please point me in the direction of where to get Copilot integrated for unity like you have it? Cheers.@@git-amend
@yeric17
@yeric17 6 ай бұрын
¡Gracias!
@git-amend
@git-amend 6 ай бұрын
Wow thank you!
@yeric17
@yeric17 6 ай бұрын
@@git-amend Your content is of great quality, your videos are impressive.
@TheKr0ckeR
@TheKr0ckeR 7 ай бұрын
Thanks for the great tutorial! I am always interested in "Architecture" part instead of coding after all these years in Unity and your videos are great source. Thanks for mentioning about more advanced stuffs. Do you prefer mono-behaviours more or focusing more on c# plain classes? For example, sword and bow are objects, and probably wont need to be a monobehaviour, but they will have mesh & etc. So do you agree with less mono-behaviour (humble-object pattern - POCO), better code or you just dont worry about it? Another example is health class, health doesnt need to be a mono behaviour since its only doing is decreasing some values etc. But when we need a healthbar, we need to create a monobehaviour to reference Image, fill amount etc. So healthbar will need Health reference to set its current / initial value etc. In tutorials, they both create health.cs and healthbar.cs as monobehaviours and healthbar references the health and subscribes events. But nowadays, Ive started to create healthbar.cs monobehaviour only, and i reference the healthbar in player, enemy etc and create health object inside player, enemy or whatever it is, and initialize healthbar.Init(health) like this. What would you have done situations like this? And for the next video suggestion, I would love to see how you seperate UI & Gameplay logic. For example, if we have a ShopUI.cs and buy button in it, would you do the logic inside ShopUI to buy a soldier from a SHOP? We first need to check if we can afford it, then we go soldiermanager and spawn the soldier, inside the ShopUI, or how would you approach this?
@git-amend
@git-amend 7 ай бұрын
Personally I tend to use C# objects as much as possible, however MonoBehaviours make life easier when you want to hook into the Unity lifecycle. Maybe I can talk about that more in the future. A few people have made similar requests to your video suggestion, so there will be a future video about that too. Cheers!
@Forture-fm1ve
@Forture-fm1ve 7 ай бұрын
Thank you for your video. In your first example, can I create an abstract class 'WeaponBase' to encapsulate all common attributes and then use interfaces as you did to create different types of weapons?
@git-amend
@git-amend 7 ай бұрын
Absolutely. My general practice is to start with an interface, create 2-3 concrete types and at that point determine if it's worth extracting common elements into an abstract base class. Cheers!
@Forture-fm1ve
@Forture-fm1ve 7 ай бұрын
You're welcome for your answer.@@git-amend
@shun6284
@shun6284 4 ай бұрын
But in real project would you still use factory instead of creating the weapons or shield directly using scriptable and just assign it to the player? Like example for an item you create a Potion Scriptable Object with base class Item that has serialized properties to be customizable and just assign it to player.
@git-amend
@git-amend 4 ай бұрын
In a simple game assigning a Scriptable Object directly to the player is often sufficient. However, in a more complicated game you would begin to use development principles such as separation of concerns, dependency inversion and abstraction. Assigning items directly to the Player tightly couples the Player to the base class of the item, and the more tightly coupled your game is, the harder it is to make changes in the future. We'll be talking about Inventory systems in some upcoming videos.
@anasmostefaoui3027
@anasmostefaoui3027 9 ай бұрын
I wanted to thank you for the amazing videos, it helped me drastically in my recent project. Do you have a Patreon account?
@git-amend
@git-amend 9 ай бұрын
That is unexpected and very gracious - but I do not actually have anything like that yet. I'm happy to hear my videos helped you out, and I'm curious about your project. Once the channel is a little bit bigger, I have some ideas for some extra resources / rewards that might be of interest to people who want access to those kinds of things through something like Patreon, or maybe even a full course on these kinds of topics.
@anasmostefaoui3027
@anasmostefaoui3027 9 ай бұрын
@@git-amend I will be the first one to buy your full course, or support you on Patreon. My project is a university final project and your video helped me immensely advancing into building my shoot em' up. What I liked the most is how you apply the design patterns in game development, I usually use them in other software development area, seeing how you were able to implement them and get great value from it in game development was very nice to see and really exciting for me. Again, I'm very grateful for your work, I hope to see this channel grow and that your content get the audience it deserves.
@git-amend
@git-amend 9 ай бұрын
@@anasmostefaoui3027 Thanks for the kind words, and congrats on your final project. I'm very happy to hear that; it's very motivating to hear that a subscriber has benefited from the channel! I will certainly keep you posted on future developments!
@thebulletkin8393
@thebulletkin8393 3 ай бұрын
A very clear explanation, but I’m not sure on where this will actually be used. Putting a sword on a knight feels like something you could just assign in the editor beforehand. So would something like this just be used so that say you have a larger army in this rts style game, would it then be used to populate them with weapons at runtime?
@git-amend
@git-amend 3 ай бұрын
As your projects grow in complexity, you'll start wanting both to work from abstractions and also move more and more away from MonoBehaviour. The factory gives you the power to supply any interface, or multiple interfaces without tighlty coupling a Sword to your Player. Instead the factory determines what IWeapon to supply at run time, and that could be for all entities in your game. I forget the exact example I used, but the purpose is to decouple your game objects. If your Player just has a [SerializeField] Sword, they can only ever have a Sword. Try to see beyond the 'Weapon' example too though. You might have an ISaveSystem and a SaveSystemFactory that supplies a Json save module, but later you decide to change to Unity cloud save. You only have to change what the Factory supplies and not every single class that needs access to the save system.
@TheKr0ckeR
@TheKr0ckeR 5 ай бұрын
As I mentioned before, I generally love using C# regular classes like you do. You have created bow, sword etc. as a plain c# class. But how would you handle what "visual" item to activate when you created Sword, or Bow. For example when we you create BOW, our character should equip the bow. So where do you handle that logic or do you give the item as direct reference to the bow class? I hope i am clear what i am asking. This is a question for how to connect visual elements with pure c# classes, and that is a great example to ask that question. How should player know we equipped the bow and it will activate the required item's etc. I generally have this difficulty when i create factories as plain class and it doesnt know what to activate, ending up complexing stuffs and corrupt the code.
@git-amend
@git-amend 5 ай бұрын
Well, that's more than I can answer in a comment, but will be a topic of a future video.
@umoyGC
@umoyGC 7 ай бұрын
Hi Adam, I wonder if there is a possiblity in using this factory pattern for switching skinned mesh renderer "objects". I wanted to change Armor parts of a sinty studios model. my code is working so far but it is a giant mess of swich cases if the part is an arm or the helmet and so on. What do you think can be a good approach to that? Also using interfaces for the body parts or have you a better or "smoother" idea :) Thanks in advance for reading my comment :)
@git-amend
@git-amend 7 ай бұрын
Great comment, and perhaps a great topic for a future video, as I know this is a pain point for many people. While the Factory pattern is useful for creating objects, a more suitable pattern for this scenario could be the Strategy pattern. Here's a brief overview: The Strategy pattern is used to define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from objects that use it. In this context, each type of armor part (helmet, arm, etc.) could be treated as a strategy. You can create an interface, say IArmorPart, with a method like ApplyPart() or ChangePart(). Then, implement this interface in different classes representing different armor parts. This approach will remove the need for switch cases and will make the code more organized. Each armor part's behaviour is encapsulated in its respective class. You could still use a Factory to create your various Weapons and Armor, but when creating them, you also provide each with an appropriate Strategy that will contain the logic for applying themselves to your character(s). Small example: public interface IArmorPart { void ApplyPart(GameObject character); } public class PlayerEquipment : MonoBehaviour { public IArmorPart currentArmorPart; // or maybe Dictionary equipment; public void ChangeArmorPart(IArmorPart newArmorPart) { currentArmorPart = newArmorPart; currentArmorPart.ApplyPart(gameObject); } } [CreateAssetMenu(...)] public class HelmetPlacementStrategy : ScriptableObject, IArmorPart { public Mesh helmetMesh; public Material helmetMaterial; public void ApplyPart(GameObject character) { // Logic to actually change the armor on the character. // For example, find the helmet mesh renderer and apply the new mesh and material, // or activate/deactivate GameObjects. } } This way your various strategies determine what happens when you 'Apply' them to your character, and not a huge list of conditional statements. Hope that helps give you some ideas!
@umoyGC
@umoyGC 7 ай бұрын
Many thx for this amazing fast and detailed answer. I will track the video about strategy patterns and will try my best to update my code in a clean and efficient way. Thank you so much :) @@git-amend
@laserbean00001
@laserbean00001 7 ай бұрын
Love your anime art clickbaits
@git-amend
@git-amend 7 ай бұрын
Haha thanks!
@zerothehero.takeasip6612
@zerothehero.takeasip6612 8 ай бұрын
Niiice video! Gamedev youtube rarely goes beyond the novice level so it´s nice to see design patterns applied to Unity! Question about the abstract factory though. If you have an abstract factory, which from what I understand is just having a bunch of factories grouped in one place, then what is the point of having made those individual factories to begin with? Why not just make each of the create methods within the equipment factory and you save yourself from having to add references to the original factories? It was hard to see the use from your example. I think it would be good if you could show a 2nd more complex example for each of these design patterns to see their benefit more clearly. So many programming conventions seem useless at the simple level as simpler techniques would suffice and it isn´t until you expand that you realize their use. Hence, I don´t think there is anything with how you taught it but I was left a bit unsure of the benefits of the abstract factory with the example provided.
@git-amend
@git-amend 8 ай бұрын
Great to hear that you found the video helpful and are interested in diving deeper! You're right; design patterns like the Abstract Factory often show their true colors when the complexity of the system increases. To address your question: The value in having separate factories and then grouping them into an abstract factory lies in modularity, separation of concerns, and ease of extension. By keeping individual factories, you can specialize them for creating particular types of objects, which may involve complex instantiation logic that is best kept isolated. An Abstract Factory serves as an orchestrator that can produce a family of related objects by composing these specialized factories. In a game development context, imagine you're making a multi-theme game with "Forest" and "Desert" environments. Each environment has its own types of enemies, plants, and weather conditions. By having individual factories for each category (EnemyFactory, PlantFactory, WeatherFactory), and then using a "ForestAbstractFactory" or "DesertAbstractFactory" to group them, you can easily switch between environments by simply switching the abstract factory. Each specific factory already knows how to create enemies, plants, etc., specific to its environment. So, when you decide to add a new theme like "Ocean", you can easily extend the system by creating new individual factories and a new abstract factory without touching the existing code. This makes your code more maintainable and scalable.
@zerothehero.takeasip6612
@zerothehero.takeasip6612 8 ай бұрын
​@@git-amend I think I understand now, thank you! Though following up on your example, would it be recommendable to have the abstractEnvironmentFactories (forest, desert, and ocean) all inheret from one class that has all the factories or would you recommend another approach. I ask, cause I was curious about the organization of the elements within the factories and I know having too many inheretances can get messy quickly. Thoughts?
@git-amend
@git-amend 8 ай бұрын
@@zerothehero.takeasip6612 Great follow-up question! Like all engineering decisions, the answer is always, 'it depends!' Generally speaking, I would start with a base interface that your consumer class can use. For example, IEnvironmentStrategy could define methods for CreateEnemy, CreatePlant, and CreateWeather. This keeps things simple and doesn't add unnecessary layers of inheritance. If there are common behaviours or shared resources among all the environment factories, then having an additional base abstract class might make sense. The base class could implement some common logic and hold references to shared resources, even concrete sub-factories, if used by all types of environment factories. However, this approach does introduce an additional layer in your inheritance hierarchy, which, as you mentioned, could get messy if not managed carefully. I tend to only include an abstract base class if there are some common variables or resources needed by all concrete implementations of the interface - I start with the simplest way possible and only refactor to a higher level of complexity when the need arises. Often, you will find that once the concrete versions of your factory start to take shape, you'll find enough common elements to warrant a shared abstract class, at which point the refactoring is clear and easy to do.
@zerothehero.takeasip6612
@zerothehero.takeasip6612 8 ай бұрын
@@git-amend Thank you for the great reply, I am still trying to habitually implement these patterns into my coding. Keep up the good work!
Clean Code using the Strategy Pattern
12:34
git-amend
Рет қаралды 11 М.
Learn to Build an Advanced Event Bus | Unity Architecture
13:27
Children deceived dad #comedy
00:19
yuzvikii_family
Рет қаралды 7 МЛН
How to Code Behaviour Trees in Unity C#
23:19
git-amend
Рет қаралды 8 М.
Unity ile Flyweight Pattern
17:07
Berk Terek
Рет қаралды 851
Visitor: How I Mastered the Toughest Programming Pattern
12:59
Change Behaviors with the Strategy Pattern - Unity and C#
8:07
One Wheel Studio
Рет қаралды 38 М.
Additive Async Multi-Scene Loading in Unity
16:59
git-amend
Рет қаралды 9 М.
LEARN UNITY - The Most BASIC TUTORIAL I'll Ever Make
2:04:31
Imphenzia
Рет қаралды 3,1 МЛН
Dependency Injection, The Best Pattern
13:16
CodeAesthetic
Рет қаралды 756 М.
Better Singletons in Unity C#
14:08
git-amend
Рет қаралды 7 М.
WoT Blitz. Late Night Birthday Lotto + Gifts and Presents
1:7:55
World of Tanks Blitz
Рет қаралды 462 М.
СМОТРИ, КАКОЙ ВКУСНЫЙ ПИРОЖОК!
12:56
ViteC ► Play
Рет қаралды 1,1 МЛН