This is called the pub/sub pattern. It's only one of many, many ways to do message passing in OOP, and definitely not the end-all be all. The pro is it's simple, but the cons are it's relatively slow and very difficult to scale without major maintainability costs. Great for small projects!
Před rokem+126
Be careful about the static fields. They are preserved between level loads which may cause problems. It is called a "singleton design pattern", look it up for more information.
@@filipe_lopes It is a hard generic question to be answered in one youtube comment. If you are making your first game with a couple of scenes and scripts, you are fine with it. When you start feeling friction and increasing commitment to it, you are mature enough to google for different way how to solve your problem without using statics. Is it understandable at least a bit? :-)
I've been searching for this video for so long. The perfect explanation that tied all of my entry level programming knowledge together in a nice bow. Thank you so much !!
Live it, it's so detailed and I haven't seen any other tutorial like this. I had no idea why you would even need events, but now I think they are the most useful thing and I going to start learning them
I swear to GOD! I used unity for 3 years without using events (I just had references for everything I wanted to access), but I recently took the plunge and learned them & their workflow, And they're sooo useful.
lol. I liked the video, then read the caption about taking a shot every time you said ball.... and I was sold on subscribing. That is the solid comedy.
You explained the Unity static class and event concepts very clearly. I had trouble understanding the specifics from the Unity chapter alone, but this filled in several gaps. Thank you!
That was the slickest way I've ever heard for telling me to subscribe. Absolutely brilliant! Also great tutorial, I'll definitely be referencing this at a later date when I'm ready to tackle this in my own projects.
THANK YOU!! this has helped so much, it was one of those thing that i’ve been struggling to understand for so long and this is the only video that actually explained it in a way that makes everything make sense
While the singleton pattern is an easy way to reference other objects it is considered an 'anti-pattern'. This is because it violates some key design principles and makes changes down the line harder to implement. Other design patterns which are a bit more complex to understand and implement but once implemented they can make things so much easier and safer down the track. If you are interested have a look into the Dependency Injection (DI) pattern, once setup it can be amazing. Remember, depending on the project, some patterns are better than others. This pattern may be fine for small projects.
There is absolutely nothing wrong with the singleton pattern, people keep repeating this myth over and over but it is just false. As I have become more experienced, I have only been using *more* singletons than before. Singletons CAN be misused, but they are not inherently bad. It makes way more sense in some scenarios to have singletons than have to connect every class to every other class and deal with dependency hell.
@@ChanDawg86 More like it took me years to discover and start practically using them. I'm self-taught, so I would come up with duck tape solutions and stubbornly stick to them because a solution is a solution, right? I now know that the answer to that is no lol I even came up with my own janky version of the Singleton pattern that didn't use the static keyword.
I swear the CZcams algorithm can see into the future. I had some issues with stuff I was doing for a project so I approached one of my teachers, he didn't have a lot of time at that moment, but he explained me some things and told me I should look into events. This video was recommended to me a few weeks prior to that conversation...
No. Singletons are not the way, nor will they ever be. You need a combination of dependency injection and dependency inversion to handle cases like this. If your balls depend on some methods provided by the manager to function, inject the manager in the ball class when spawning them. If your balls invoke behavior of manager when certain actions are taken, use events from them and have the manager subscribe to each as it spawns the ball. P.S. I’ve not seen your channel before, but I would prefer to have less people out there mentioning singletons as a solution to anything. It is almost never a good decision and will cause almost unsolvable issues in the future
Dependency injection is something I wanted to cover but decided the focus would be on events; I agree dependency injection in this case would work well! Be careful about completely ruling out singletons, while I understand the controversy around them, they have their place in certain situations.
@@Dfjs427 I think of it less as situations they could be avoided and more as situations they could be used without abusing them. Sure, in most cases you can find a way around using them, but in some situations I haven't found them to be problematic to use. For example, logger classes you could find a way to avoid them, but is it necessary? I haven't yet been burned by singletons so badly that I've completely sworn off them, but who knows, perhaps in the future I'll have a particularly traumatic experience😉
While this is true, unfortunately Unity is built in a way that simply makes the singleton anti-pattern easier. Instantiating a prefab does not have a simple good way to do dependency injection (at least that I know of). I've seen solutions that ranged from building a specific factory per prefab (requiring compiling all dependencies into one place with no automated tooling), to reflection on a tree search of the prefab. You can clutter your scene with hidden objects that you clone, rather than prefabs, losing you the benefit of them. In an ideal world, Unity would scan a prefab for dependencies to be injected when it is turned into a prefab, and automatically attempt to resolve those dependencies when that prefab is referenced in the editor, but it doesn't do that. Instead objects are spawned with nothing injected, and no references to any non global object, including the script that spawned it. We are forced to have at least one singleton if we want to link it. Using singletons we can at least make it work, and work efficiently. It's biggest problem is that it doesn't scale, and often that doesn't matter. Yes it stinks, but sometimes that is the cost of working in a codebase you didn't write. You absolutely don't NEED anything else, particularly when 'best practice' is fighting the existing code.
@@Dfjs427 Who hurt you? Show me your released game titles with credits that cross reference to you clearly. I think you're likely a peasant who has never released anything worthwhile and just like to spout regurgitated bullshit you've read on some threads. Negativity without example destroys any credibility you have. Stay small, manlet.
For every beginners watching this video, please don't take it as a good practice (I mean it). This is actually the opposite, and you should absolutely avoid to program like this. Let me explain a bit more : Singleton design pattern (ensuring that a class has a single instance, and providing a global access point to this instance ) is what the creator wants to show you. First, the singleton pattern is not correctly designed, and doing like it's done in the video can lead to errors. Exposing global variables like that, accessible everywhere in the code, is of course the easiest (read : laziest) way to make components communicate. The biggest issue with that, is the control flow of your application. In the example that is shown in the video, it is all fun and games, everything works properly, because it is a super simple example, with a manager and a ball. Let's say you want to create a big project, with NPCs, World Building, Quest system, inventory etc etc ... If you design your application like this, it means that every system you create, has the possibility to communicate with every other systems of the application. As the project will grow, this will (100%) lead to systems that should have no connection whatsoever communicating together, and therefore, create an absolute undebuggable / unscalable project. The way to go, is first to read actual real books or articles about software design before going to youtube for some obscure tutorials. Advice number one, and probably the most important : learn the SOLID principles , apply it whenever you can. Learn about inversion of control, read articles about design patterns that are ACTUALLY real scalable, good practices. Of course it seems harder, but if you really want to progress, and make real projects, this is the only way to go. And basically, every "problems" that the creator thinks he is solving by using a singleton are actually only problems when you don't know how to handle them (this is no criticism, just a fact). First example : when he says "If you have a lot of balls that you want to communicate, it is tedious to assign them in the editor manually". Solution : Create a serialized array of balls. You can then select them all in the editor, and drag and drop directly to the ball manager script. Second : When he says "If the manager instantiates a ball, he won't be able to communicate with it" : Wrong ! Create a prefab of the ball, with the script Ball attached on it , and do like this in the manager : [SerializeField] private Ball ballPrefab; void OnEnable() { Ball ball = Instantiate(ballPrefab); ball.DoSomething(); } It is as simple as that. If you want to create multiple balls, iterate through an array of the size you want, and instantiate the number of balls you want (and it is actually not even the best way to do that, a pooling system is better to avoid garbage collection overhead, but this is another topic). If you want to keep a reference to the balls in the scene, create a list at the top of the class, and add the balls that you instantiated to this list. I hope this will help a poor soul seeking for answer about unity, which is of course a big, complex topic ! But please, don't take advices like this, this is bad practice. Read before youtube ;)
Because almost every tutorial creator is a beginner themself who spews regurgitated content and has no computer science background or a subject matter expert level experience in Unity. They know that the beginner stage gets the most views, so they are content with showing people how to make a sprite jump and collide and maybe update some text on the screen. 90% of people will quit after that point, so why try hard for 10% viewer retention.
The singleton pattern is okay, but one bad thing about it is that it results in a big spider web of dependencies. Of course, other design patterns also have their downsides but I prefer the observer design pattern. It doesn't get rid of all dependencies, but at least it redirects all unnecessary dependencies to a single, manageable place using event listeners.
Lovely tutorial, very clear and high quality. The only issue though is that you are showing a practice that becomes quicky problematic without mentioning it. Why is it problematic ? - Singleton causes spaghetti code and quickly make classes impossible to use outside of a particular context ( create dependencies). It's a good pattern to start, but I would advice to look for other patterns as well to have more solutions in your toolbox (useful ones are scriptable object architecture or Dependency injections for example). Feel free to check out my tutorial about scriptable object architecture if you are interested in original way to pass data in Unity. Also, instead of having the static events in the BallManager you could try a new static GameEvent class. This way you have one location for all your events (you can even make categories) and classes subscribing to those events are decoupled from a specific class but coupled to the bridge : GameEvents. Granted, in your example there is not much going on, but in a bigger game in might be useful. Continue the good videos 👍
Thanks very much! Yeah I tend to keep my events in a static event class since I think it's cleaner to keep them all in one place rather than in disparate scripts
dude he's literally just showing you how he built up to usinng Events. We all know Static classes are Bad, you aren't some genius comoing over here to tell us something we don't know.
No we don't all know it, matter of fact its still very used everywhere. Most tutorials use it ^^. I never said I was a genius, I just commented on his video. Also, I never said they were bad, I just mention that a Singleton can create unwanted dependencies.
You don't advertise on someone else's channel. Especially when your content is so bad. SOAP is WAY more coupled than a global event manager. Get out of here. Reported for advertising on other channels.
@@newf_gg1230 I see, yeah maybe I should not have suggested my channel. I was merely trying to guide to other solutions and I know, by experience that SO architecture works well for decoupling. I am not sure I understand why you would say its way more coupled. Curious to know your stance and where that comes from.
I cant thank you enough for this tutorial , everywhere I see is only beginner tutorial , it was something I really needed as intermediate programmer , also if u can suggest some more like these not the beginner ones , which are essential for unity.
Static instances can be very useful if you only ever want to have one object of a given type active, it's called the singleton design pattern, and I use it all the time, however something to be aware of is that static variables persist between scenes and if you load a new scene without an instance of that type and a script tries to access it it will return null since that particular object instance doesn't exist anymore. I also like to set it up so any instance of that class that is created after the Instance field has been assigned is destroyed, this isn't necessary but it does give you one less way to accidentally break your code. Here's how I tend to write singletons when coding for Unity projects: private static MyClass instance; public static MyClass Instance { get{ return instance: } } private void Awake() { if(instance != null && instance != this) { Destroy (this.gameObject); } else instance = this; } Something to note is that I set this in awake so you need to get it in Start or later.
You don't have to assign them in the editor, you can do that at runtime just fine. Ballmanager can Instantiate balls and keep the references in a List/Array or even as simple children if you choose Ballmanager as their parent. So then you have full control over enabling/disabling them. No need to manually numerate them in the inspector or such.
I think I watched this video a year ago, and I didn’t understand it at all. Recently I’ve been working on a lite RTS game with 100s of different objects, systems, managers. I have actually been using this exact pattern and it works so well! It gets really powerful if you make a scriptable object for the balls. Then each can have specific properties and data you can either pass through the event or reference for very precise control.
I just learned something about System dot serializable scripts. I made a bunch of Arrays and scripted with foreach. Im happy to have Arrays now so I can just put New objects in the inspector instead of Scripting each one. I made a spawner with 10 waves of enemies with over 900 likes of always repeating Code. Now I wave 170 lines doing more stuff than before and with unlimited waves. Once you notice sich thing you can work with another Perspective on these things. I love to see the progress in learning
Correct my if I'm wrong but at 6:56, shouldn't you subscribe to the event in the start method? Cross reference another class in the awake method can be tricky because you'll end up in a race condition. With subscribing in the Start method we make sure that BallManager is 100% initialized before Ball.
You can register the ball to an array on the ball manager and it will do the same without using events . I believe events eill be tougher on memory than this method
May be for this simple example yes. However events are extremely powerful is programming, not just in game development. Once you have a complex project event becomes a life saver.
Not gonna lie I didn't realize there was a ball counter throughout the video and I actually spent time counting how many times you said the word ball and I counted 59 which is only one off from the actual number, ngl kinda impressed with how close I got lol
Thanks for sharing. I wasn't sure if C# had something similar to lambda functionality you find in Javascript, but what you're describing is the Publisher/Subscriber module design pattern I've been using in web SaaS applications.
Great video, I would like to mention GetComponent and FindObjectOfType. These are both extremely useful methods for finding objects with a reference to the object or without. It is also important to note that if for whatever reason you can't use the singleton design pattern (because static instances persist between scenes) you could use FindObjectType to get the object with a manager script on it in order to subscribe to events. You could also just delete the references to specific objects in the OnSceneLoad event. Not going to explain it fully as it would take some time, but look into the unity documentation.
These are expensive. Be sure to cache them and not call GetComponent or FindObjectOfType every frame. Also, in most use cases for this you are creating tighter coupling, so always look for an alternative way. Only use what he recommends if you literally have no other choice imo.
Static means that there is only one. In the case of a class, it means you don't make instances. So for example, if BallManager is static, you can do: BallManager.Foo(); BallManager.Bar(); It'll work just fine. If BallManager wasn't static, you'd need to make an instance like this: BallManager ballManager = new BallManager(); ballManager.Foo(); ballManager.Bar(); See how we make an object and assign it to a variable? Because BallManager isn't static, there can be multiple BallManagers, so we have to make one. For the BallManager class, it makes sense to have it be static because there should only be one Manager. For the Ball class, it makes more sense for it to not be static. There's no reason to limit ourselves to having only one Ball. We use static classes all the time for things that should "just be there" for anything to use. Console is a static class, which we use like Console.WriteLine("Hello World"). We don't need to make a Console object, the Console just exists. Non-static classes are things we want to be able to create instances of, like the objects in our game. It's not a given that there will be any Ball in our scene - there might be none at all, or there might be many of them. A class can also have static fields, like a static string. If we have a static string field on our Ball class, even though the class is non-static, if one Ball changes the string it updates for every ball. So if Ball.Str is static, changing ball1.Str also changes ball2.Str. Even though they're on different instances, because the string is static, they all reference the same string.
@@tomysshadow Very well summarised! The only thing that I would add is that the way static fields work is by assigning the fields to the class object, rather than an instance object of the class. Meaning that any given class inherently has a class object to which static fields and methods are assigned. Therefore, these are also accessible to instances of the class but unlike non-static fields and methods (of which each instance has its own "snapshot"), the static ones are shared between all instances of a class.
Visual Basic refers to static as 'Shared' if that clarifies what static does. it's like everyone sharing one box of pizza (static) instead of having their own boxes of pizza to themselves (non-static).
Thanks for the video, but the title is a bit clickbaity. A static reference that assures only one instance is living is a Singleton Pattern and the event related architecture is the Observer Pattern. There are other concepts in unity that, in my opinion, are more fundamental than these, like the Composite Pattern, the SOLID principles, the Proptotype pattern (basically how prefabs works). And if you are talking about the Unity Engine itself (not only scripting) there are concepts like scene splitting, prefab utilization and prefab variants, project organization and folder structure that I think is even more important. Singleton is a pattern that works ok in small projects, but can be bad in bigger projects with too many things referencing each other without an abstraction layer and too much static state. Another pattern that is usually compared to singleton for these solutions is the Service Locator. It is usually implemented using interfaces and a static class that keeps references to registered services.
Great video with Good Style ... but many "specialist" can't understand the main idea of this video and begin discussion which "singleton design pattern" must be use and why static fields isn't good :))
Yeahhh I really didn't expect people to focus so hard on singletons... I only intended to mention it in passing but I stepped into a bit of a minefield lol. Guess I know for next time
So its like a Hearer and Speaker.... (Just Guessing) Where the Hearer is the static BallManager NameInstance; and the Speaker are the event static Action OnEnableBALLS; Hmmm.... so to talk to Statics Objects i "need" a Action On.... ok... theres probably other methods but im guessing this works in most Situations
As someone has already said this would’ve been so helpful when I first started learning Unity, hopefully there’s someone in that position right now watching this vid so they don’t have to learn it the hard way. Ps: would you happen to have a discord sever? I looked around but didn’t see anything, I think it would be a great way to build up your community, it’s also good to start when you’re still small so you don’t have to try to push everyone in all at once when you get bigger lol. If you don’t have a discord server I’m more then happy to help you out, I’ve setup multiple professional servers and currently moderate a few of them, let me know if that’s something you’re interested in🙂
❤Thank you for your efforts.❤ I would however be driven with care when implementing singletons without the correct use of the pattern. They can become unruly for testing, create strong coupling, and without guard clausing that Instance variable, you may find trouble ahead when your project code complexity grows or you load a new level withouth handling that script refiring and creating another ! Here is an example explaining what I mean and to go forward with: public static Instance {get; private set;} private static instance; void Awake() { if(Instance != null) DestroyImmediate(gameObject); else { Instance = this; instance = Instance; DontDestroyOnLoad(instance.gameObject); } working with instance inside the class and calling Instance from any other scripts :) (: All in all, fo me, this has some really nice overviews of some key operational mechanisms in Unity using C#, looking forward to your upcoming videos :)
Agreed! I chose to omit explaining the singleton pattern for brevity since I only briefly touched on static instances, but perhaps I should've spent some more time explaining the associated pitfalls
@@Archions Bruh, you rule for even doing a YT tutorial, especially one that covers some of the key "get ahead" areas for early entrants, but yeah somethings, like this, can obvs be a bit "trappy" down the line as that complexity grows, so prob best to give em all the ammo you can :) I still say very very well done on a fantastic tutorial that does indeed cover a great deal in short form. Very good indeed and dont you forget it, I'm subbed and look forward to seeing more from you bosscat! let's goooooooooo
Started learning a bit of unity recently. Have a background in programming. Was uncertain about how the course I'm watching handle things. Don't like dragging stuff and not seeing it spelled out in the code itself. THANK YOU. (Don't of this will help me with everything I'm not certain about but I suspect it will help somewhat. Again, thank you very much.)
If you have any suggestions about how to "attach stuff to each other" without dragging and dropping, please let me know. Or if it does not make sense for some reason… Thank you again.
The video and the concept on its own is pretty good but the tutorial and the information given is rather questionnable. The conclusion that events are the way to go is perfect though, I'm not saying that's a bad thing to do. However few things to keep in mind. In the first part of the video you show the example of ball1, ball2, ball3 and say it's tedious. If you've ever heard of arrays, you know that this isn't tedious at all. You can have 150 balls on your scene and still drag & drop them into an array, and that doesn't take a lot of time to do. Showing your method in the video kinda implicitly says "it's the only way" where it's definitely not. - When you want to access/modify scripts from other scripts, it's not a matter of accessibility. It's a matter of context. If the object exists when the other object also exists, then a drag & drop is sufficient. If it's not, then there ALWAYS is a context from where these two objects should communicate. Collisions, Instantiation, etc... not all of your objects in your games require a manager and events. There should be some context at some point. - Showing the Singleton pattern when talking about "Balls" is not relevant. A singleton is literally one single instance. Showing that in your video and telling "it's not working" is kinda misleading in my opinion. There is no reasons or logic to use a singleton is that case. - Events shouldn't be named with "On" at the start. They should be named on the actual event that happened. For instance in your case, the event should be called something like "disabledBalls". Only the method that subscribes to that event you start with "On". Think about how Unity works, the methods you use are not "TriggerEnter" it's "OnTriggerEnter" because the event is not OnTriggerEnter, but the method is. - When using Action with parameters, it's important to keep in mind that with just the Action sort of things, it's really hard to see which parameter does what. Try learning about delegates to have names put next to the type to have way more information. The video and its intentions are good, but the way it is shown is not that great. Keep it up though, the editing part and the explanation are pretty cool! Sorry about that long message and I hope you've learned one thing or two!
Hey, thanks for the detailed feedback! It's always challenging trying to strike the right balance between brevity and detail. I didn't want the video to get super long and chose instead to focus on the core concept of communicating between objects in C#. Naturally this comes at the cost of skipping over information which would still be useful. I will keep your feedback in mind when deciding on the balance between detail and engagement in the future !
how about arrays or lists? having an array as a static variable and when any ball is instantiated it adds itself to that array so the ball manager can find it there or have the array as a public variable in ballamanager instead of static and do the same thing
"Because we can only ever have one static instance for any given class. " That's actually a big mistake here. You can have as many static instances in class as you want with any collection like list or array. To be clear I'm not recommending it. But in the class Ball you can have: public static readonly List Instances = new List(); and instead of: Instance = this; you do: Instances.Add(this); and in OnDestroy you do: Instances.Remove(this); For small and simple project this should be sufficient. But in order to make it a little better. You could make BallManager just a simple MonoBehaviour and in Ball class you just "find it" in awake. So: void Awake() { var ballManager = FindObjectOfType(); ballManager.AddBall(this); } with this you can get rid of this ugly static fields. And with all instances in one place you can count them, iterate them, make Object Pooling, and more.
Does C#/Unity allow to find parents/children of a game object or of a scene? (This would be pretty easy, performant and safe in Swift language, for instance)
Unity FAILS to provide basic communication methods on an instance level (e.g. for cross-scene/cross (nested) prefab (variants) communication ...) No matter what you use (ScriptableObjectReferences, Events, maybe a (G)UID system) it will still get extremely messy & complex when you communicate on an instance level (and not just sending from instance to a singleton/static which is the easiest scenario)
9:24 There's gotta be a way to modify the parameter of an event in an other way than a field, like in a script, no ? If someone knows, please tell me ? :)
Hey everyone, it's only an anti-pattern if you are following OO and SOLID. Specifically, it couples things together using global state, hides dependencies, can lead to concurrency issues if you are not careful, and can hurt some forms of testability. HOWEVER, there are very successful programs/programmers that do not follow OO/SOLID. Remember that OO is a *constraint* because *limits* what you can code (which is good thing for some people... it's the tradeoff they make). Anyhow, it's all relative to what you are trying to achieve and where your programming practice is at and who you are working with/for.
I prefer to have a list on the manager / single instance. See ~code below: public class Ballmanager : MonoBehaviour { public static Ballmanager Instance; public List Balls; void Awake() { Instance = this; } void DisableBalls() { foreach (var ball in balls) { ball.gameObject.setActive(false) } } } public class Ball : MonoBehaviour { void OnEnable() { if(!Ballmanager.Instance.Balls.Contains(this)) Ballmanager.Instance.Balls.Add(this); } void OnDisable() { if(Ballmanager.Instance.Balls.Contains(this)) Ballmanager.Instance.Balls.Remove(this); } }
Grats on your list. Now update the UI to add to a score. Now update your achievement system. Now update your stats. Now update your character state. Is it game over? Have you ran out of balls? Oh right, you're not firing an event to let any scripts that MIGHT want to know about the balls number changing. Guess you better hard code and tightly couple this then. Please don't teach bad habits. Your list is fine, but it's irrelevant to what he's showcasing which is communication and decoupling.
@@newf_gg1230 No need to be condescending. When you mature you will learn that there is no right or wrong, only problem solved or not. The problem was how to reference objects without manually doing it with a serialized reference. A simple List.Add in OnEnable solves that. Having UI components poll a manager is not a bad practice. It's a different practice.
Few possibilities: 1. Make sure your static class is in your game scene (i.e. the script is on a game object) and the object is enabled 2. Make sure you're assigning the instance in the Awake function (Instance = this) 3. Make sure that wherever you're referencing the static class from, is doing so AFTER the instance is set. I.e. if (in your static class) you're assigning the reference in the Awake function, consider referencing it in any function except the Awake function in other scripts. If you try to reference your static instance from other classes on their Awake it will cause errors if their awake is run before the awake function in the static class. Hope that makes sense
DO NOT FOLLOW THIS Thank god this "only" got 46k views. Overcomplicated code, faulty examples and misinformation. Spend more time learning unity than editing funny images on the video if you want to help people.
It's actually kinda sad to see horrible advice like this being taught to budding developers. It's obvious that you yourself are a beginner programmer so why teach other beginners and lead them astray?
Did you really just come to call his advice horrible and be condescending instead of letting newer users understand why its bad. No matter how bad his advice may be, at least its actually advice.
Yes it is not the nicest way to say it, but it is actually a terrible advice. And i agree with him, you shouldnt start trying to expose things on CZcams when you are an absolue beginner as the creator of the video seems to be. Singletons (and this is not even a singleton in the case of this video, just a static field) are in my opinion to avoid almost entirely. I understand that beginners start from there, as it is easy to implement and to understand. I wont go into too much détails, but this is basically an anti pattern / lazy way of organizing and architecture code. In his exemple , it is all fun and game, but in a Real application, organizing the codebase like this will lead to an absolute garbage unmaintainable mess. Every components , accessible from anywhere is basically what you want to avoid if you want to create a good and maintenable codebase. To go a bit further : instead of watching this video, go check solid Principles, ans scriptable objects :)
This is called the pub/sub pattern. It's only one of many, many ways to do message passing in OOP, and definitely not the end-all be all. The pro is it's simple, but the cons are it's relatively slow and very difficult to scale without major maintainability costs. Great for small projects!
Be careful about the static fields. They are preserved between level loads which may cause problems.
It is called a "singleton design pattern", look it up for more information.
Its an "anti pattern" not a design pattern :)
@@killereks Well it is a design pattern, standardizing solving very specific problems. It may be used badly, just as any other design pattern.
Interesting. Do you know how one could avoid those problems while still enjoying the "static" benefit?
global state cringe
@@filipe_lopes It is a hard generic question to be answered in one youtube comment. If you are making your first game with a couple of scenes and scripts, you are fine with it. When you start feeling friction and increasing commitment to it, you are mature enough to google for different way how to solve your problem without using statics.
Is it understandable at least a bit? :-)
I've been searching for this video for so long. The perfect explanation that tied all of my entry level programming knowledge together in a nice bow. Thank you so much !!
Live it, it's so detailed and I haven't seen any other tutorial like this. I had no idea why you would even need events, but now I think they are the most useful thing and I going to start learning them
No wonder Godot made event signals part of the basic tutorial
I swear to GOD! I used unity for 3 years without using events (I just had references for everything I wanted to access), but I recently took the plunge and learned them & their workflow, And they're sooo useful.
Bro I love this. I have been trying to find a way to do this and no other tutorial has been this instructive
Glad to hear it my guy
lol. I liked the video, then read the caption about taking a shot every time you said ball.... and I was sold on subscribing. That is the solid comedy.
You explained the Unity static class and event concepts very clearly. I had trouble understanding the specifics from the Unity chapter alone, but this filled in several gaps. Thank you!
That was the slickest way I've ever heard for telling me to subscribe. Absolutely brilliant! Also great tutorial, I'll definitely be referencing this at a later date when I'm ready to tackle this in my own projects.
Glad to hear it, good luck!
THANK YOU!! this has helped so much, it was one of those thing that i’ve been struggling to understand for so long and this is the only video that actually explained it in a way that makes everything make sense
While the singleton pattern is an easy way to reference other objects it is considered an 'anti-pattern'. This is because it violates some key design principles and makes changes down the line harder to implement. Other design patterns which are a bit more complex to understand and implement but once implemented they can make things so much easier and safer down the track.
If you are interested have a look into the Dependency Injection (DI) pattern, once setup it can be amazing.
Remember, depending on the project, some patterns are better than others. This pattern may be fine for small projects.
Fully agree, dependency injection is a great way to handle referencing other objects
@@Archions It is definitely not a beginner friendly topic though and a beginner might not understand or be able to appreciate the pros/cons of DI.
There is absolutely nothing wrong with the singleton pattern, people keep repeating this myth over and over but it is just false. As I have become more experienced, I have only been using *more* singletons than before.
Singletons CAN be misused, but they are not inherently bad. It makes way more sense in some scenarios to have singletons than have to connect every class to every other class and deal with dependency hell.
This video would've been incredibly helpful when I was learning Unity! It perfectly describes concepts that took me years to figure out on my own!
took you years to figure out events? jesus christ
@@ChanDawg86 More like it took me years to discover and start practically using them. I'm self-taught, so I would come up with duck tape solutions and stubbornly stick to them because a solution is a solution, right? I now know that the answer to that is no lol
I even came up with my own janky version of the Singleton pattern that didn't use the static keyword.
I've seen good tutorials in the past.
This was a game changer for me.
Thank you.
I swear the CZcams algorithm can see into the future. I had some issues with stuff I was doing for a project so I approached one of my teachers, he didn't have a lot of time at that moment, but he explained me some things and told me I should look into events. This video was recommended to me a few weeks prior to that conversation...
BROOOO!!! This literally describes what I've banged my head on my desk trying to figure out for weeks. THANK YOU!
Happy to hear it my dude
You could have a list of balls in the ball manager, which a ball adds itself to when created. The event system is definitely better though
That's a lot of balls.
I loved the simple explanations, and the trial and error of why one concept won't work and how to resolve the issues has been insightful! thnx!
No. Singletons are not the way, nor will they ever be.
You need a combination of dependency injection and dependency inversion to handle cases like this.
If your balls depend on some methods provided by the manager to function, inject the manager in the ball class when spawning them.
If your balls invoke behavior of manager when certain actions are taken, use events from them and have the manager subscribe to each as it spawns the ball.
P.S. I’ve not seen your channel before, but I would prefer to have less people out there mentioning singletons as a solution to anything. It is almost never a good decision and will cause almost unsolvable issues in the future
Dependency injection is something I wanted to cover but decided the focus would be on events; I agree dependency injection in this case would work well!
Be careful about completely ruling out singletons, while I understand the controversy around them, they have their place in certain situations.
@@Archions Which situations? I’ve never seen a situation where you couldn’t avoid them
@@Dfjs427 I think of it less as situations they could be avoided and more as situations they could be used without abusing them. Sure, in most cases you can find a way around using them, but in some situations I haven't found them to be problematic to use. For example, logger classes you could find a way to avoid them, but is it necessary? I haven't yet been burned by singletons so badly that I've completely sworn off them, but who knows, perhaps in the future I'll have a particularly traumatic experience😉
While this is true, unfortunately Unity is built in a way that simply makes the singleton anti-pattern easier. Instantiating a prefab does not have a simple good way to do dependency injection (at least that I know of). I've seen solutions that ranged from building a specific factory per prefab (requiring compiling all dependencies into one place with no automated tooling), to reflection on a tree search of the prefab. You can clutter your scene with hidden objects that you clone, rather than prefabs, losing you the benefit of them.
In an ideal world, Unity would scan a prefab for dependencies to be injected when it is turned into a prefab, and automatically attempt to resolve those dependencies when that prefab is referenced in the editor, but it doesn't do that. Instead objects are spawned with nothing injected, and no references to any non global object, including the script that spawned it. We are forced to have at least one singleton if we want to link it. Using singletons we can at least make it work, and work efficiently. It's biggest problem is that it doesn't scale, and often that doesn't matter.
Yes it stinks, but sometimes that is the cost of working in a codebase you didn't write. You absolutely don't NEED anything else, particularly when 'best practice' is fighting the existing code.
@@Dfjs427 Who hurt you? Show me your released game titles with credits that cross reference to you clearly. I think you're likely a peasant who has never released anything worthwhile and just like to spout regurgitated bullshit you've read on some threads. Negativity without example destroys any credibility you have. Stay small, manlet.
So clear and to the point, thank you!
For every beginners watching this video, please don't take it as a good practice (I mean it). This is actually the opposite, and you should absolutely avoid to program like this.
Let me explain a bit more :
Singleton design pattern (ensuring that a class has a single instance, and providing a global access point to this instance ) is what the creator wants to show you. First, the singleton pattern is not correctly designed, and doing like it's done in the video can lead to errors.
Exposing global variables like that, accessible everywhere in the code, is of course the easiest (read : laziest) way to make components communicate. The biggest issue with that, is the control flow of your application. In the example that is shown in the video, it is all fun and games, everything works properly, because it is a super simple example, with a manager and a ball.
Let's say you want to create a big project, with NPCs, World Building, Quest system, inventory etc etc ... If you design your application like this, it means that every system you create, has the possibility to communicate with every other systems of the application. As the project will grow, this will (100%) lead to systems that should have no connection whatsoever communicating together, and therefore, create an absolute undebuggable / unscalable project.
The way to go, is first to read actual real books or articles about software design before going to youtube for some obscure tutorials. Advice number one, and probably the most important : learn the SOLID principles , apply it whenever you can. Learn about inversion of control, read articles about design patterns that are ACTUALLY real scalable, good practices. Of course it seems harder, but if you really want to progress, and make real projects, this is the only way to go.
And basically, every "problems" that the creator thinks he is solving by using a singleton are actually only problems when you don't know how to handle them (this is no criticism, just a fact).
First example : when he says "If you have a lot of balls that you want to communicate, it is tedious to assign them in the editor manually". Solution : Create a serialized array of balls. You can then select them all in the editor, and drag and drop directly to the ball manager script.
Second : When he says "If the manager instantiates a ball, he won't be able to communicate with it" : Wrong !
Create a prefab of the ball, with the script Ball attached on it , and do like this in the manager :
[SerializeField] private Ball ballPrefab;
void OnEnable()
{
Ball ball = Instantiate(ballPrefab);
ball.DoSomething();
}
It is as simple as that. If you want to create multiple balls, iterate through an array of the size you want, and instantiate the number of balls you want (and it is actually not even the best way to do that, a pooling system is better to avoid garbage collection overhead, but this is another topic).
If you want to keep a reference to the balls in the scene, create a list at the top of the class, and add the balls that you instantiated to this list.
I hope this will help a poor soul seeking for answer about unity, which is of course a big, complex topic !
But please, don't take advices like this, this is bad practice. Read before youtube ;)
Hmm these balls gave me nut clarity about programming. You have good sense of balls. Bravo!
This is actually such important information. I don't understand why these concepts aren't preached more to beginners
Because almost every tutorial creator is a beginner themself who spews regurgitated content and has no computer science background or a subject matter expert level experience in Unity. They know that the beginner stage gets the most views, so they are content with showing people how to make a sprite jump and collide and maybe update some text on the screen. 90% of people will quit after that point, so why try hard for 10% viewer retention.
@@newf_gg1230 valid response
Simplest and Easiest way to learn about event, Loved your video. Keep up the good work bro.
The singleton pattern is okay, but one bad thing about it is that it results in a big spider web of dependencies. Of course, other design patterns also have their downsides but I prefer the observer design pattern. It doesn't get rid of all dependencies, but at least it redirects all unnecessary dependencies to a single, manageable place using event listeners.
Lovely tutorial, very clear and high quality. The only issue though is that you are showing a practice that becomes quicky problematic without mentioning it.
Why is it problematic ?
- Singleton causes spaghetti code and quickly make classes impossible to use outside of a particular context ( create dependencies).
It's a good pattern to start, but I would advice to look for other patterns as well to have more solutions in your toolbox (useful ones are scriptable object architecture or Dependency injections for example). Feel free to check out my tutorial about scriptable object architecture if you are interested in original way to pass data in Unity.
Also, instead of having the static events in the BallManager you could try a new static GameEvent class. This way you have one location for all your events (you can even make categories) and classes subscribing to those events are decoupled from a specific class but coupled to the bridge : GameEvents. Granted, in your example there is not much going on, but in a bigger game in might be useful. Continue the good videos 👍
Thanks very much! Yeah I tend to keep my events in a static event class since I think it's cleaner to keep them all in one place rather than in disparate scripts
dude he's literally just showing you how he built up to usinng Events. We all know Static classes are Bad, you aren't some genius comoing over here to tell us something we don't know.
No we don't all know it, matter of fact its still very used everywhere. Most tutorials use it ^^. I never said I was a genius, I just commented on his video. Also, I never said they were bad, I just mention that a Singleton can create unwanted dependencies.
You don't advertise on someone else's channel. Especially when your content is so bad. SOAP is WAY more coupled than a global event manager. Get out of here. Reported for advertising on other channels.
@@newf_gg1230 I see, yeah maybe I should not have suggested my channel. I was merely trying to guide to other solutions and I know, by experience that SO architecture works well for decoupling. I am not sure I understand why you would say its way more coupled. Curious to know your stance and where that comes from.
I cant thank you enough for this tutorial , everywhere I see is only beginner tutorial , it was something I really needed as intermediate programmer , also if u can suggest some more like these not the beginner ones , which are essential for unity.
This video was pretty awesome. Have heard of events before but i didn't know that they were so useful
Yup, they are incredibly helpful and I pretty much use them in all my games
Static instances can be very useful if you only ever want to have one object of a given type active, it's called the singleton design pattern, and I use it all the time, however something to be aware of is that static variables persist between scenes and if you load a new scene without an instance of that type and a script tries to access it it will return null since that particular object instance doesn't exist anymore. I also like to set it up so any instance of that class that is created after the Instance field has been assigned is destroyed, this isn't necessary but it does give you one less way to accidentally break your code.
Here's how I tend to write singletons when coding for Unity projects:
private static MyClass instance;
public static MyClass Instance {
get{
return instance:
}
}
private void Awake() {
if(instance != null && instance != this) {
Destroy (this.gameObject);
}
else instance = this;
}
Something to note is that I set this in awake so you need to get it in Start or later.
This video was awesome: it's great content, great presentation, and even better balls.
Glad to hear it!
This video got balls.;;
3:14 This kind of static instance is called the Singleton Pattern, in case you need to look it up
Really?
This is pretty different from what I use Singletons for
Events, Actions and lamdas have made my life so much easier :)
Legends say that the ball counter is still going up
You don't have to assign them in the editor, you can do that at runtime just fine. Ballmanager can Instantiate balls and keep the references in a List/Array or even as simple children if you choose Ballmanager as their parent. So then you have full control over enabling/disabling them. No need to manually numerate them in the inspector or such.
this was very, very informative
I think I watched this video a year ago, and I didn’t understand it at all. Recently I’ve been working on a lite RTS game with 100s of different objects, systems, managers. I have actually been using this exact pattern and it works so well!
It gets really powerful if you make a scriptable object for the balls. Then each can have specific properties and data you can either pass through the event or reference for very precise control.
I just learned something about System dot serializable scripts. I made a bunch of Arrays and scripted with foreach. Im happy to have Arrays now so I can just put New objects in the inspector instead of Scripting each one. I made a spawner with 10 waves of enemies with over 900 likes of always repeating Code. Now I wave 170 lines doing more stuff than before and with unlimited waves. Once you notice sich thing you can work with another Perspective on these things. I love to see the progress in learning
Correct my if I'm wrong but at 6:56, shouldn't you subscribe to the event in the start method? Cross reference another class in the awake method can be tricky because you'll end up in a race condition. With subscribing in the Start method we make sure that BallManager is 100% initialized before Ball.
You can register the ball to an array on the ball manager and it will do the same without using events . I believe events eill be tougher on memory than this method
May be for this simple example yes. However events are extremely powerful is programming, not just in game development. Once you have a complex project event becomes a life saver.
Not gonna lie I didn't realize there was a ball counter throughout the video and I actually spent time counting how many times you said the word ball and I counted 59 which is only one off from the actual number, ngl kinda impressed with how close I got lol
Great info, usually I use lists, but this is great when you want to keep iteration down.
i like the ball counter
Balls
your voice is like a news speaker explaining a tragedy with 30 deaths, it feels weird to watch the video
Thanks for sharing. I wasn't sure if C# had something similar to lambda functionality you find in Javascript, but what you're describing is the Publisher/Subscriber module design pattern I've been using in web SaaS applications.
Very nice, check out the 'Observer pattern' in C# - I think that's the equivalent of the Publisher/Subscriber design pattern in JS
Delegates are the closest C# equivalent to anonymous functions.
This video is gold! It solved my problems
Great, detailed video! Keep up the good work!
I love object oriented programming
Subbed. Hope to see more unity tutorials like this.
Thanks! I'll see what I can do
Great video, I would like to mention GetComponent and FindObjectOfType. These are both extremely useful methods for finding objects with a reference to the object or without. It is also important to note that if for whatever reason you can't use the singleton design pattern (because static instances persist between scenes) you could use FindObjectType to get the object with a manager script on it in order to subscribe to events. You could also just delete the references to specific objects in the OnSceneLoad event. Not going to explain it fully as it would take some time, but look into the unity documentation.
These are expensive. Be sure to cache them and not call GetComponent or FindObjectOfType every frame. Also, in most use cases for this you are creating tighter coupling, so always look for an alternative way. Only use what he recommends if you literally have no other choice imo.
This was helpful af. If only I understand the concept of static 😂
Static means that there is only one. In the case of a class, it means you don't make instances. So for example, if BallManager is static, you can do:
BallManager.Foo();
BallManager.Bar();
It'll work just fine. If BallManager wasn't static, you'd need to make an instance like this:
BallManager ballManager = new BallManager();
ballManager.Foo();
ballManager.Bar();
See how we make an object and assign it to a variable? Because BallManager isn't static, there can be multiple BallManagers, so we have to make one.
For the BallManager class, it makes sense to have it be static because there should only be one Manager. For the Ball class, it makes more sense for it to not be static. There's no reason to limit ourselves to having only one Ball.
We use static classes all the time for things that should "just be there" for anything to use. Console is a static class, which we use like Console.WriteLine("Hello World"). We don't need to make a Console object, the Console just exists. Non-static classes are things we want to be able to create instances of, like the objects in our game. It's not a given that there will be any Ball in our scene - there might be none at all, or there might be many of them.
A class can also have static fields, like a static string. If we have a static string field on our Ball class, even though the class is non-static, if one Ball changes the string it updates for every ball. So if Ball.Str is static, changing ball1.Str also changes ball2.Str. Even though they're on different instances, because the string is static, they all reference the same string.
@@tomysshadow Very well summarised!
The only thing that I would add is that the way static fields work is by assigning the fields to the class object, rather than an instance object of the class.
Meaning that any given class inherently has a class object to which static fields and methods are assigned. Therefore, these are also accessible to instances of the class but unlike non-static fields and methods (of which each instance has its own "snapshot"), the static ones are shared between all instances of a class.
Visual Basic refers to static as 'Shared' if that clarifies what static does. it's like everyone sharing one box of pizza (static) instead of having their own boxes of pizza to themselves (non-static).
You sound like james jani so much . Thanks for the video
Thanks for the video, but the title is a bit clickbaity. A static reference that assures only one instance is living is a Singleton Pattern and the event related architecture is the Observer Pattern.
There are other concepts in unity that, in my opinion, are more fundamental than these, like the Composite Pattern, the SOLID principles, the Proptotype pattern (basically how prefabs works). And if you are talking about the Unity Engine itself (not only scripting) there are concepts like scene splitting, prefab utilization and prefab variants, project organization and folder structure that I think is even more important.
Singleton is a pattern that works ok in small projects, but can be bad in bigger projects with too many things referencing each other without an abstraction layer and too much static state. Another pattern that is usually compared to singleton for these solutions is the Service Locator. It is usually implemented using interfaces and a static class that keeps references to registered services.
Great video with Good Style ... but many "specialist" can't understand the main idea of this video and begin discussion which "singleton design pattern" must be use and why static fields isn't good :))
Yeahhh I really didn't expect people to focus so hard on singletons... I only intended to mention it in passing but I stepped into a bit of a minefield lol. Guess I know for next time
I'm ur 56th subscriber, Thank for the tutorial.
So its like a Hearer and Speaker....
(Just Guessing) Where the Hearer is the static BallManager NameInstance;
and the Speaker are the event static Action OnEnableBALLS;
Hmmm.... so to talk to Statics Objects i "need" a Action On.... ok... theres probably other methods but im guessing this works in most Situations
fk my brain hurt...when i heard object orientate but i appreciate the 10 min vid to tackle my main issue
It is important for a manager to communicate correctly with their balls
I literally just figured this out last week where was this video then
Thank you for this! I actually learned something new and helpful :D
As someone has already said this would’ve been so helpful when I first started learning Unity, hopefully there’s someone in that position right now watching this vid so they don’t have to learn it the hard way.
Ps: would you happen to have a discord sever? I looked around but didn’t see anything, I think it would be a great way to build up your community, it’s also good to start when you’re still small so you don’t have to try to push everyone in all at once when you get bigger lol. If you don’t have a discord server I’m more then happy to help you out, I’ve setup multiple professional servers and currently moderate a few of them, let me know if that’s something you’re interested in🙂
Sure, sounds like a good idea - what's your Discord? (Feel free to email me it if you don't want to post it publicly lmao)
@@Archions That's awesome to hear, I don't mind posting it here, it's @LegendarySwordsman2#7777, can't wait to get started.
discord.gg/T6ZgeKW6 esketit
awesome vids.
❤Thank you for your efforts.❤ I would however be driven with care when implementing singletons without the correct use of the pattern. They can become unruly for testing, create strong coupling, and without guard clausing that Instance variable, you may find trouble ahead when your project code complexity grows or you load a new level withouth handling that script refiring and creating another !
Here is an example explaining what I mean and to go forward with:
public static Instance {get; private set;}
private static instance;
void Awake() {
if(Instance != null)
DestroyImmediate(gameObject);
else {
Instance = this;
instance = Instance;
DontDestroyOnLoad(instance.gameObject);
}
working with instance inside the class and calling Instance from any other scripts :)
(: All in all, fo me, this has some really nice overviews of some key operational mechanisms in Unity using C#, looking forward to your upcoming videos :)
Agreed! I chose to omit explaining the singleton pattern for brevity since I only briefly touched on static instances, but perhaps I should've spent some more time explaining the associated pitfalls
@@Archions Bruh, you rule for even doing a YT tutorial, especially one that covers some of the key "get ahead" areas for early entrants, but yeah somethings, like this, can obvs be a bit "trappy" down the line as that complexity grows, so prob best to give em all the ammo you can :) I still say very very well done on a fantastic tutorial that does indeed cover a great deal in short form. Very good indeed and dont you forget it, I'm subbed and look forward to seeing more from you bosscat! let's goooooooooo
Very calming and useful information , oh and i expected the balls count to go upto 69 :P
Lmao if only
Thank you so much!
Thanks mate!
Thanks a lot man this was very useful!
Started learning a bit of unity recently. Have a background in programming. Was uncertain about how the course I'm watching handle things. Don't like dragging stuff and not seeing it spelled out in the code itself. THANK YOU. (Don't of this will help me with everything I'm not certain about but I suspect it will help somewhat. Again, thank you very much.)
If you have any suggestions about how to "attach stuff to each other" without dragging and dropping, please let me know. Or if it does not make sense for some reason… Thank you again.
czcams.com/video/dtv7mjj_iog/video.html - here's a great video about some ways you can reference objects in Unity/C#
@@Archions Thank you!
Well explained, thanks
I love ur videos ❤❤
The video and the concept on its own is pretty good but the tutorial and the information given is rather questionnable. The conclusion that events are the way to go is perfect though, I'm not saying that's a bad thing to do.
However few things to keep in mind. In the first part of the video you show the example of ball1, ball2, ball3 and say it's tedious. If you've ever heard of arrays, you know that this isn't tedious at all. You can have 150 balls on your scene and still drag & drop them into an array, and that doesn't take a lot of time to do. Showing your method in the video kinda implicitly says "it's the only way" where it's definitely not.
- When you want to access/modify scripts from other scripts, it's not a matter of accessibility. It's a matter of context. If the object exists when the other object also exists, then a drag & drop is sufficient. If it's not, then there ALWAYS is a context from where these two objects should communicate. Collisions, Instantiation, etc... not all of your objects in your games require a manager and events. There should be some context at some point.
- Showing the Singleton pattern when talking about "Balls" is not relevant. A singleton is literally one single instance. Showing that in your video and telling "it's not working" is kinda misleading in my opinion. There is no reasons or logic to use a singleton is that case.
- Events shouldn't be named with "On" at the start. They should be named on the actual event that happened. For instance in your case, the event should be called something like "disabledBalls". Only the method that subscribes to that event you start with "On". Think about how Unity works, the methods you use are not "TriggerEnter" it's "OnTriggerEnter" because the event is not OnTriggerEnter, but the method is.
- When using Action with parameters, it's important to keep in mind that with just the Action sort of things, it's really hard to see which parameter does what. Try learning about delegates to have names put next to the type to have way more information.
The video and its intentions are good, but the way it is shown is not that great. Keep it up though, the editing part and the explanation are pretty cool! Sorry about that long message and I hope you've learned one thing or two!
Hey, thanks for the detailed feedback! It's always challenging trying to strike the right balance between brevity and detail. I didn't want the video to get super long and chose instead to focus on the core concept of communicating between objects in C#. Naturally this comes at the cost of skipping over information which would still be useful. I will keep your feedback in mind when deciding on the balance between detail and engagement in the future !
how about arrays or lists? having an array as a static variable and when any ball is instantiated it adds itself to that array so the ball manager can find it there
or have the array as a public variable in ballamanager instead of static and do the same thing
Thanks.
"Because we can only ever have one static instance for any given class. "
That's actually a big mistake here.
You can have as many static instances in class as you want with any collection like list or array.
To be clear I'm not recommending it.
But in the class Ball you can have:
public static readonly List Instances = new List();
and instead of:
Instance = this;
you do:
Instances.Add(this);
and in OnDestroy you do:
Instances.Remove(this);
For small and simple project this should be sufficient.
But in order to make it a little better. You could make BallManager just a simple MonoBehaviour and in Ball class you just "find it" in awake. So:
void Awake() {
var ballManager = FindObjectOfType();
ballManager.AddBall(this);
}
with this you can get rid of this ugly static fields.
And with all instances in one place you can count them, iterate them, make Object Pooling, and more.
I'm a 50th subscriber :)
00:15 ECS : "Hold my ISystem"
Does C#/Unity allow to find parents/children of a game object or of a scene? (This would be pretty easy, performant and safe in Swift language, for instance)
Thanks!
Very underrated, keep it up!
Thanks, will do!
Unity FAILS to provide basic communication methods on an instance level (e.g. for cross-scene/cross (nested) prefab (variants) communication ...)
No matter what you use (ScriptableObjectReferences, Events, maybe a (G)UID system) it will still get extremely messy & complex when you communicate on an instance level (and not just sending from instance to a singleton/static which is the easiest scenario)
So freaking helpful!!!
6:05 Why use Action instead of UnityEvent?
9:24 There's gotta be a way to modify the parameter of an event in an other way than a field, like in a script, no ? If someone knows, please tell me ? :)
Hey everyone, it's only an anti-pattern if you are following OO and SOLID. Specifically, it couples things together using global state, hides dependencies, can lead to concurrency issues if you are not careful, and can hurt some forms of testability. HOWEVER, there are very successful programs/programmers that do not follow OO/SOLID. Remember that OO is a *constraint* because *limits* what you can code (which is good thing for some people... it's the tradeoff they make). Anyhow, it's all relative to what you are trying to achieve and where your programming practice is at and who you are working with/for.
I prefer to have a list on the manager / single instance. See ~code below:
public class Ballmanager : MonoBehaviour
{
public static Ballmanager Instance;
public List Balls;
void Awake()
{
Instance = this;
}
void DisableBalls()
{
foreach (var ball in balls)
{
ball.gameObject.setActive(false)
}
}
}
public class Ball : MonoBehaviour
{
void OnEnable()
{
if(!Ballmanager.Instance.Balls.Contains(this))
Ballmanager.Instance.Balls.Add(this);
}
void OnDisable()
{
if(Ballmanager.Instance.Balls.Contains(this))
Ballmanager.Instance.Balls.Remove(this);
}
}
Grats on your list. Now update the UI to add to a score. Now update your achievement system. Now update your stats. Now update your character state. Is it game over? Have you ran out of balls? Oh right, you're not firing an event to let any scripts that MIGHT want to know about the balls number changing. Guess you better hard code and tightly couple this then. Please don't teach bad habits. Your list is fine, but it's irrelevant to what he's showcasing which is communication and decoupling.
@@newf_gg1230 No need to be condescending. When you mature you will learn that there is no right or wrong, only problem solved or not.
The problem was how to reference objects without manually doing it with a serialized reference. A simple List.Add in OnEnable solves that.
Having UI components poll a manager is not a bad practice. It's a different practice.
you can go a whole new level if you make events an ScriptableObject. then you won't have to make the manager class static anymore
I keep getting Object refrence not set to an instance of an object when trying to refrence a function from the static class?
Few possibilities:
1. Make sure your static class is in your game scene (i.e. the script is on a game object) and the object is enabled
2. Make sure you're assigning the instance in the Awake function (Instance = this)
3. Make sure that wherever you're referencing the static class from, is doing so AFTER the instance is set. I.e. if (in your static class) you're assigning the reference in the Awake function, consider referencing it in any function except the Awake function in other scripts. If you try to reference your static instance from other classes on their Awake it will cause errors if their awake is run before the awake function in the static class.
Hope that makes sense
@@Archions Yeah the mistake was putting the script on an object that is disabled at start up oops, thank you sm for the feedback
I thought it was easy to make videogames in Unity!
DO NOT FOLLOW THIS
Thank god this "only" got 46k views. Overcomplicated code, faulty examples and misinformation.
Spend more time learning unity than editing funny images on the video if you want to help people.
Really helpful!
Cool video. But telling beginners to use singletons is a disaster waiting to happen.
All your videos has tightly coupled code and switch statements everywhere, but yea, singletons are the issue here...🤣
It's actually kinda sad to see horrible advice like this being taught to budding developers. It's obvious that you yourself are a beginner programmer so why teach other beginners and lead them astray?
Why is it horrible advice?
Did you really just come to call his advice horrible and be condescending instead of letting newer users understand why its bad. No matter how bad his advice may be, at least its actually advice.
Yes it is not the nicest way to say it, but it is actually a terrible advice. And i agree with him, you shouldnt start trying to expose things on CZcams when you are an absolue beginner as the creator of the video seems to be. Singletons (and this is not even a singleton in the case of this video, just a static field) are in my opinion to avoid almost entirely. I understand that beginners start from there, as it is easy to implement and to understand. I wont go into too much détails, but this is basically an anti pattern / lazy way of organizing and architecture code. In his exemple , it is all fun and game, but in a Real application, organizing the codebase like this will lead to an absolute garbage unmaintainable mess. Every components , accessible from anywhere is basically what you want to avoid if you want to create a good and maintenable codebase. To go a bit further : instead of watching this video, go check solid Principles, ans scriptable objects :)
Encapsulation, inheritance, abstraction, polymorphism. This example completely ignores those.
@@Helloworld20109oop is shit and you’re the reason why
You just made my life a whole lot easier🥹
balls
Is that you como
This is like the most basic of basic things, but explained all wrong.
This is why people who dont understand a thing should not make videos about it. You are showing people really bad practices...
Step One: Use Unreal Engine 5.
Show me something you've published with unreal engine 5. Big talk for a nobody.
Nice content.
Thanks very much
bro what are y doing?
Just use a List balls in the manager class? You are mixing a lot of weird stuff ( I didn't watch the events stuff though).