You're the only one who teaches about real-world stuff, Jason! Everybody can do a Pong game having just a few classes - things can't get too complicated. But making any bigger game requires better code architecture if you don't want to get lost after adding a few mechanics. Thank you for that! I learn a lot from your videos and I know this knowledge is applicable to a real-world development process, not like Brackey's "How to create Flappy Bird" videos where the whole game logic is being put in one class :D I hope you'll keep creating :)
Yeah, SO many tutorials out there that are just setting people up to fail. I am very much a Unity noob right now, but even I get incredibly frustrated seeing beginner tutorials that don't even point out the pitfalls that they are leading people into. Example would be a tutorial that shows how to do hit detection for a simple shooter without even bothering to destroy the bullet objects. Even a small game is going to have problems there. Sure you don't want to have to explain object pooling in a total newbie video, but at least state the basic concept so they know they have another thing to learn when the time comes.
@@Alluvian567 If a beginner tutorial described all the ways that they could make things better, the one following the tutorial will just be overwhelmed. You have to take it step by step.
Hey Jason, Static constructors are definitely a thing! They get executed the first time a static property or method is accessed or called, so would behave the exact same way as your initialization method. I also feel like generics would be a better fit for factories like these (and keep the reflection for the UI script e.g.), but that's a whole 'nother discussion. ;)
Love how your examples always have something fun and semi real world use. Other programming tutorials always have some stupid accounting software or something weird. Studying software development, so these videos are amazing at helping me understand the course material.
This has got to be my favorite video yet. This pattern is incredibly powerful. Jason said at the end "you cant shove this pattern into everything" but there is a part of me thinking, "watch me". :P This factory pattern is just really cool. The ease of extendibility is out of this world.
I really appreciate you doing those tutorial. I have searched and found countless of switch statement examples. This example with reflection usage is great. Thank you!
For anyone who's curious, you actually CAN have a constructor for a static class in C#. The syntax is pretty much the same as any other constructor, except it has to be marked static and ( as I currently understand it) cannot have an access modifier keyword, similar to an interface: public static class MyClass { static MyClass() { // code goes here } }
I would like to thank you for the awesome information you manage to relay in your videos, really helps roughing out some of the bad practices one might commit without prior knowledge to the use of some of these solutions, keep up the good work!
I do like your videos. You stay focused, and you keep the examples simple to show the core concepts and leave the complicating details to the comments. On that note... One thing I've found useful in creating factories is for any given type the factory can create to have the ability to specify that the type should always return a new instance or should return a cached singleton instance. Returning a singleton saves the overhead of creating a new instance. But of course that's not always the best approach, or may be the best approach only for some types the factory creates. Also as you touched on for a project of any size I would suggest using some sort of dependency injection that gives you the ability to swap out the types that will be created (whether that's a dependency injection library or just functionality implemented within your factory). Very handy for testing where you may want to mock some/all of the types the factory produces. Testing is just as important in games as it is in any other type of application 🙂
Thank you very much for all the knowledge you share with us, i've been trying to find these explanations and use cases for a long time, Game architecture can be so abstract and hard to understant for newbies, but you're a great teacher, very to the point and accesible. Gracias
Awesome video!! These kind of tutorials are hard to find--lots of great info here that's crucial for building an actual large-scale game, rather than making everything a Monobehavior. I'd love to see more!
The next level would be to make a pool of objects that can be reused for cases where the created instances become obsolete over time. This will greatly reduce GC time and overall performance when dealing with hundreds or thousands of complex objects.
Hey Jason, Thanks for the Tutorials! I had stepped through with the debugger to try to better understand what's going on... in InitializeFactroy() "type" already contains the Name string. Changed the line to abilitiesByName.Add(type.Name, type). Works without instantiating.
At 11:55 you say you can't have an constructor for an static class. That confuses me, because I use static constructors for static classes in my projects. These are automatically called, when the static class is used for the first time. Just followed your example and used the static constructor: static Factory() { ... } In there, I put your initialisation-code. Didn't know that for a long time, too. Saw it in a coursera video for the Unity Expert Gameplay Programmer Specialisation.
They don't work the same way. Static constructors will get called only once as soon as the program runs, no matter how many instances are created. You also can't use parameters or access modifiers. I'd stay away
Nice video but I don't like the idea of creating something to get the string with a name :) I would use attribute for that. Like: [AbbilityInfo(Name ="Health")] Not big of a deal, but looks cleaner. Thanks for video again.
imo it is way more effective to teach code like you do, explaining line for line and adding the background knowledge where necessary. Very nice teaching style, please more Pattern videos in context of game dev. Maybe some procedural generation
If you completely suck at UI, like me, and it never makes sense, you got lost at about 9:20.... ...To continue, add the panel in the heirarchy (create - > UI -> panel), then you add the button,
Thanks for the great video ! I do get how this patterns aims at making your life easier when expanding your project (you say so at the very beginning) but I'd like to know the pros and cons about building an ability system this way compared with Scriptable Objects or the new Prefabs (which are both pretty commun methods) thank you so much for all your hard work :)
What an awesome series of tutorials this was, really appreciated your work. I've been launched into a higher level of development skill. Thank you Jason. I've been going through your "SOLID in Unity & C#" series as well, and trying to figure out a way of converting the Finite State Machine into a pattern that honors the SOLID principles -mostly the Open/Closed Principle. But i've had no luck yet. Which has led me to ditching a FSM approach, and instead go for the state pattern explained in the Game Programming Patterns book you've recommended. Though unfortunately, i've ran into the same problem of failing to honor the SOLID principles when implementing the State Pattern. So what i really wanted to ask you, is if you could PLEASE cover the state pattern too. And how one goes about implementing it while honoring the SOLID principles. It would be an excellent addition to this playlist. Your biggest fan and student, Jude
Funny thing, i have watched this video roughly 12 times and given how half of those were during past year, its funny how i couldnt understand all the libraries he was using, so i didnt know where Type, Activator or Assembly were coming from... ;-; only now did i learn about it
One quick note, I wouldn't get the abilities by the reflection, I woul rather use an array for that. Why? Because if I have abilities that I want to toggle (enabled or not), I would have to make a second check inside the ability and change through code. Using an array would open the possibility of a non coder tweaking those values (or even dynamically adding abilities through code).
I have been trying to implement this myself and am having a hard time, I have probably watched the video 10+ times and have not seen where you show the AbilityButton Script. Without it the ButtonPanel script will not compile because it AbilityButton isn't defined. I tried stubbing it out with a basic class named AbilityButton and a method SetAbilityName but when I try to run this the line that instantiates the AbilityButton prefab fails with a null reference. This makes sense to me since all you did was declare buttonPrefab, it's value is never set in your code, so I don't understand how in your project the buttonPrefab is actually getting initialized. I also don't see a link anywhere in the description to a sample project.
If you wanted a factory for, let's say, different types of enemies, would you make a separate factory for them, or put them into the same factory as this along with your abstract enemy class?
@Jason, do you have a video or any suggestion to make a game with a lot of binding keys? Each key can trigger a different ability, like for example "Dragon Age: Origins" ?
How would this work when an ability uses 2 pre-existing abilities? For example, a new ring of fire spell which uses both the fire ability and damage self ability. You can only have one base class, so how would that work?
If you would implement IDispose to the abstract class, and then call it whenever you get an ability (also the dictionary would take a instance of each implementation of the abstract class), wont the program be more friendly to the GC?, or is this the only way factory pattern works?
Hello Jason, I've been following this series, and am grateful for the work you've put in. I've also been reading the book and following along with your videos. All these patterns have been super helpful, but there is one other pattern discussed in the book -called the State Pattern. I'm almost done understanding it, but wanted to know if it's a worthwhile pattern to know in Unity -since you haven't covered it in the series. Might your reasons be that the state pattern is insufficient, and that those you've covered are all we'll need thus far? I'm eager to hear from you. Cheers
Yes, I'll definitely cover that soon. It's a very important one IMO and I've talked about it in a few places but not in this series where it belongs yet :)
I'm with you on that request. It's hard to manage state and still honor the SOLID principles. I really hope Jason reads this (hi Jason), and can give us a video on the topic soon. This is maybe the best unity architecture channel on RUclips.
@@judehariot8076 Yep, i'm 100% with you on that one. Though you'll be glad to know that he already has a State Pattern video in the works. Got confirmation from him via email, so fingers crossed, hoping we'd see it next week. Cheers
If I were to make a moba or something similar in nature where different characters have a unique set of abilities, or even a game where abilities get unlocked throughout the game, would this be ideal? For instance, if I were remaking league of legends, I could in theory have one class for a skillshot, and on the individual character, house the projectile with distinct velocity, hitbox, etc.? Or would each unique character ability require it's own class?
I would use scriptable objects to construct any objects or pass any data. creating many classes for everything/spell/weapon isn't too useful in game programming I feel like.
Regarding performance like in mobile apps wouldn't it be better to avoid System.Reflection because it's kinda slow...? I'm currently using Reflection for creating several ScriptableObjects from a CustomEditor at once while feeding data from a CSV into these SOs, but not in runtime
My suggestion is to filter you reflection , for example filter by name spaces , eg put your ability under a name space , the reflection will look only there so it's faster .
Great video. I just would like to ask if in reflection ability example making the name a static string in Ability and hiding the base string in Children with "static new string" would be a valid way to solve the name problem - to avoid instantiating? What do you think? Thanks!
Hey Jason, I know this is an older video but I'd like to ask what made the reflection factory more adherent to the open-closed principle? It's still looking for abilities by name, but now it's in a dictionary and all of them are mapped once you declare the class. You're pretty much cutting the switch case and the case creation from each new ability. Edit: In this scenario you didn't have to change the player because you're iterating the ability list to have each ability, but in most cases you'd have a customized call
Personally I would have used Generics instead of reflection. public class AbilityFactory { public T GetInstance() where T: Ability, new() { return new T(); } }
In that case you'd be instantiating and generating extra garbage for the gc. The goal of the reflection part was just to keep single instances of them and use them from data, without having to add code in multiple spots for every new type. Also came from a scenario with over 100 types now where they're constantly getting added. That said, I do love generics tho :)
Quick question about reflection and performance. I come from an Android mobile app background and always feel that reflection is pretty slow. Can this become a problem in C# on usual consumer machines? Or might this be a problem when the target platform is mobile? Is C# reflection very slow? Saw you using reflection many times now. You know what you are doing, but I am just asking to be certain.
Greetings, really liked the video, and I'm now trying the pattern. One question I have now is how to go about having a sprite icon for the ability to put on the UI button
Greetings Jason, I'm lucky to have found your work. Are you planning more videos covering the patterns mentioned in Robert Nystrom's "Game Programming" book? If so, then i'm definitely looking forward to them. I'd also like to suggest a video on how to manage state. The book discusses the topic, but makes use of switch statements. Which after having gone through your SOLID principles series, seems a little bad in practice. Especially if the number of states grow beyond 5. I can imagine states increasing over time, and the switch statement having to grow in its case clauses -ugly business. Any way, i'd be interested to see how you'd implement something a long the lines of the problem i just briefly discussed. Thank you, and please take care.
I try to use factory pattern and there're too many if.. else to classify type. and i found this solution :D. Thank you!! but is this stable for mobile device? using reflection is good in runtime?
I love to learn about things like this. But I have to say, I still don't really understand why I would need such a factory to return me objects, when I can just instantiate them directly.
Couldn't you just use a static constructor for the static Factory instead of the InitializeFactory Method? Then you wouldn't need to check whether it was already initialized and wouldn't have to call that initialize because that happens automatically before the dictionary is first used.
In this example I'd say scriptable objects would work better. MyAbility extends Ability and Ability holds Execute() and extends ScriptableObject. Then create instances of unique abilities and reference specific abilities via inspector. Unity even will pop up all abilities containing in project. No reflection needed, no ugly string refs, nice preview of all abilities in project and you may also find usages of specific abilities in the project
@@Ne0mega Sure. I currently use it for items. Designer can create new items in a few clicks and assign them to containers etc, no additional code needed. You can also create custom inspectors for SO. There is a few incredible videos and I think any unity developer should watch them (and maybe not once) ruclips.net/video/raQ3iHhE_Kk/видео.html ruclips.net/video/6vmRwLYWNRo/видео.html
@@AndreyDeadcow Ive watched both of those... I've watched Richard Fineman's at least 4 times now. :P So far only finished one scriptable object tutorial. Failed on this one: ruclips.net/video/cHUXh5biQMg/видео.html I should try it again. I tried it about 5 months ago now. Learned a lot since. It all fell apart right a the end for me last time.
the asset you create from single ScriptableObject class share the same logic and you cant chaneg it for each instance , it must be the same , value yeah but behavior , nope! you will end up creating a new scriptableObject class for each ability just to overide the logic , so you are back to this video implemeantion .
@@The28studio Yeah, in case of implementation you described SO is not the best fit, but I assume it's better to create abilities in more generic way. Like, ability is just set of commands, and commands is generic bits of logic and may be grouped in abilities. This way you'll get max power without code edition and also reduce code duplication
The reflection is still needed to get the actual types (normally I do it with an enum instead of a string though). The reflection cost is tiny though since it's a one time setup thing only. Generally people talk about avoiding reflection, but that's when it's somewhere in the hot path of code that is running often (every frame/more/etc). For simple setup like this it's completely fine :)
@@Unity3dCollege I took another look at what I have done and I am using Activator.CreateInstance, which I am not sure of performance difference from your example. Incorporating it into your code it would look something like below. Let me know what you think. public abstract class Ability { public abstract void Process(); } public class StartFireAbility : Ability { public override void Process() { //GameObject.FindObjectOfType().ShowParticle(0); Debug.Log("Ability triggered"); } } public static class AbilityFactory where TAbility : Ability { public static void ActivateAbility() { var tAbility = typeof(TAbility); var ability = (TAbility)Activator.CreateInstance(tAbility); ability.Process(); } } Usage: AbilityFactory.ActivateAbility();
It's funny, the official Microsoft dependency injection framework is called "Unity" (though Ninject is also pretty good). Why not just use one of those? I haven't tried yet, but it makes me wonder if NuGet works with Unity...
I definitely have the same question. I would assume the first try for a green field project will be to use a dependency injection library or framework, he mentioned that has conflicts with Unity, I wonder what are those conflicts/issues.
Good to see this kind of videos man, Sometimes is hard to visualize new patterns without good examples
Glad it was helpful! :)
Thanks!
Yup, the examples do incredibly much when it comes to understanding the subject, which is one reason why i love his videos.
You're the only one who teaches about real-world stuff, Jason! Everybody can do a Pong game having just a few classes - things can't get too complicated. But making any bigger game requires better code architecture if you don't want to get lost after adding a few mechanics. Thank you for that! I learn a lot from your videos and I know this knowledge is applicable to a real-world development process, not like Brackey's "How to create Flappy Bird" videos where the whole game logic is being put in one class :D I hope you'll keep creating :)
'How to create Flappy Bird' is useful for beginners. Brackey's tutorials have their place.
Yeah, SO many tutorials out there that are just setting people up to fail. I am very much a Unity noob right now, but even I get incredibly frustrated seeing beginner tutorials that don't even point out the pitfalls that they are leading people into. Example would be a tutorial that shows how to do hit detection for a simple shooter without even bothering to destroy the bullet objects. Even a small game is going to have problems there. Sure you don't want to have to explain object pooling in a total newbie video, but at least state the basic concept so they know they have another thing to learn when the time comes.
@@Alluvian567 If a beginner tutorial described all the ways that they could make things better, the one following the tutorial will just be overwhelmed. You have to take it step by step.
if you think that any programmer worth something would actually use pre-determined "patterns" like this you're out of your mind.
Yes, this exactly.
Hey Jason,
Static constructors are definitely a thing! They get executed the first time a static property or method is accessed or called, so would behave the exact same way as your initialization method.
I also feel like generics would be a better fit for factories like these (and keep the reflection for the UI script e.g.), but that's a whole 'nother discussion. ;)
I can‘t tell why, but it is quiet satisfying to watch those patterns work.
Most underrated channel ever. Thanks for your tutorials.
Love how your examples always have something fun and semi real world use. Other programming tutorials always have some stupid accounting software or something weird.
Studying software development, so these videos are amazing at helping me understand the course material.
the reflection part blew my mind!
This has got to be my favorite video yet. This pattern is incredibly powerful. Jason said at the end "you cant shove this pattern into everything" but there is a part of me thinking, "watch me". :P This factory pattern is just really cool. The ease of extendibility is out of this world.
Jason you're the best source for Unity devs, even better than their documentation lol
I’ve been looking for a good tutorial on the factory pattern and I really liked that this was using unity much appreciated
Thanks for another interesting video. I'd love to see more pattern videos like this!
I'm watching your videos and I don't even work with game dev. But the concepts you teach are universal in the software engineering
It's very helpful to see how you use the patterns in real unity examples!!
I really appreciate you doing those tutorial. I have searched and found countless of switch statement examples. This example with reflection usage is great. Thank you!
For anyone who's curious, you actually CAN have a constructor for a static class in C#. The syntax is pretty much the same as any other constructor, except it has to be marked static and ( as I currently understand it) cannot have an access modifier keyword, similar to an interface:
public static class MyClass
{
static MyClass()
{
// code goes here
}
}
Great to see these patterns applied to games/Unity. Going to binge watch the others now...
Great as always Jason. Appreciate you.
Very welcome!
Thanks a lot! There aren't many good unity design pattern tutorials out there. This really helped!
Thank you for such an interesting and important content, Jason! Can't wait to see next episodes.
I would like to thank you for the awesome information you manage to relay in your videos, really helps roughing out some of the bad practices one might commit without prior knowledge to the use of some of these solutions, keep up the good work!
I do like your videos. You stay focused, and you keep the examples simple to show the core concepts and leave the complicating details to the comments. On that note...
One thing I've found useful in creating factories is for any given type the factory can create to have the ability to specify that the type should always return a new instance or should return a cached singleton instance. Returning a singleton saves the overhead of creating a new instance. But of course that's not always the best approach, or may be the best approach only for some types the factory creates. Also as you touched on for a project of any size I would suggest using some sort of dependency injection that gives you the ability to swap out the types that will be created (whether that's a dependency injection library or just functionality implemented within your factory). Very handy for testing where you may want to mock some/all of the types the factory produces. Testing is just as important in games as it is in any other type of application 🙂
Wow I loved the reflection examples!!
Thank you very much for all the knowledge you share with us, i've been trying to find these explanations and use cases for a long time, Game architecture can be so abstract and hard to understant for newbies, but you're a great teacher, very to the point and accesible. Gracias
Awesome video!! These kind of tutorials are hard to find--lots of great info here that's crucial for building an actual large-scale game, rather than making everything a Monobehavior. I'd love to see more!
Cool video. Learning to implement desing patterns in unity have been complicated for me jajaja
The next level would be to make a pool of objects that can be reused for cases where the created instances become obsolete over time. This will greatly reduce GC time and overall performance when dealing with hundreds or thousands of complex objects.
learned factory pattern and ability system at the same time thanks
Thanks! Great class. But why reflection and strings instead of a generic method taking Ability derived type. Or an interface?
Excellent! I really like seeing code that is implemented in this fashion. Thank you.
Hey Jason, Thanks for the Tutorials! I had stepped through with the debugger to try to better understand what's going on... in InitializeFactroy() "type" already contains the Name string. Changed the line to abilitiesByName.Add(type.Name, type). Works without instantiating.
At 11:55 you say you can't have an constructor for an static class. That confuses me, because I use static constructors for static classes in my projects. These are automatically called, when the static class is used for the first time. Just followed your example and used the static constructor:
static Factory() {
...
}
In there, I put your initialisation-code. Didn't know that for a long time, too. Saw it in a coursera video for the Unity Expert Gameplay Programmer Specialisation.
They don't work the same way. Static constructors will get called only once as soon as the program runs, no matter how many instances are created. You also can't use parameters or access modifiers. I'd stay away
I just love these architecture videos, mann!
Great work!
Going to check out your DI vid next.
For the string ability type I would go for enums => more accurate and clear. Also here it could be better to use interfaces over abstract class.
Nice video but I don't like the idea of creating something to get the string with a name :)
I would use attribute for that. Like:
[AbbilityInfo(Name ="Health")]
Not big of a deal, but looks cleaner. Thanks for video again.
Great video! I want to learn more about patterns and these videos are very helpful.
You are a rockstar, sir.
another awesome video with great practical examples. Thank you.
imo it is way more effective to teach code like you do, explaining line for line and adding the background knowledge where necessary. Very nice teaching style, please more Pattern videos in context of game dev. Maybe some procedural generation
I really like these kinds of videos!
Oohhh yeah.
This is why i'm here!!! ❤😁😁
Thank you very much for the great tips and explanations. It helped a lot! :)
Great video Jason, very informative.
cheers man, this is a really useful tute
Thanks for wonderful sharing. Really like your videos about pattern. I've learned a lot.
Thank you! Very clear explanation!
If you completely suck at UI, like me, and it never makes sense, you got lost at about 9:20.... ...To continue, add the panel in the heirarchy (create - > UI -> panel), then you add the button,
This has been very helpful.
Thanks for the great video !
I do get how this patterns aims at making your life easier when expanding your project (you say so at the very beginning) but I'd like to know the pros and cons about building an ability system this way compared with Scriptable Objects or the new Prefabs (which are both pretty commun methods)
thank you so much for all your hard work :)
By far one the patterns I use the most
Hey Jason good use of Reflection too. Thanks!
It will be great if you cover how c# reflection can be used in Game Architecture in detail
Great explanation. Thanks!
What an awesome series of tutorials this was, really appreciated your work. I've been launched into a higher level of development skill. Thank you Jason. I've been going through your "SOLID in Unity & C#" series as well, and trying to figure out a way of converting the Finite State Machine into a pattern that honors the SOLID principles -mostly the Open/Closed Principle. But i've had no luck yet. Which has led me to ditching a FSM approach, and instead go for the state pattern explained in the Game Programming Patterns book you've recommended. Though unfortunately, i've ran into the same problem of failing to honor the SOLID principles when implementing the State Pattern. So what i really wanted to ask you, is if you could PLEASE cover the state pattern too. And how one goes about implementing it while honoring the SOLID principles. It would be an excellent addition to this playlist.
Your biggest fan and student,
Jude
ruclips.net/video/nqAHJmpWLBg/видео.html this will solve your open closed thingy btw, in case you still wondering 😋
Funny thing, i have watched this video roughly 12 times
and given how half of those were during past year, its funny how i couldnt understand all the libraries he was using, so i didnt know where Type, Activator or Assembly were coming from...
;-; only now did i learn about it
Why not create a static constructor to contain what InitialiseFactory does at 12:50?
Thanks for such quality and usefull content. Thank you!
One quick note, I wouldn't get the abilities by the reflection, I woul rather use an array for that.
Why?
Because if I have abilities that I want to toggle (enabled or not), I would have to make a second check inside the ability and change through code. Using an array would open the possibility of a non coder tweaking those values (or even dynamically adding abilities through code).
I don't like this kind of video. I *love* this kind of video. Thanks, Jason!
I have been trying to implement this myself and am having a hard time, I have probably watched the video 10+ times and have not seen where you show the AbilityButton Script. Without it the ButtonPanel script will not compile because it AbilityButton isn't defined. I tried stubbing it out with a basic class named AbilityButton and a method SetAbilityName but when I try to run this the line that instantiates the AbilityButton prefab fails with a null reference. This makes sense to me since all you did was declare buttonPrefab, it's value is never set in your code, so I don't understand how in your project the buttonPrefab is actually getting initialized. I also don't see a link anywhere in the description to a sample project.
If you wanted a factory for, let's say, different types of enemies, would you make a separate factory for them, or put them into the same factory as this along with your abstract enemy class?
Have you considered using generics for these kinda things? would love to see your take on it =)
@Jason, do you have a video or any suggestion to make a game with a lot of binding keys?
Each key can trigger a different ability, like for example "Dragon Age: Origins" ?
How would this work when an ability uses 2 pre-existing abilities? For example, a new ring of fire spell which uses both the fire ability and damage self ability. You can only have one base class, so how would that work?
If you would implement IDispose to the abstract class, and then call it whenever you get an ability (also the dictionary would take a instance of each implementation of the abstract class), wont the program be more friendly to the GC?, or is this the only way factory pattern works?
Ooh... I learned something new with that "getter" pattern. ( Name => "name"; )
is there anytime in the video where u show the abilityButton script? i couldnt find it
Hello Jason,
I've been following this series, and am grateful for the work you've put in.
I've also been reading the book and following along with your videos. All these patterns have been super helpful, but there is one other pattern discussed in the book -called the State Pattern. I'm almost done understanding it, but wanted to know if it's a worthwhile pattern to know in Unity -since you haven't covered it in the series. Might your reasons be that the state pattern is insufficient, and that those you've covered are all we'll need thus far?
I'm eager to hear from you.
Cheers
Yes, I'll definitely cover that soon. It's a very important one IMO and I've talked about it in a few places but not in this series where it belongs yet :)
@@Unity3dCollege Okay good to hear. I'll be looking out for your video then.
Cheers
I'm with you on that request. It's hard to manage state and still honor the SOLID principles. I really hope Jason reads this (hi Jason), and can give us a video on the topic soon. This is maybe the best unity architecture channel on RUclips.
@@judehariot8076 Yep, i'm 100% with you on that one. Though you'll be glad to know that he already has a State Pattern video in the works. Got confirmation from him via email, so fingers crossed, hoping we'd see it next week.
Cheers
ScriptableObjects are also about Abilities in Games. So when we should prefer Factory pattern instead of Scriptableobjects?
Thank you for making this video...
If I were to make a moba or something similar in nature where different characters have a unique set of abilities, or even a game where abilities get unlocked throughout the game, would this be ideal?
For instance, if I were remaking league of legends, I could in theory have one class for a skillshot, and on the individual character, house the projectile with distinct velocity, hitbox, etc.? Or would each unique character ability require it's own class?
I would use scriptable objects to construct any objects or pass any data. creating many classes for everything/spell/weapon isn't too useful in game programming I feel like.
A suggestion, this, but this time with mono scripts to install custom classes onto a scriptable object.
how does the abilitybutton script work? So how do I actually call an ability? I would be glad if someone can help me
private void OnClick() { AbilityFactory.GetAbility("the name").Process();}
This was interesting!
Regarding performance like in mobile apps wouldn't it be better to avoid System.Reflection because it's kinda slow...? I'm currently using Reflection for creating several ScriptableObjects from a CustomEditor at once while feeding data from a CSV into these SOs, but not in runtime
My suggestion is to filter you reflection , for example filter by name spaces , eg put your ability under a name space , the reflection will look only there so it's faster .
Great video. I just would like to ask if in reflection ability example making the name a static string in Ability and hiding the base string in Children with "static new string" would be a valid way to solve the name problem - to avoid instantiating? What do you think? Thanks!
Would be great if you could show your AbilityButton Script. Thanks!
Hey Jason. When are you going to make more of the Design Pattern tutorials in the series?
Definitely! Is there one you wanna see next?
Hey Jason, I know this is an older video but I'd like to ask what made the reflection factory more adherent to the open-closed principle?
It's still looking for abilities by name, but now it's in a dictionary and all of them are mapped once you declare the class.
You're pretty much cutting the switch case and the case creation from each new ability.
Edit: In this scenario you didn't have to change the player because you're iterating the ability list to have each ability, but in most cases you'd have a customized call
Personally I would have used Generics instead of reflection.
public class AbilityFactory
{
public T GetInstance() where T: Ability, new()
{
return new T();
}
}
In that case you'd be instantiating and generating extra garbage for the gc. The goal of the reflection part was just to keep single instances of them and use them from data, without having to add code in multiple spots for every new type. Also came from a scenario with over 100 types now where they're constantly getting added.
That said, I do love generics tho :)
I like the explanation, but it would have been nice if there was an example I could relate to.
You can have a static constructor in C#, otherwise good video.
It's not possible to use this pattern, if your abstract class inherits from MonoBehaviour -- is it ?
Quick question about reflection and performance. I come from an Android mobile app background and always feel that reflection is pretty slow. Can this become a problem in C# on usual consumer machines? Or might this be a problem when the target platform is mobile? Is C# reflection very slow? Saw you using reflection many times now. You know what you are doing, but I am just asking to be certain.
Nevermind. I just realized that you use reflection only for instantiation and not on Update.
Greetings, really liked the video, and I'm now trying the pattern. One question I have now is how to go about having a sprite icon for the ability to put on the UI button
Greetings Jason,
I'm lucky to have found your work. Are you planning more videos covering the patterns mentioned in Robert Nystrom's "Game Programming" book? If so, then i'm definitely looking forward to them. I'd also like to suggest a video on how to manage state. The book discusses the topic, but makes use of switch statements. Which after having gone through your SOLID principles series, seems a little bad in practice. Especially if the number of states grow beyond 5. I can imagine states increasing over time, and the switch statement having to grow in its case clauses -ugly business. Any way, i'd be interested to see how you'd implement something a long the lines of the problem i just briefly discussed.
Thank you, and please take care.
The State pattern is the next one I'm doing from there :) Should be out sometime this month
@@Unity3dCollege
That's great.
I'm genuinely looking forward to it.
Keep it up. Cheers.
I try to use factory pattern and there're too many if.. else to classify type. and i found this solution :D. Thank you!! but is this stable for mobile device? using reflection is good in runtime?
Can anyone tell me what's in the "AbilityButton" Script?
good stuff!
Fantastic.
I love to learn about things like this. But I have to say, I still don't really understand why I would need such a factory to return me objects, when I can just instantiate them directly.
what if we just want the object to appear on the screen? (rather than an ability)
Couldn't you just use a static constructor for the static Factory instead of the InitializeFactory Method? Then you wouldn't need to check whether it was already initialized and wouldn't have to call that initialize because that happens automatically before the dictionary is first used.
Subbed, do you plan on doing any videos on Unity Tiny?
In this example I'd say scriptable objects would work better. MyAbility extends Ability and Ability holds Execute() and extends ScriptableObject. Then create instances of unique abilities and reference specific abilities via inspector. Unity even will pop up all abilities containing in project. No reflection needed, no ugly string refs, nice preview of all abilities in project and you may also find usages of specific abilities in the project
Have you tried this? I'd love to be able to make in game customizable spells and abilities that just mix shape, element, power, duration, etc...
@@Ne0mega Sure. I currently use it for items. Designer can create new items in a few clicks and assign them to containers etc, no additional code needed. You can also create custom inspectors for SO. There is a few incredible videos and I think any unity developer should watch them (and maybe not once)
ruclips.net/video/raQ3iHhE_Kk/видео.html
ruclips.net/video/6vmRwLYWNRo/видео.html
@@AndreyDeadcow Ive watched both of those... I've watched Richard Fineman's at least 4 times now. :P So far only finished one scriptable object tutorial.
Failed on this one: ruclips.net/video/cHUXh5biQMg/видео.html
I should try it again. I tried it about 5 months ago now. Learned a lot since. It all fell apart right a the end for me last time.
the asset you create from single ScriptableObject class share the same logic and you cant chaneg it for each instance , it must be the same , value yeah but behavior , nope!
you will end up creating a new scriptableObject class for each ability just to overide the logic , so you are back to this video implemeantion .
@@The28studio Yeah, in case of implementation you described SO is not the best fit, but I assume it's better to create abilities in more generic way. Like, ability is just set of commands, and commands is generic bits of logic and may be grouped in abilities. This way you'll get max power without code edition and also reduce code duplication
Bit complicated bit it works .
Can't you avoid the type reflection by using an enum argument instead of a string?
The reflection is still needed to get the actual types (normally I do it with an enum instead of a string though). The reflection cost is tiny though since it's a one time setup thing only. Generally people talk about avoiding reflection, but that's when it's somewhere in the hot path of code that is running often (every frame/more/etc). For simple setup like this it's completely fine :)
enum or string you still have to open the file when you have to add new abilities there by violating the Open/Close Solid principle.
@@Unity3dCollege Or couldn't you use generics to call an ability by specifying a class name?
@@truedox I'm not sure how that would work, can you link an example when you get a minute so I can check out what you're thinking?
@@Unity3dCollege I took another look at what I have done and I am using Activator.CreateInstance, which I am not sure of performance difference from your example. Incorporating it into your code it would look something like below. Let me know what you think.
public abstract class Ability {
public abstract void Process();
}
public class StartFireAbility : Ability
{
public override void Process()
{
//GameObject.FindObjectOfType().ShowParticle(0);
Debug.Log("Ability triggered");
}
}
public static class AbilityFactory where TAbility : Ability
{
public static void ActivateAbility()
{
var tAbility = typeof(TAbility);
var ability = (TAbility)Activator.CreateInstance(tAbility);
ability.Process();
}
}
Usage:
AbilityFactory.ActivateAbility();
It's funny, the official Microsoft dependency injection framework is called "Unity" (though Ninject is also pretty good). Why not just use one of those? I haven't tried yet, but it makes me wonder if NuGet works with Unity...
I definitely have the same question. I would assume the first try for a green field project will be to use a dependency injection library or framework, he mentioned that has conflicts with Unity, I wonder what are those conflicts/issues.
What is Type in the dictionary?
Thanks!