Modify the code by adding the keyword 'params' in case you need to send more than 1 data to the listener. Class GameEventListener: public void OnEventRaised(Component sender,params object[] data) { response.Invoke(sender, data); } Class GameEvent: public void Raise(Component sender, params object[] data) { for (int i = 0; i < listeners.Count; i++) { listeners[i].OnEventRaised(sender, data); } }
@this-is-gamedev Жыл бұрын
Great usage of this c# feature! 👏
@owlsponge3159 Жыл бұрын
To those who wonder how to access the new parameters inside their method, this is what i did: public void SomeMethod(Component sender, object data) { object[] dataArray = (object[])data; //Use the index of dataArray you need }
@SaphireDO18 күн бұрын
No overload for method 'Invoke' takes 2 arguments In GameEventListener
@santiagorodriguezeidner Жыл бұрын
I literally got the scripts, didn't understand the code at all, but still very happy that it works
@nviiir8226 Жыл бұрын
This is the coolest video I have ever seen, love the editing style and so informative!
@this-is-gamedev Жыл бұрын
Wow, thanks!
@paulrukavishnikov5171 Жыл бұрын
You only begin to truly value design patterns when you need to do one that you've done so many times before in your coding practice, only it was in another field where you've done it (web development in my case), and then you just find a perfect guide for doing that, and you already understand what they do - because it's just a design pattern, and it's so much the same idea that it gives you chills. You just type the code, and you've done with the task. Fascinating, thank you for the guide!
@this-is-gamedev Жыл бұрын
Fully agree!
@corr2143 Жыл бұрын
Worth mentioning that in that talk there is a github demo with examples to the code. Trying to reverse engineer the examples to use in a game project with a deeper understanding for the last couple of days, hoping to stop trying to fire events that arent ready or being able to fire an event more than once before its complete, time to build from the ground up without applying bandaids every major change!
@this-is-gamedev Жыл бұрын
Those are also interesting use cases! You could look are message queues and publishers/consumers rather than publisher/subscriber.
@simonsantics96722 жыл бұрын
Great video! Well laid out and explained.... I literally LOL'ed at the "you still with me". The Radio analogy is great.
@this-is-gamedev2 жыл бұрын
Thanks!! I am glad you liked it :D More is on the way
@simonsantics96722 жыл бұрын
@@this-is-gamedev Awesome. I'm just starting out at Unity - and these are pitched just right!
@alansteyrbach6926 Жыл бұрын
This is absolute killer. I am writing a mix of battle royale, HOI4, psychological thriller and GTA game, this will be massive help
@this-is-gamedev Жыл бұрын
Awesome! I am glad it is helpful!
@napoleonbonerfarte673912 күн бұрын
Jesus Christ that's a big undertaking how's it getting on, I won't blame you if you burnt out and quit.
@Braneloc Жыл бұрын
Thumbs up for an epic NPC waiting for a quest man.
@GWTrinku Жыл бұрын
Very important lesson from a year in the future; in order for your GameEventListener to use dynamic functions and pull data you pass in from variables, you *need* to be sure the function being called has a (Component x, object y) argument. Don't lose hours to this like I did, write an overload!
@FortbloxNET Жыл бұрын
but it's explained in the video? 6:28 for example he shows his UpdateHealth Function with "component sender, object data" ...
@claudiogallardo638311 ай бұрын
Thanks! I had this issue, I was using UnityEngine.Object instead of primitive object class. Thanks for the help!
@jdgoldvox8 ай бұрын
UR SO RIGHT. THANK YOU!!!!!!!!!! I thought I was just being dumb... and I am. lol
@melonezone Жыл бұрын
Yo just wanted to say thanks for the clear explanation it helped me a lot! Also the video looked very professional
@this-is-gamedev Жыл бұрын
Thanks! I am glad it help you!
@GTZ-988 ай бұрын
Holy Shit this took me way too long to fully understand, now that I've got it this must be one of the best features I've learned so far! :D
@this-is-gamedev8 ай бұрын
Awesome!
@darkman2377 ай бұрын
I've used managers for a long time, but for my epic sized game I need to decouple things. This might just be the ticket. Thanks!
@CSurf3r6 ай бұрын
First of all, thank you for this video. I've implemented this solution months ago and after figuring out some best practices it's been going great. I just want to report what I've learned. One thing I've learned quite early on, was using as little different GameEvents as possible. It just makes it easier to maintain and debug. I'm following this principle at least as long as I'm making big changes to the core systems of my game. Reducing the listener count to each event would be something for performance optimization - in my mind. Using as little different GameEvents as possible lead me to a point though, where every button used the same 'ButtonClicked'-event. So, I had a button that disables/enables a menu window, which contains other buttons. That made Unity throw me an error. You know, the one basically saying "you are changing the size of a list, while iterating through it." So, while iterating through the listeners-list in Raise() for some listeners UnregisterListener() is called, which removes entries from the list. I guess this is quite obvious when it happens to you, but it's just something to be mindful of.
@this-is-gamedev6 ай бұрын
Thanks for sharing! Those are all good points!
@orwell235 Жыл бұрын
Great system that I did not see the implementation before. Scriptable objects for events, marvelous! However, I'll not use it definitely :) Visual drag and drop of events as SO and handling them might be a killer in relatively huge projects and not really a scripting way of handling events
@CodingBill Жыл бұрын
You can assign them with code. Almost everything you can do within Unity interface/inspector can be made with code in order to scale and make automatic things.
@orwell235 Жыл бұрын
@@CodingBill yeah, you can. Probably it's just me but it seems like reaching the same thing with extra layer of complexity. I'm happy that it works for you but you should create custom game events which anyway should have references to what they are sending events to but built in Action do it out of the box. Long story short I don't see the benefit for myself comparing it to DI container where you put an event with special signature and subscribe to it from whenever needed. Especially if I don't need to create separate scriptable objects for each event IMHO
@alexandreclement9399 Жыл бұрын
I strongly agree. On the first look, dragging and dropping looks intuitive and beginner friendly, like "you don't have to code anymore !". But at some point, you realise that a well maintained code-based is worth 100 editor manipulations.
@eaglemangamedev24 күн бұрын
Exactly what I was looking for! Thanks for the great video!
@xobk8 ай бұрын
I'm super happy I watched this right before starting a new game
@this-is-gamedev8 ай бұрын
Awesome and good luck on your game :D
@VilmaPole-zg5rw3 ай бұрын
you make every topic you touch both accessible and intriguing!
@this-is-gamedev3 ай бұрын
Thanks! Happy you liked it!
@semi_jared39 Жыл бұрын
there are many implementations of UnityEvents using SOs, and this is undoubtably one of them of the more advanced ones but the video is still great
@abhisheksuper20 Жыл бұрын
Super helpful video. Love the editing and presentation style!!
@this-is-gamedev Жыл бұрын
Thanks a lot for your kind words!
@flathippo49972 ай бұрын
Me personally i love the idea i just dont like doing everything in the editor so instead of scriptable objects with listeners I just use a static class with a bunch of different Action/Func ‘s the system is amazing!
@this-is-gamedev2 ай бұрын
I agree and have a newer video showing exactly that :D
@crosline2 жыл бұрын
Great tutorial, also you can directly cast object to integer without checking it twice inside if such as if (data is int amount) This is a pretty good system for teams with designers etc. but as a lonely developer I think this much usage of editor gets messy sometimes... Dragging and dropping everthing, all the references can be broken if you change variable names etc. (I hate FormerlySerializedAs modifier too) Especially with bigger projects
@this-is-gamedev2 жыл бұрын
Oh right. Looked it up and that’s very useful, and it is supported since C# 7 🙈 Thanks!
@trinetrapandey53399 ай бұрын
finnaly iam going to use something professional sounding system in my game. thankssss
@jannisgnadt2524 Жыл бұрын
Great Video! I learned many new concepts in c# which werent even focus of the video.
@this-is-gamedev Жыл бұрын
Thanks! That's really great to hear!
@Kynzw3 ай бұрын
Thank you very much, it's the first tutorial about it i've understood
@dev-yu Жыл бұрын
Hey.,,, Im looking for this information for a month. Thank you so much!!! This one is so helpful.
@this-is-gamedev Жыл бұрын
Thanks! Happy you like it.
@dreidgon Жыл бұрын
I can't believe that I saw the npc from viva la dirt league on min 0:43 xD
@this-is-gamedev Жыл бұрын
Hello Adventurer!
@resistancefighter8883 ай бұрын
I find it problematic that I can raise an event from any class that a reference to it, I can imagine that it can easily lead to spaghetti code if you're not careful and in case you have a bug it will become to difficult to trace its source...
@aaronh560 Жыл бұрын
I'm a unity beginner, coming from a moderate understanding of unreal blueprints. And I didn't get a lot of it. Maybe some larger diagram of what code goes where. There was a lot of terminology and definitions I didn't understand so there seems to be a need of pre requisite knowledge. I did understand the need for this type of communication between scripts. Though I'm also curious how this differs from interfaces - not that I really understand those. I'm gonna go check out the original talk now
@racrityАй бұрын
Damn man i love you so much. Thanks til' infinity!
@youtubebarashka7182 Жыл бұрын
I have an error in: "response.Invoke(sender, data);" "No overload for method "invoke" takes 2 arguments" What should I do?
@this-is-gamedev Жыл бұрын
Did you define the CustomGameEvent and changed the response type to public CustomGameEvent response?
Жыл бұрын
woah this video is very informative and the editing style is so immersive, thank you :)
@this-is-gamedev Жыл бұрын
Thank you!! I am happy you like it! I’ll continue in that direction for a while :D
Жыл бұрын
@@this-is-gamedev cool!! keep it up :>
@kingofroms72242 жыл бұрын
This video is beautiful, thank you so muchhh.
@this-is-gamedev2 жыл бұрын
Happy you like it 🥹🤓
@SantosRasputin3 ай бұрын
if it needs references it lost its purpose for me, making it a lot more complex...even when its watched as a good practice, having adhd so this event system sounds like spaguety references for me im working on another approach, a log system, and like for example, object a send a log on console: "player - 15 hp" a script log register that log on a list and the script reader of that object, if it reads player lost -15 hp, says, life_manager it deduct the life using "X" method..... this works with 2 scripts ....but im testing it...and this is just talking i need to fix stuff to see if it actually works for its purpouses
@zainulabideen6197 ай бұрын
You just earned a new subscriber....♥ Awesome content
@this-is-gamedev7 ай бұрын
Thanks! 🙏
@sodosodgerel84872 жыл бұрын
Awesome tutorial!!!! Please make more videos ...
@this-is-gamedev2 жыл бұрын
Thanks! 🙏 on it 🫡:D
@etistyle966 ай бұрын
me "that kind of nice but can we add parameter ?" 5:22 "Chill, we need to modify the code to add parameters" YwY
@inxendere Жыл бұрын
I literally love you.
@this-is-gamedev Жыл бұрын
🙏
@seanc11192 жыл бұрын
definitely a game changer, thanks for uploading this!
@JJDSG4 ай бұрын
Wow That helped A lot but can you update this Event System to Listen to multiple different events using just 1 single Event Listener Script on the object because currently we have to add separate Event listener Scripts for different events and say if we have 20 Events then we have to attach 20 event listener scripts on the gameobject to listen to them, but if a array based Event Listener works then it would be awesome, i would like to know your thoughts on this.
@iampaullo2489 Жыл бұрын
I really enjoyed this video, thanks man
@this-is-gamedev Жыл бұрын
Thanks! Glad you enjoyed it!
@bluzenkk Жыл бұрын
Question, In the context of maintenance and scalability, how is this method (Event Sys using SO) compare to having a static class that contains all the event calling and invoke ? So far i can see it may be easier for the designer, but i fear that once the project gets large, you wont be able to keep track of which component has which event, and if a event is lost, you wont be able to spot it and attach to it again.
@this-is-gamedev Жыл бұрын
Yes, those are the main disadvantages and you might need some extra editor tools to work on large projects. Nothing wrong with a static class, it’s just very explicit and you make every other component depend on it, e.g. a UI health bar, the player health stats, the sound effects for health changes, player animation changes based on health. Suddenly they are all dependant on each other through that static class. They are harder to reuse (e.g. Split screen for player 2), same health bar for the enemy. But at the end, use whatever works for your project :D
@hernandonj11 ай бұрын
Great video! Thank you!
@this-is-gamedev11 ай бұрын
Thanks!
@lln6123 Жыл бұрын
wow that is a really good explanation!
@this-is-gamedev Жыл бұрын
Thanks! happy you like it :D
@arisaek77642 жыл бұрын
very cool tnx
@haody_hao Жыл бұрын
this video is severely underrated xDDD
@Director414 Жыл бұрын
Great video! You have a great style of editing+ pacing etc, thanks! I just cant see how this is simpler than just using regular Action events?? What does your thing do vs the regular one? Is it just for having it in the editor, or anything else? Pleaee clarify, i wonder if i missed something
@this-is-gamedev Жыл бұрын
The main difference is that the regular Action is directly linked to the target it affects. So if the player picks up a key and you want to show that on the UI, the Action event on the player pickup script needs to know which UI to update. With this event approach, the pickup script broadcasts “key has been picked up”. Then the Ui can listen and update itself, the soundmanager can listen and play a sound, maybe the enemy manager listens and spawn a new wave, etc. So overall you are making sure that each component have less dependencies and can exists alone without failing.
@marwasalama422811 ай бұрын
Amazing thank you!
@fawn3080 Жыл бұрын
Thank you so much, I'll use this system to make my game more organized!
@this-is-gamedev Жыл бұрын
Thanks! Awesome!
@hatrer2244 Жыл бұрын
Amazing🎉 Looks a lot like C# delegates though?
@this-is-gamedev Жыл бұрын
Yes, Delegates, Actions, UnityEvent, all very similar.
@hadyhesham1203 Жыл бұрын
Awesome Tutorial !
@this-is-gamedev Жыл бұрын
Thanks!!!
@raindiamond3456 ай бұрын
Great concept, It just very hard to understand in your video :( I'll go watch the original
@B_aka_Scias Жыл бұрын
I loved this and used it a lot, I tried to make another custom event that would send only a component but for some reason the response on the EventListener wouldn't appear on the editor I gave up and just used this custom event and ignored the sender part and it worked, but I kinda wish the one I did worked because I have no ideia why it didn't :T
@tommywilkinson333 ай бұрын
My major concern with using this is if you get far along in the project and ever need to adjust the base class or add or remove something from it. I don’t know if this has changed in the latest versions of the Unity Editor but if you had a bunch of GameEvent SOs you had created and then edit the base SO class in anyway it tends to erase the data in ALL of the child SOs in your project. So all of those links might suddenly break. I don’t know if this is more effective than having a singleton manager system that utilizes Actions or Events built into C# natively. I automate the whole connection process you have to do manually here just inside the code like you did with the registering and unregistering. I can even have it where the manager is instantiated and sets itself as a singleton instance if it gets missed in creating a scene… It feels more robust to me.
@this-is-gamedev3 ай бұрын
Changing the signature of the event might break all listeners since the parameters change. There the better way is to support multiple signatures and migrate your listeners one after one. Manager with actions/event and define all by code is of course the most robust method! Have a video about that :D
@tommywilkinson333 ай бұрын
@@this-is-gamedev Hmm, my experience hasn’t been about the signature and one particular function. I think with the method you’re using it may not be as big of a problem since you’re directly referencing the entire SO object and not data within it. But 100% for me at least with Unity 2021 and 2022 versions if you ever change anything in the base SO script, add a new variable, add a new function, even just add a comment, everything in the child classes gets reset to default or null if you don’t provide a default in the initialization.
@kengokurimoto Жыл бұрын
Amazing video, thanks so much! I have a couple of questions; If I would sometimes like to pass more than the Sender, Object data, eg Sender, hitforce and damage, how would I set this up? Would I set up Sender, Object, Object and pass a null for things that only need to pass Sender and Object? Secondly, can the same system be used for sending specific data to specific objects eg. player hits a creature and gives it damage? Or do you just do things like that the conventional way using direct references? Thanks again for such an empowering video!
@this-is-gamedev Жыл бұрын
Thanks! Yes, so either you make the signature of the method bigger: more parameters everywhere. Or, you pass a custom object like a class HitData which contains hitforce, damage, etc. HitData is an object. So, in the method receiving the event you check if data is of type HitData. :D
@kengokurimoto Жыл бұрын
OMG you can do that?! That's so powerful! Thanks so much!😃@@this-is-gamedev
@heeyoungabc8688 Жыл бұрын
Amazing video. Do you have a name for this technique? In which scenario should we use it?
@this-is-gamedev Жыл бұрын
Event System or Publish/Subscribe. Useful anywhere where you want to broadcast messages to other components without the sender knowing who receives the messages. Like UI reacting to events, subsystems (analytics, achievements,…) etc
@jeffmunson385 Жыл бұрын
Great work, thanks. Can you expose the GameEventListener in Visual Scripting graphs?
@this-is-gamedev Жыл бұрын
Thanks! For visual scripting I don’t know for sure, but I remember that you can access public methods on your scripts. At least it was working when it was called Bolt :D
@DanielSzweda Жыл бұрын
Thanks for the informative video, it has helped me to reflect on the system that I am currently developing. I have a question regarding instantiation of new objects that require health display. How can they retrieve the health data without the event being invoked?
@this-is-gamedev Жыл бұрын
You could store the health in a scriptable object and have this shared among all who needs to read that data.
@this-is-gamedev Жыл бұрын
That way the event is used as a call to update and less for sending data
@onezerodev17568 ай бұрын
this is cool. Had to watch 3times to understand because demo is too fast
@this-is-gamedev8 ай бұрын
Thanks! Yeah, newer tutorials will be a bit slower 😅
@LuRybz Жыл бұрын
very good content!
@this-is-gamedev Жыл бұрын
Thanks!
@heavensfield494 Жыл бұрын
What if, say I have a Achivement manager that keep track of an increasing value like the number of enemy killed, how can I unsubscribe the event when the achivement is achived? I dont want to kept calling it. I already have a listener for the On player Shoot, do I have to create another listener script for OnAchiveKillcount for every single achivement I have???
@this-is-gamedev Жыл бұрын
You could do this in different ways. Like having 1 OnAchieveAction and you call this one for every possible achievement, however in the call you pass a custom Achievement object that contains the information needed to know if it’s an enemy kill, or something else. You might have 100s of achievement so passing them through the same event might be easier
@Zorgers11 ай бұрын
Hi, very nice video! I just started with Unity and in general dont have much experience with programming. So far your Event System is working pretty fine for me. I use it for example to trigger prefabs to be enabled from an object pool ( and many more applications to come!). So far i only have one problem and that is when i run my program the first time in Unity it works well. But after stopping and then starting it again when an event is triggered i dont access the "OnEventRaised" function anymore. I have to close Unity completely to get it running again.....so far i have to do this everytime when i want to test small code changes. Any idea what may cause this? Im pretty lost right now and dont really know what to even search for. Maybe some cache related stuff? (I already tried to write a comment but it vanished, so sorry if my questions got any responses already)
@this-is-gamedev11 ай бұрын
Might be that your prefabs who subscribe to the event do not properly unsubscribe and this leaves null references in the list of game event listeners.
@Zorgers10 ай бұрын
Hey thanks for the fast response. That sounds so crazy to me. I would assume that after stopping and starting again everything would be .... clean..... Thx for the help so far! Happy new year!@@this-is-gamedev
@Zorgers10 ай бұрын
I just found out that being lazy and using copy/paste without carefully checking again is a pretty time consuming habit to have :D In the GameEvent class i used the same check condition for RegisterListeners and UnregisterListeners .... for unregister i obviously should have checked if the listener is already in the List .... but atleast i got some practice with debugging.... Now its working like charm :D
@neumy9 ай бұрын
Love your content! Do you have a solution for inspecting the listeners list at runtime on the SO? Right now, there is a type mismatch due to how scriptable objects work, but it seems like you should be able to create a custom display of the list.
@this-is-gamedev9 ай бұрын
Yeah, you can extend the editor. OdinInspector might be helpful in that case. I even thought of generating a kind of text/json report to dump all relations in a file, detect what is not used anymore etc. Keeps me awake at night :D
@IrenesWorkDemos-su2ip Жыл бұрын
Thanks for the tutorial. I'm stuck at the int amount = (int) data; part. How would I use this if I need the data to be different types of objects that inherit from the same class. I can't wrap my head around it. Do I need different methods for all of the different types it could be?
@this-is-gamedev Жыл бұрын
Data is of type object, it can be any type of data. You then cast data to whatever type you expect to get for a particular event. You should read a bit about Object-Oriented Programming and then all will be more clear and even more possibilities will open.
@wilfal Жыл бұрын
I am trying to do the GUI-drops via scripting instead, to add flexibility. After adding the component GameEventListener to a gameobject, how do I add a function to the response list (via C#)?
@this-is-gamedev Жыл бұрын
You could try eventName.AddListener: docs.unity3d.com/ScriptReference/Events.UnityEvent_1.html
@lozD8310 ай бұрын
As a seasoned developer, I wouldn't recommend this approach, and would warn that when you hear/learn something new, it's best not to immediately go around telling everyone how great it is and telling people they should use it. It's important to understand the shortcomings of the approach
@LillbaskernSSBM10 ай бұрын
I've heard that using scriptableobjects for events is unwise before, but do you think you could clarify why?
@МихаилИонов-г2ж9 ай бұрын
@@LillbaskernSSBMit's pretty complicated realization of the event system. better find a KZbin video with realization through a static dictionary
@sadusko71039 ай бұрын
I’m confused why he thought this approach was a lot better at all. Why not just use Action, UnityEvent or EventHandler and just listen to your events as usual, seems as simple as it can be. A lot of overcomplication and with intricate systems it might even lead to completely losing track this way I’d suppose, at least for someone using just C#.
@this-is-gamedev9 ай бұрын
It’s all about having systems separate from each other and still have the flexibility that different instances of the same class can register to different events. For example, I might have a ButtonPrefab with a CustomButton Script, I want to easily reuse the button in all the game, but every instance of the button needs to trigger another event (OnShowOptions, OnMenuBack, OnMenuOK, OnMenuCancel, ….). Some buttons might need to trigger multiple events, and the logic of what happens onClick is separate from the button itself or even from the scene itself.
@damionmccoy99668 ай бұрын
It's funny you say your a seasoned dev. Then you would understand that not only is this approach appreciate for a new dev to understand this architecture before creating something more complex but this methodology is now one that unity itself has embraced and making into a best practice. I'm not saying I'm seasoned but I have been working in unity for going on 13+ years now. And unity seems to be pretty good at deciding what works best with their code. Unless you're saying you know better than the unity devs when it comes to using unity.
@MadDev_9 ай бұрын
Thank you for this video!! Just a question: how would you manage bidirectional bonds? do you have some tips about this? or should I just create GameEvents for both the components and add GameEventListeners on both? Creating on both components sounds good to me, but I am wondering if there is a better way, just out of curiosity.
@this-is-gamedev9 ай бұрын
Thanks! There are no native binding feature in C#. But with scriptable objects, you could reproduce something close. Like having a FloatSO that just stores one value. And then through a delegate, any component that has a ref to the SO can add itself and listen to changes.
@Weirdman28 Жыл бұрын
I really liked the video and the tutorial, but am very stupid and don't know how to use it (it ruins the whole point of having it in the first place) I don't know what code to put in what scripts, or where, and it won't even let me assign a function to the Game Event Listener in the inspector at all. Can someone please explain how the heck to get this to work? I know it will be super useful for my current projects and future projects.
@this-is-gamedev Жыл бұрын
Once you methods are public you can drag and drop your script into the GameEventListener and choose that function. Then on other scripts, you add the CustomEvent as a public field and this allows you to raise event there and affect another place in your game. Without having both script know about each other
@muftahdev83712 жыл бұрын
This is amazing but I've got an error, when added CustomGameEvent the response.Invoke(sender, data); showing error (No overload for method 'Invoke' takes '2' arguments)
@this-is-gamedev2 жыл бұрын
Weird, feel free to check the code here : gamedev.lu/downloads Make sure response is also defined: public CustomGameEvent response;
@muftahdev83712 жыл бұрын
@@this-is-gamedev I checked the source code and it worked, thank you
@naramoro2 жыл бұрын
I dont see the advantage over a delegate system. Yes its a bit more targeted but also a lot messier to set up ( child class, create SO, drag drop, link methods in inspector)
@this-is-gamedev2 жыл бұрын
It really depends how you organise your delegate system. The advantage of this approach is that you can broadcast events and both, the receiver and sender, never know about each other. Only thing they share is the SO. And if one side is missing, the game still works and throws no error. That’s very useful when working on a scene that’s part of a larger system.
@naramoro2 жыл бұрын
@@this-is-gamedev the functionality of sender and receiver not knowing eachother is also a feature of delegate systems
@this-is-gamedev2 жыл бұрын
I’d love to see an example showing that :D What I most often see with delegates is something like: In the GameController, onEnable, you register the delegate like: PlayerHealth.onDeath += GameOver; But in that case GameController is dependant on PlayerHealth.
@naramoro2 жыл бұрын
@@this-is-gamedev yeah exactly. You could also add the static delegate to any class you’d like ( EventManager.OnHealtChange). Where‘s the problem here?
@this-is-gamedev2 жыл бұрын
Yes that’s also a nice solution 🤓
@enchantgames_7 ай бұрын
Hi! Thanks for the amazing video! I have a question, sorry, I'm noob but I can't understand why to put sender and data being mandatory add flexibilty? My Invokes always ask me about the parameters: "There is no argument given that corresponds to the required formal parameter 'arg0' of 'UnityEvent.Invoke(Component, object)'" Do I have to put Invoke(null, null) everytime?
@this-is-gamedev7 ай бұрын
The method Raise() has 3 different signatures to handle exactly that. And the Raise() with no parameters is actually doing Invoke(null, null).
@Shinos_99 Жыл бұрын
Hey, cool tutorial, i am deep diving in learning how to do a nice event system, and i noticed that at (7:00) on the right you show that obviously we can just put multiple gameventlistener script on a gameobject to handle different events, but could we find a way to handle a list of more events with just one script? could be a lil more elegant i am trying to replicate it like this but i am facing some issues :/ (especially with handling each response for the specific event) do u think this would be too unpracticable?
@this-is-gamedev Жыл бұрын
Thanks! This can work also. I think the way is to make a new class GameEventListenerItem which has the event and the list. Make sure it is [System.Serializable] and then gameEvenListener class from the tutorial then has a list of GameEventListenerItems
@Shinos_99 Жыл бұрын
@@this-is-gamedev mmm i kinda lost u x) are u saying to create a new class with a list of GameEventListener ? the part i didn't understand mostly is this xD " Make sure it is [System.Serializable] and then gameEvenListener class from the tutorial then has a list of GameEventListenerItems" ps: maybe i did a working solution : { public List gameEvents = new List(); public List responses = new List(); private void OnEnable() { RegisterListeners(); } private void OnDisable() { UnregisterListeners(); } public void RegisterListeners() { for (int i = 0; i < gameEvents.Count; i++) { gameEvents[i].RegisterListener(this); } } public void UnregisterListeners() { for (int i = 0; i < gameEvents.Count; i++) { gameEvents[i].UnregisterListener(this); } } public void OnEventRaised(GameEvent gameEvent, Component sender, object data) { int index = gameEvents.IndexOf(gameEvent); if (index >= 0 && index < responses.Count) { responses[index].Invoke(sender,data); } } }
@Shinos_99 Жыл бұрын
@@this-is-gamedev also I have one more of a pretty dumb question: at the end of the tutorial we upgraded the system by taking the component and object parameters in it, but what if I am invoking something that does not need any parameter, so I just put a "null" as object? Also there are some limitations that bugs my brain here 1- i have seen that methods with "double" parameter can't get called in the editor response menu with the unity events 2- we can use only one parameter since methods with 2 or more won't show up in the editor neither Have u ever found a way to solve these problems?
@this-is-gamedev Жыл бұрын
If a parameter is null it is not a big deal, you just protect from it in the method itself.
@this-is-gamedev Жыл бұрын
Don’t hesitate to jump on discord, will be easier to assist for bigger code :D
@teleted300010 ай бұрын
It would be easier to follow along if the speaking and actions were done more slowly. Even starting and stopping the video, it is hard to see what is being done in the inspector.
@YoupiMatos2 Жыл бұрын
Hey, thanks for the video, I have a question though : If I want to keep the simple event with no parameters like you have during the first half, but also have the component and data event like you made in the second, I need a brand new listener for every type of event? Because I've tried but I've hurt myself to problems with inheritance, I've tried to extend "GameEventListener" but I didn't manage to override the UnityEvent with a CustomGameEvent. This is badly worded and I'm sorry, but if you get what i'm saying, thanks in advance! Love your tutorial from France!
@this-is-gamedev Жыл бұрын
Hey, thanks a lot! You can always call Raise() with no parameters, which then call the method with null, null. If you want different event signatures, then you need to define multiple CustomEvents etc. Not sure of the benefits.
@mcpete404 Жыл бұрын
this is very cool, thank you for this, I have one question, what if we want to stop listening for a reason, lets say an object becomes locked and shouldn't listen anymore but we still want it to be visible in the game?
@this-is-gamedev Жыл бұрын
If you disable the monobehavior or gameobject, it will stop listening automatically. But maybe, you would prefer to implement something like “ignore event”, directly in the target class. Because that class might know best when a particular event should be ignored.
@mcpete404 Жыл бұрын
@@this-is-gamedev thank you!
@Weahl2 жыл бұрын
Awesome! But I have a big doubt, is there no way to pass more than one parameter to a Raise()? If not, this is very very limiting no?
@this-is-gamedev2 жыл бұрын
You you can pass multiple parameters, it’s easy to extend that part of the code. Also, one parameter being of type object, you could also define wrapper class that contains much more information. Hope it makes sense :D
@Weahl2 жыл бұрын
@@this-is-gamedev I will need to learn more about C# then and how to do that, because coming from JS creating a class just to send more than one parameters sounds really weird for me, thanks a lot!!
@this-is-gamedev2 жыл бұрын
In JS you probably send {…} objects around like a context. Just with C# you create a class or send dictionaries, but dict. hold one type ^^
@Weahl2 жыл бұрын
@@this-is-gamedev noted, thanks again for your amazing work :)
@damionmccoy99668 ай бұрын
So I have been using this a while and its great but its been a while since i last used it and for some reason in the event listener component it wont show me the option for the callback method in the drop down when i have the parameters listed. I know i have done it before but i was hoping you can tell me what im doing wrong. If there are no parameters i can select the method
@bensilburn Жыл бұрын
Great video! Since you can add any component to the CustomGameEvent object it seems you don't need to add the GameEventListener to the component that responds to the event. In fact, your Unity setup looked like you have a "Level Events" game object with a whole load of Event Listeners - is that the idea? A single game object in the scene whose sole purpose is to listen for all the events and hook them up to the relevant components/methods? If so this seems like a 'sort of' singleton pattern, a monolithic event listener rather than listeners on each component, or am I missing something?
@this-is-gamedev Жыл бұрын
Yes, you will definitely have lots of GameEventListeners, but more grouped by domain. Like the SoundManager might have 1 GameEventListener per sound effect type. The HealthUI might have one listener per health status (damaged, healed, poisened,…) And if it get too big you can always make your own GameEventListener that might have lists of events, etc. This is just a starting base
@AstralNostalgia Жыл бұрын
why you put in blank "sender" ? in the "UpdateHealth(Component sender, object data)? in the PlayerHealth class?
@this-is-gamedev Жыл бұрын
I am not sure what you mean by “blank”. The sender is useful for the event receiver to know who send him that event. You might use that to access some kind of data or call methods or send other events.
@AstralNostalgia Жыл бұрын
@@this-is-gamedev hey , another thing I would like to know...if the suscripton and desuscription are automatically? I do not have to create and unregister method? or OnDisable? right? . thanks
@this-is-gamedev Жыл бұрын
Yes the GameEvenListener handles the subscribe/unsubscribe onEnable and onDisable. No need to code more
@AstralNostalgia Жыл бұрын
@@this-is-gamedev it is normal to get many listener as component ? depends on the component I want to suscribe? for example can I get UiManager with the GameListerener.cs attached and the UI manger implement fews mehtod per listener? applyint the logics ... thx
@tobyayres59018 ай бұрын
is there away to pass multiple arguments without adding lots of object data parameters?
@this-is-gamedev8 ай бұрын
Yes you can wrap the arguments in any kind of object like a custom Class and pass this as data
@USSR-Lenin-Stalin-Forever Жыл бұрын
CustomGameEvent not work, missing PlayerHealthListener
@this-is-gamedev Жыл бұрын
It seems that the PlayerHealthListener is missing. :D Check references, object in inspector, etc.
@USSR-Lenin-Stalin-Forever Жыл бұрын
I found a malfunction, I didn't want to transfer the component and it was so UnityEvent in a custom event and as soon as I registered everything worked
@USSR-Lenin-Stalin-Forever Жыл бұрын
real cool stuff!
@Strategiusz Жыл бұрын
Why do you need to do this SO events/channels from scratch as a List and not as a built-in UnityAction? I can see one advantage: you can check the length of the list in the inspector. But is there something more?
@this-is-gamedev Жыл бұрын
That's a very good point. UnityAction, as far I as know, is not serializable by default, which make it not work inside of an SO, where every field is meant to be serialized.
@USSR-Lenin-Stalin-Forever Жыл бұрын
it is not clear why if there is an eventhandler that can be made static?
@this-is-gamedev Жыл бұрын
If a field is static it will be shared among all instances of that class.
@Besttechnology Жыл бұрын
can be a system like that but automated, im working on case that i instatiate game object and each game object get data from api so i want game object create they own events
@this-is-gamedev Жыл бұрын
Interesting! There are for sure many approaches for your use case. Since it’s api driven, it’s probably all about passing the correct context around
@lorenam9739 Жыл бұрын
Hi, thanks for the tutorial! This is really helpful :D I have a question: since the "response" variable is of type CustomGameEvent (the one you modified) I cannot use response.AddListeners to assign methods to it (throws an error every time). I have a script that holds an array of ScriptableGameEvents and on Awake I want to add a listener to my gameobject for each of these gameEvents and assign them methods to call on response. Do you have an idea how I could achieve this?
@this-is-gamedev Жыл бұрын
Thanks! If you don’t want to do it in the inspector, To add listeners by code you have to instanciate a GameEventListener class or refactor that part to maybe accept an new “IGameEventListener” interface and you then have two classes : one for the inspector and one simpler one for using in code
@lorenam9739 Жыл бұрын
@@this-is-gamedev Thanks for the response! I'll try that out :)
@cabbibal Жыл бұрын
Epic tutorial, really great to follow along! I have one problem though: When implemented as shown, the game event Listeners dont unregister after I test it, and I have to manually remove them from the game event's list. If i dont, it wont work the next time. Any idea how to avoid this?
@this-is-gamedev Жыл бұрын
Thanks! Euhm, maybe OnDisable is not defined? Or, Could it be that you enabled some Play Mode option to start up faster? This will not fully reset certain aspects of the scene
@RapidTech Жыл бұрын
@ryandoesstuffapparently154011 ай бұрын
Does anyone know why I'm getting a type mismatch when I try to register a listener?
@ryandoesstuffapparently154011 ай бұрын
The only change I made was that I made the CustomGameEvent serializable, otherwise the response wasn't showing up in my inspector.
@ryandoesstuffapparently154011 ай бұрын
I'm seeing that he makes this change himself, so I don't understand why it isn't working for me. My code is exactly the same.
@wildbard4112 Жыл бұрын
I have a weird problem where there's somehow a type mismatch with the gameEventListener. I have a debug log that shows the object is in fact a GameEventListener but I get a type mismatch in my gameEvent SO
@this-is-gamedev Жыл бұрын
Weird. Difficult to help. Check all syntax, that everything is correctly saved, filenames, typos?
@wildbard4112 Жыл бұрын
@@this-is-gamedev Everything is correctly saved and spelled correctly. The event works if the list of listeners on the gameEvent is empty but there is still a type mismatch.
@this-is-gamedev Жыл бұрын
What line does the error point to? (You can also join on Discord, might be faster to help you out with screenshots and all)
@wildbard4112 Жыл бұрын
@@this-is-gamedev There's no syntax error or anything like that. The whole thing functions like it's supposed to if the list gets cleared OnDisable. I just don't know how the type mismatch is happening but it works how I have it set up right now
@this-is-gamedev Жыл бұрын
That’s good news then. Very weird. Is it maybe just Warning?
@show123asd Жыл бұрын
Is it possible to have a sender from Scene1 and a listener from Scene2? For example if I update some values in Gameplay Scene until the level ends and after the level ends it will load the Between Levels Scene where I would like to show the results. So basically what I'm asking based on the example above is: Will it work if the sender is in Gameplay Scene and the listener is in the Between Levels Scene? I've tested a bit, but with no result. The listener only listen while it was the same Scene as the sender.
@this-is-gamedev Жыл бұрын
It does work, because the event is an SO and is basically an asset. For example, my player published HealthChanged events. The listener is on another scene (like UIScene) where it updates the health bar. The SO should simply be the same on the receiver and sender side
@glitchover9894Ай бұрын
i can pass parameters throw this event , but i cant recieve them ?
@this-is-gamedev23 күн бұрын
The GameEventListener receives them. Drag and drop the same SO, add a function to call and that should be it.
@glitchover989422 күн бұрын
@@this-is-gamedev thanks
@abbenylund2 жыл бұрын
6:09 By adding component and object parameters to the listening function, I can no longer call it from the game event listener, it simply never shows up in the inspector. I can't find how you solved this in the video, am I doing something wrong?
@this-is-gamedev2 жыл бұрын
When you change, the method will be removed in the inspector, since the signature changed. Normally, you can go into the dropdown and link the method again. It should be at the top.
@abbenylund2 жыл бұрын
@@this-is-gamedev Indeed it was, I was looking at the bottom where it used to be for me, thank you :D
@seanc61937 ай бұрын
This system seems to have enormous drawbacks. Unless I'm mistaken you can only pass 1 parameter and you cant return? I was hoping you could enlighten me.
@this-is-gamedev7 ай бұрын
One parameter in this example, but that object can be anything. Like a class or struct containing all your data. No return because it’s event-based: fire and forget. It’s just a different way of coding.
@seanc61937 ай бұрын
@@this-is-gamedev Passing a struct is genius. I have 1 more question: I have decided for a Manager to manage 10 instances of a script, these scripts hold the values for the intractables in my clicker game. I then link 4 others to the Manager that calculate complex sums etc. I have opted for this method as to not use static function and actions, and also now return values. Other then the initial linking in the editor all functions are uncoupled. I was going to use your system to completely decouple my game but I was wondering which of the systems would be more demanding on the operating.system? Thank you so much for such a quick response on a 1 year old video. What a legend.
@this-is-gamedev7 ай бұрын
Maybe if you reach a high number of events per frame and those event all trigger expensive things, then you might get performance drops but that would be the same for both methods. One of my last videos, I moved towards 100% in-code solution (no scriptable objects). And it is also common to have a big manager, which is like the game’s blackboard (everyone sees the blackboard kind of concept). Just go for whatever is easier to maintain for your project.
@seanc61937 ай бұрын
@@this-is-gamedev Thank you so much for your advice, just do what feels right. I think ill use the manager for return values and use the listener to handle 1 way traffic. I think if you have 1 player this system is god, like in a more action orientated game. You're a genius and still replying so I'm going to be cheeky and ask 1 more question, this is the meat of my concerns about script performance. If you think of my game as very similar to Adventure Capitalist it will help you visualize.: Current cost is calculated like this: baseCost * (Math.Pow(1 + costIncrease, level) (This applies the cost increase exponentially) There is a MaxBuy feature that will show you the maximum upgrade you can afford and the calculation isn't an easy one. Its doesn't use loops or floating points but its not small. This cost needs to be updated every moneyinteraction to be accurate. This will need to make the calculation to update the UI. The money will update at most when its busy 5/8 times a second. The way I handle this: Line holds data and build/upgrade function. LineManager holds a list of Lines and scripts needed for moving money and calculating maxcost/speed/price and all scripts communicate through events to keep them decoupled. This way I can access the events without static references. Is this a valid way of handling the issue? Sorry for the essay. I've been learning coding for about 6 months and I still feel like a noob. Thank you so much for your help. When I talk coding to people they normally glaze over!
@lucaffo992 жыл бұрын
I think you miss the purpose by generally defining in the first seconds a "Best Way". There is not best way to do things, there are ways for sure, but it's best based on: Time, Maintainability and Performance. In your video you show us a scriptable event approching which is really cool for fast prototyping (Like a tech demo), but an ass in the hell when you run your game in production. Then i really miss what you mean by "Designer Friendly" allowing them to mess up all the game flow. You should make the game flow extendible and editable but now allowing them to broke the game. For performance reason and maintainability is really hard to use this methods, but in other hand is a way to fast prototype events (Even i prefer the old approch to define a class Events that handle all the events in that game context).
@phodaOG2 жыл бұрын
So c# event with extra steps?
@this-is-gamedev2 жыл бұрын
With extra modularity and user-friendliness for level designer :)
@dantoose8023 Жыл бұрын
@@this-is-gamedev Ha! In my experience, this just leads to level designers asking you to write mountains of small scripts for all their event functionality ideas ;)
@issaelalexanderynumazenten552 Жыл бұрын
Observer Pattern.
@ThatLazyGameDev Жыл бұрын
1 dev, 2 scripts 😭😭😭😭😭😭😭😭😭
@raelroque5595 Жыл бұрын
show how it work
@chillywilson4 ай бұрын
Why would they make it like this?
@JayadevHaddadi Жыл бұрын
Super cool! Isn't this what Jason Weimann talked about 1 year earlier in this video: kzbin.info/www/bejne/opikaX6fp81_e7c Seems a bit inflexible in how much data can be sent, there is only one argument for data there, what if we needed to send more? We then have to package it somehow right? Or make calls that take more arguments. Without any arguments one could also do a global broadcast system, like from this Unity talk: kzbin.info/www/bejne/ZnLUeGScec2Dipo What's wrong with a normal approach of having static or non-static Actions where the event is triggered and whoever wants can listen to them, then it is also much easier to modify the amount of arguments and correct the return value. Thanks! ☺
@this-is-gamedev Жыл бұрын
Yes, that's the same as Jason's video :O :D ! You can of course change the amount of data that is sent by changing the event's signature. Packaging / wrapping your data into another class is also an option, that's why it's an object, it can be anything. Nothing wrong with the normal approach. The biggest advantage is that senders and receiver really do not know anything about each other. No reference, no code to register/unregister anywhere, no names. They only share the Scriptable Object. You can imagine the Player having 1 GamEvent per action, like Attack, Jump, DoubleJump. Then, you can have 1 sound manager, completely separate that will listen to those events. But then, also a Statistics Manager that will track what the player does, by listening to the events. Maybe a Screen Shake Manager that listens to the Jump event etc... And you can delete or disable any game object and there will never be an error thrown.