The Power of Scriptable Objects as Middle-Men

Поділитися
Вставка
  • Опубліковано 10 чер 2024
  • In this video I'll show you how to use Scriptable Objects to design your game architecture to be flexible, easily debuggable, and extendable for both coders and designers.
    ᐅGet the full Source Code Bundle to my Unity Tutorials 🤓
    sam-yam.itch.io/samyam-full-s...
    📥 Get the Source Code 📥
    / 62243000
    🤝 Support Me 🤝
    Patreon: / samyg
    Donate: ko-fi.com/samyam
    Check out Mental Checkpoint!
    👉 / mentalcheckpoint
    ►🔗 Relevant Video Links 🔗
    ᐅThe Ultimate Introduction to Scriptable Objects in Unity
    • The Ultimate Introduct...
    ᐅUnite Austin 2017 - Game Architecture with Scriptable Objects
    • Unite Austin 2017 - Ga...
    ᐅPlayer Prefs
    docs.unity3d.com/ScriptRefere...
    The idea is to use a Scriptable Object as a middle-man for communication between two different scripts, and we use event-based messaging to shoot out events from the Scriptable Object to whoever is listening. This results in decoupling code and dependencies, making your code easier to rework and adapt to new changes.
    ►⏱️ Timestamps ⏱️
    0:00 Intro
    1:16 Mental Checkpoint Sponsorship
    1:48 Bad Example #1
    4:55 Bad Example #2
    7:28 Bad Example #3
    9:45 Additive Scenes Mention
    10:51 Scriptable Objects as a Middle-Man
    14:55 Scriptable Object VS Monobehaviour
    15:25 Dependency Injection
    16:18 Outro
    💖💖THANK YOU TO ALL MY PATRONS 💖💖
    ❯❯❯ My Links ❮❮❮
    💗 Patreon 💗
    / samyg
    💬 Discord Server 💬
    / discord
    🐦 Twitter 🐦
    / samyam_youtube
    📚 Facebook 📚
    / samyam.youtube
    🎵 Music 🎵
    Ambient Gold
    streambeats.com
    👍 Like and Subscribe! 👍
    🖥️ Computer Setup 🖥️
    *As an Amazon Associate I earn from qualifying purchases.
    www.amazon.com/shop/samyam
    Disclosure: This post may contain affiliate links, which means we may receive a commission if you click a link and purchase something that we have recommended. While clicking these links won't cost you any money, they will help me fund my development projects while recommending great assets!
    #madewithunity #gamedev #unity
  • Наука та технологія

КОМЕНТАРІ • 241

  • @ERSmith
    @ERSmith Рік тому +49

    I can't tell you how many times I've watched this video. So grateful you made such a beginner-friendly yet in-depth video. Thanks so much!!

  • @512Squared
    @512Squared Рік тому +20

    Another approach is a static class to hold actions that can then be invoked anywhere. That likewise doesn't have to sit on a game object of worry about being destroyed. But decoupled code can make it difficult to track event chains, since a publisher has no record of its subscribers. You have to use your search parameters in your code IDE to tracks event chains. Spaghetti is horrible, but so is a partially obscured event system.

  • @empty5013
    @empty5013 2 роки тому +15

    singletons are actually used in games more than most other programming fields because the usual downsides of singleton (global state) are not as bad in video games since you know your code will be run in a single contained application. singletons cause issues in projects like web servers which are doing loads of things simultaneously and having a single shared resource and single shared piece of state can cause loads of problems, in a game its much easier to manage global state and singletons are a good way to keep global state from getting messy.
    I'd also like to point out that your SOs are basically singletons implemented in a different way and have all the same issues with global state, plus some idiosyncracies with how SOs are implemented. The main advantage of this solution is you have avoided dependency chains, which is a problem that's already solved (most games will instantiate all their singletons at game boot time and set up dependency chains then)
    Event based programming also has it's own set of problems and downsides. However this is a useful strategy I hadn't seen before so thank you for the informative video.

    • @wumpie5267
      @wumpie5267 2 роки тому

      Thanks, your comment helped

    • @dreamcatforgotten8435
      @dreamcatforgotten8435 Рік тому +1

      There is a clear difference between non-Singleton SOs and Singletons [in the case of Unity, though I'm not sure what other game Engine also has SOs-- ]
      Domain Reload.
      Singletons require static referencing, so you must keep Domain Reload on to maintain a fresh state between Play Sessions in the Editor.
      SO have no such requirement since they are always considered loaded within the Editor, and when they are referenced [by a MonoBehaviour] in a Build.
      This difference means it is orders faster to test and iterate with non-Singleton SOs versus Singletons, especially as your project and assemblies grow larger.
      Edit: I'm being explicit about non-Singleton SOs, because you can implement SO's as Singletons. They're not mutually exclusive.

    • @user-uk9er5vw4c
      @user-uk9er5vw4c 9 днів тому

      Singletons are commonly used in web development, especially with frameworks that support hooks

  • @migueldc6845
    @migueldc6845 Рік тому +4

    I've seen the talk you're referencing ... and am very happy to found someone who goes and explains it in more detail! Thanks!!

  • @alfredoheights
    @alfredoheights 2 роки тому +13

    Thank you, this did so much more for me than the Unite Austin talk. I could not ever wrap my mind around what he was saying, but this is just a really well-done demonstration.

    • @samyam
      @samyam  2 роки тому +1

      Thank you! Appreciate the kind words 😁

  • @theUSpopulation
    @theUSpopulation 2 роки тому +9

    Thank you for this! I have to go back and change a lot of things for my personal project, but you did a great job showing me that will be worth it!

  • @AliceLoverdrive
    @AliceLoverdrive 2 роки тому +166

    A word of caution: since ScriptableObjects retain values _after_ exiting play mode, this approach may lead to undoing previous work if you ain't careful enough. Otherwise, great tutorial. I'd personally attack the problem in an example from a different angle, but it does illustrate the point fairly well.

    • @danielfazly1350
      @danielfazly1350 2 роки тому +42

      Yep, this is a common problem. Instead of altering the ScriptableObject, your scripts should make a new instance of it and alter that instead.

    • @MattiaBelletti
      @MattiaBelletti 2 роки тому +1

      I'm interested in comparing various solutions for this kind of problems: which architecture would you put in place to solve it?

    • @AliceLoverdrive
      @AliceLoverdrive 2 роки тому +13

      ​@@MattiaBelletti in this particular case, I'd go simple and just mark both player character's GO and UI manager go as DontDestroyOnLoad -- it's highly unlikely that the only data you'd need to retain about the player character is their health, after all.
      Also, I'd just make UI manager to FIndObjectOfType on awake to avoid making PlayerCharacter class being dependent on UI.

    • @CockroachSlidy
      @CockroachSlidy 2 роки тому +10

      @@danielfazly1350 No need for that. Just create properties and assign them from serialized fields in OnEnable in your scriptable objects. This way you can separate runtime data or even fetch it from PlayerPreafs.

    • @callmedeno
      @callmedeno 2 роки тому +1

      @@CockroachSlidy Can you explain that a bit more? So you have a sctiptable object which has default values, then in on on enable you get them from what serialized fields, from where a file?

  • @jonathanjblair
    @jonathanjblair 2 роки тому +4

    I remember watching your videos when you had less than 1k subs. So glad you stuck with it and are closing in on 20k. Keep up the good work.

    • @samyam
      @samyam  2 роки тому +2

      Thanks so much for the support 😄

  • @JoSke633
    @JoSke633 2 роки тому +9

    Awesome vid! You went through the concepts in a very digestable and clear way, adding some sweet graphics :)
    I think this approach really shines for making tech designer-friendly tools, which you mentioned at the end. If working with someone who can move around in Unity and iterate on mechanics and gameplay with these events without diving into code, it can be a huge productivity boost and fuel creativity while keeping the code decoupled. If just working with code, then I don't think it pays off compared to a regular event bus in C#.

  • @jaywha
    @jaywha Рік тому +1

    As my first introduction to scriptable objects, this was concise and extremely helpful. Looking forward to your other vids

  • @ShinichiKudoQatnip
    @ShinichiKudoQatnip 2 роки тому +18

    Your explanation is just nothing short of amazing!!!! So much love for this 🤗

    • @samyam
      @samyam  2 роки тому +2

      Thank you!!!

  • @rudrakpatra6579
    @rudrakpatra6579 Рік тому

    Your way of explanation is so simple and easy to understand. Even before watching, I somehow know that I will be able to digest all of the concepts!

    • @samyam
      @samyam  Рік тому

      That is my goal! Glad it is coming through 😄

  • @ironcladvr
    @ironcladvr 2 роки тому

    As I search to scriptable Objects, you've put out a video helping me understand them better.
    Many thanks Sam!

    • @samyam
      @samyam  2 роки тому

      Glad to help! :)

  • @vornamenachname906
    @vornamenachname906 2 роки тому +15

    that has nothing to do with "scriptable objects" , its just the correct event handling.
    one last advice:
    use x?.invoke() with the questionmark to prevent exception's in case the delegate x is empty.

    • @vornamenachname906
      @vornamenachname906 2 роки тому

      *exceptions

    • @Kalahee
      @Kalahee 2 роки тому

      The point here was to use SO as data storage over playerprefs or singletons. Event handling is just an example

  • @tobinrysenga1894
    @tobinrysenga1894 10 місяців тому +2

    This is really just moving the dependencies to something else that is not scene-dependent. It is quite useful though. The same could be achieved with C# events and I'm hoping the persistent side of scriptable objects isn't adding some overhead to these events. One thing you didn't mention though is since it is not scene dependent, it would be vital that you remove listener when your objects are destroyed or you will get exceptions.

  • @Brioshie
    @Brioshie Рік тому +2

    Although I've been using them already, you made me approach differently and optimize my project a lot! For example I have one scriptable object with a list of all my enemy behaviors and each enemy simply picks their properties from there. I can change only one asset now instead of 10s of prefabs

  • @akitoakito
    @akitoakito 2 роки тому

    This is a great tutorial on scriptable objects. It guides you through both the why and the how.

  • @chrismcintosh2286
    @chrismcintosh2286 2 роки тому +3

    i am doing something similar, but different in my RTS game. I am using scriptable objects to define Unit types. these can be created in the UI, and you can assign the values/sprites/etc to them.
    However I then have a Unit class, that has a UnitType property that is assigned the correct scriptable object. the Unit class does not alter any data in the ScriptableObject as that is being used as a Template for new instances of that type of unit. There are some helper methods I have in the UnitType to get the cost to craft the unit, its default health, damage, etc.
    I then have a singleton Unit manager class that handles spawning / tracking all of the units in the game, and also helps with saving/loading of the unit data. (The unit class is Serializable). I also have an independent script that is just for displaying details in the UI. So that concerns are kept separate from one another.

  • @MagicPigGames
    @MagicPigGames 2 роки тому +3

    I like to make a Game version for in-game use. I.e. "ItemObject" is a scriptable object, and "GameItemObject" is the runtime variant. When creating the game version, JSON Utility can be used to clone the scriptable object data into the game version, which can then be changed and saved.
    I also use a repository object in the scene to reference the original Scriptable Object if needs be.

  • @vilks_jan
    @vilks_jan 2 роки тому

    Fairly new to unity. Thank you so much for great videos so far. You give enough information for me to understand key concepts and it helps me tremendously whenever put it into context. Also you gloss over related concepts which is just amazing. One thing I was struggling with was instantiating health change event (cannot instantiate abstract class)
    keep up the great work!

    • @samyam
      @samyam  2 роки тому

      Thanks so much!

    • @aaronspencermusic
      @aaronspencermusic 2 роки тому

      Did you find a sollution to the abstract class thing? I'm thinking it's because i'm not on the correct version of unity

  • @hanzofactory
    @hanzofactory 2 роки тому

    Thank you so much. I was really hung about how to use events with non-global data, and I managed to implement it thanks to this video!

    • @samyam
      @samyam  2 роки тому

      Glad it helped!

  • @thatoneguy9153
    @thatoneguy9153 25 днів тому

    This is a great example! Great use of ScriptableObjects.
    I absolutely love the note at the end on Dependency Injection. I would argue, if you use interfaces correctly there isn't really a need for ScriptableObjects this way. I prefer that method, but I can definitely see the usefulness of visibly seeing the data through the scriptable objects.

  • @GrahamOfLegend
    @GrahamOfLegend 2 роки тому +3

    Such an excellent video! I really love scriptable objects and want more people to get into using em 🙌🏽🔥

    • @samyam
      @samyam  2 роки тому

      Thank you!!

  • @kristianthaler6525
    @kristianthaler6525 Рік тому

    Very clear explanation of why you should avoid dependencies, thank you.

  • @teleted3000
    @teleted3000 4 місяці тому

    Clearly explained. Well done.

  • @richardcabral9425
    @richardcabral9425 11 місяців тому

    Wonderful, when I was learning SOLID I didn't think it would be so useful in game dev.
    Congratulations on your didactic

  • @snek5385
    @snek5385 2 роки тому

    This is sooooo useful! Thanks!
    Wish to see more contents like this.

  • @cinnamonmatcha9406
    @cinnamonmatcha9406 2 місяці тому

    After starting to consistenly use this I can say that it changed my life

  • @ragerungames
    @ragerungames 2 роки тому

    Great video.. Really liked the example problem you stated before and giving solutions to it!

    • @samyam
      @samyam  2 роки тому

      Thank you!!

  • @1oglop1
    @1oglop1 3 місяці тому

    Thank you very much, your video has saved me a lot of time. C# is a new language for me.

  • @jl6723
    @jl6723 2 роки тому +1

    Personally, I like to have my managers use a global static dependency injector. This works well for having a manager talk with it’s subsidiaries in scene though.

  • @SoaringSimulator
    @SoaringSimulator 2 роки тому +1

    There is a hidden important script code at 13:35!
    Having no references to other game objects is so difficult and at the same so important! In Unity is difficult to understand how references work inside a project. And if you hide or delete a game object with references that point to it you can get hidden bugs (null references) that do not pop up in the console.

  • @wspascoe
    @wspascoe Рік тому +1

    I remember trying this after the talk you mentioned but wasn't there something weird that happens when you actually build a game into an exe. I can't remember it's been awhile but still a great video.

  • @benjaminlehmann
    @benjaminlehmann Рік тому

    Great video. Thanks for the insight.

  • @datbubby
    @datbubby Рік тому +1

    This is so helpful! Thanks :)

  • @ferhatkaya9217
    @ferhatkaya9217 2 роки тому

    Seen your channel newly. Youre amazing

  • @michaelshemesh3141
    @michaelshemesh3141 2 роки тому

    my app is a GUI so this really helps a lot, thank you!!

  • @asadickens9353
    @asadickens9353 2 роки тому +2

    I don’t know why, but your videos are the only videos i don’t have to physically watch. I can listen to them and follow along easily enough!
    It might be the simple explanations and step by step process of how you think mixed with my general knowledge of unity.

  • @AlexBlackfrost
    @AlexBlackfrost 2 роки тому +3

    Very great tutorial, I like how you use bad examples first to explain what works and what doesn't.

    • @samyam
      @samyam  2 роки тому +2

      Thanks Alex!! Hope it helped 😄

  • @lekretka
    @lekretka 10 місяців тому +2

    Well, great video regarding explanation and graphics, but I have strong opinion against this approach and scriptable object architecture in general.
    1. While it can be designer friendly, it's error prone because you can forget to assign the event SO or someone can delete it.
    2. As a programmer it's really too much work to jump from code to editor back and forth.
    3. It creates the same problem as singleton bad example, you can't create more than one of these if you have multiple objects with Health logic. This is suitable for one player to many UIs, but it's not suitable for 100 units with 100 healthbars.
    Architecture imo should give you flexibility, but this approach requires separate Health handling for Player and other objects.
    I also think that bad examples to this approach comparison is quite unfair. There are much better ways to create health UI system without event SO approach.
    1. UI which grabs reference to Player which has "Action/UnityEvent HealthChanged" is pretty fine.
    2. Static EventBus which can be written in 20minutes is fine.
    3. Simple static field in Player or somewhere else with Action/UnityEvent is fine.
    Last two give you same decoupling between Player and UI.
    I'm glad you covered dependency injection topic, but for me it's default way to go and I would encourage more people using it.
    It solves all dependency/decoupling problems and let you build proper architecture.
    Sure it requires a framework, but if you are really at this point when simple approaches, I suggested above, don't fit you project it's probably time to learn Zenject.

  • @omyb
    @omyb Рік тому

    It's a very interesting video! Just one question: what's the pro of doing that instead of a classical event in the player script with the UI manager listening to it?

  • @bobbob9821
    @bobbob9821 6 місяців тому +1

    Its my understanding that scriptable objects are best for storing read only data like item attributes and you don't want to be messing with changing values during runtime.

  • @lawsylawsy6593
    @lawsylawsy6593 2 роки тому +1

    Awesome video! Breaking everything down understandably for new coders! Beef it up by making a generic scriptable object event system and you have a totally decoupled code

    • @samyam
      @samyam  2 роки тому

      Great idea for another video! Thanks 🙂

    • @lawsylawsy6593
      @lawsylawsy6593 2 роки тому

      Happy to share code if you are interested? made the event system as a unity package for ease of sharing between our projects

  • @SMT-ks8yp
    @SMT-ks8yp 2 роки тому

    Don't quite get it. For example, currently I'm using a script on the player object which does nothing but providing references to other player components so if anything wants to interact with the player components, it could get this script and reference whatever it needs from there. Should I replace it with scriptable object and references with events? If so, where should I get references to the object? Would it be fine (and not tedious) to manually put it from the project through inspector in every script which would interact with the player, like every enemy, door, NPC or whatever?

  • @Cameo221
    @Cameo221 2 роки тому +10

    I've seen the unite videos, looked deeply into SOs, tried the Unity Atoms package, but all these ideas have made me formulate some thoughts.
    I've had a personal concern with using SOs as an event based medium. And it's that the project window could easily be muddled with seemingly hundreds of these objects, especially as a project grows, and no amount of folder organisation can seem to solve that problem. 🤔
    But I'd be interested in a solution to this problem? It's a real problem that I've seen discussions about this before for, and is the main caveat that I could see happening when architecting events with SOs.

    • @Cameo221
      @Cameo221 2 роки тому +1

      And to add to this, it's very easy for a designer to duplicate assets. So how could we know if something, somewhere in the entire project, is listening to, or broadcasting an asset? It's far too easy to delete assets that may have originally been thought to not be used anymore, and then the game is broken since it was in fact being used somewhere.

    • @Cameo221
      @Cameo221 2 роки тому +2

      Something to alleviate this problem, is to have the assets use some form of editor scripting to detect if the asset is being referenced somewhere in the project. (List of broadcasters and listeners in the event's inspector) This would make tracking events drastically easier. I just haven't seen this done before, but would definitely make using these a whole lot easier.

    • @MattiaBelletti
      @MattiaBelletti 2 роки тому +5

      @@Cameo221 i think these points were briefly touched in the unite video, where he stressed the necessity for planning debugging tools ahead (which to me includes stuff like "who is attached to this event or data in the project?", something an usual code editor is able to answer with a "show all references" tool).

    • @Cameo221
      @Cameo221 2 роки тому +1

      @@MattiaBelletti Certainly. I would definitely use this as long as it can track references, just like in code 🙂

    • @lucaffo99
      @lucaffo99 2 роки тому +4

      I agree with mostly all that you had written. Scriptable objects are good as data containers. But you can use it as solution only when you have some infrastructure to use it. Events like most engineering problems, are half resolved. In this case the only way is to escape from project folder hell and drag n drop hell. Implement you tool UI to select scriptables (Like they do odin but you can use you custom editor solution).
      In my opinion the solution to this problems is to trash the project folder scriptable hell and not try to use scriptable as drag n droppable solutions. At least you can use selector on custom editor window etc..

  • @ToddHarrisonDavis
    @ToddHarrisonDavis 2 роки тому +2

    Good video, but it left me feeling confused about one of your main points, which was the problem of having things coupled or dependent on other things. For example, at one point, you were talking about how if you wanted to test one Manager-class that had references to another Manager-class then you would have to include that other Manager-class in the test, because we need to have a reference to it. In order to fix that, you propose we use Events to fire off functions in other classes, as that is seen as a "decoupled approach". But it's not. In order to subscribe to an event in another class, we still need a hard-coded reference to that class. Sure, we could add some code to see if the reference exists or not, and if not, then nothing gets subscribed to. But that would remove our ability to test those functions, no? I've seen some games where an EventManager class is instantiated as a singleton, and then everything else kinda uses that as a "bridge" so that there is only one reference to maintain, and that helps cut down on the need for multiple references. But it still is not completely decoupled. Am I misunderstanding how this works?

    • @andrueanderson8637
      @andrueanderson8637 2 роки тому +2

      Just wanted to validate your concerns Todd, you're absolutely right. There are no perfect solutions to the problem of coupling, the most we can really do is make it as hands-free as possible. Most of the time that means adding to the "execution context" whether that is editor references or singleton references.
      Taking the bigger issue here, this video is clearly just a new creator trying to build an audience. Every point comes directly from other sources, including the Unite 2016 talk and the Unity Open Source project called "Chop Chop!" - If you're genuinely trying to learn something I recommend going to the direct sources. A lot of context is lost in translation while this creator attempts to digest the information and put her own "content flair" on it for audience building purposes.

  • @steveh3206
    @steveh3206 2 роки тому

    Really helpful videos, thanks!

    • @samyam
      @samyam  2 роки тому

      Thank you :)

  • @PeterMilko
    @PeterMilko Місяць тому

    I use dont destroy on load. For stuff like that i use delegates actions and unityevents. When you call them check for null event?.Invoke
    ()

  • @jugger6228
    @jugger6228 Рік тому

    OMG that's so awesome. Finally a solution without a bunch of annoying managers and singletons. Thank you very much :D

  • @PaperMouseGames
    @PaperMouseGames 2 роки тому

    Awesome video as always! I love scriptable objects and use them for everything I can 🤣

    • @samyam
      @samyam  2 роки тому

      Thank you!! 😄

  • @ardPArd
    @ardPArd 11 місяців тому

    Thanks, for your tutorial sis

  • @johnnewton7401
    @johnnewton7401 2 роки тому

    When the scene is reset with the scriptable object, how does the reloaded UI slider get the current health value? The event is only fired when the health is decreased so why is it updated when the scene is reloaded? I feel like I'm missing something. Thanks :)

  • @TheGugustar
    @TheGugustar Рік тому

    In your example of an event subscription "middle-man", what would be the advantage of a Scriptable Object instead of a public static class?

  • @lee1davis1
    @lee1davis1 2 роки тому

    I'm glad you showed the problem with singletons. I know a lot if you tubers that still promote it.

  • @HenonChesserPlus
    @HenonChesserPlus 4 місяці тому

    Given this example, how would you handle several entities/gameObject who need their health managed? Would you have to create a new Health Manager SO for each entity?

  • @HaniSharif
    @HaniSharif 2 роки тому

    This might be a silly question. But how do i use the same system to have a health decreasing and auto health regeneration after say. 5 seconds?
    Great tutorial btw. Helped me a lot!

  • @er0s14
    @er0s14 2 роки тому +1

    Can this solution scale with multiple instances of Player? Seems like it might be limited to just one player?

  • @alexf3946
    @alexf3946 2 роки тому

    This is magic, thanks!

  • @TheLazyIndianTechie
    @TheLazyIndianTechie Рік тому

    Hey. Firstly, thank you for this detailed video. It's a lot of hard work and it's much appreciated.
    Just wanted to check, have you looked into using Visual Scripting Variables for the carrying data across scenes? I use it regularly and it's quite easy to setup and work with.
    p.s. - Not sure of the performance implications but it;'s definitely easy to set up.

    • @samyam
      @samyam  Рік тому +1

      Thank you! No I haven’t looked into it, wasn’t aware of it. I’ll take a look when I have time!

    • @TheLazyIndianTechie
      @TheLazyIndianTechie Рік тому

      @@samyam Awesome. Yeah would love your take on it. I was planning to record a really short video and put it on my channel as well. Looks like a lot of people haven't started using it and it might help someone!

  • @dibaterman
    @dibaterman 2 роки тому

    So, to take this a little further, creating a "Character" SO to be a database for the health SO and other character related functions could work as a library without changing the actual Health SO? So many objects could be using the same Health or other stat SO.
    So basically the Database SO would I could make a List for the values of the attached SO's and that holds the values that are changed. It's getting confusing for me, I'd have to do this to see where it screws up XD. Thanks for the video, this looks like a lot of effort.

  • @perabajadev
    @perabajadev Рік тому

    I've got a question for you about what happens if I need to have multiple gameObjects with the same component, such as health Component and I need to modify the values differently for a player or some enemies. With ScriptableObjects wouldn't have a health value for each one, in fact I would only one

  • @coderious4568
    @coderious4568 2 роки тому

    Excellent tutorial!

    • @samyam
      @samyam  2 роки тому

      Thanks so much!!

  • @inquisitortr7930
    @inquisitortr7930 8 місяців тому

    Hi samyam can we apply this scriptable object for more than one player. You know we have one player here but what if we have 3 or 4. They will have different health values. Will just one scriptable object is enough or should we create multiple scriptable object to change health of players seperately? By the way awasome video thanks.

  • @TheCecchino98
    @TheCecchino98 Рік тому

    I'm wondering if it the scriptable object approach is still worth using if none of its data/events have to be used outside of one scene

  • @IlaiyaBharathi
    @IlaiyaBharathi 2 роки тому +1

    ooh.. can't wait...

  • @ShaneCurtis1705
    @ShaneCurtis1705 2 роки тому

    You could also just make the slider dependant on the player which would not matter anywhere near as much. Because in what case is a level going to have the slider and not the player? Just make it on update get player health

  • @ramongonzalezfernandez8904
    @ramongonzalezfernandez8904 2 роки тому

    Could you not use the scriptable object implementation on the health manager class (in a separate scene)?

  • @janjonas270
    @janjonas270 8 місяців тому

    have a question, is there a reason not to make Singleton-type SOs static? because having a serializefield reference to the asset can be very annoying once you have tons of objects that get their event impulses from a single SO.

  • @AndrewKolb773
    @AndrewKolb773 2 роки тому

    anyone else getting getting error CS0144: Cannot create an instance of the abstract class or interface 'UnityEvent' on line 23 of the HealthManagerScriptableObject.cs? Anyone know how to fix this? I'm using Unity 2019.4.31f1 to test this out.

  • @MaZyYTube
    @MaZyYTube 2 роки тому +1

    I worked on many different projects from small to big. We weregetting disappointed if the game also gets bigger. You have toooooooooo many scriptableobjects everywhere. You need to search, click here and there to finally work with them. Sometimes you also do not know where it is used. The question often is there "Do I need it.. can I delete it?". Often you would need your own Editor Tool Solution to see what is where connected. It is great for designers but if you start to make easy for your designer, why not use visual scripting?
    This also makes problem with buttons. Did you ever say "oops" OnClick still tries to invoke function but actually you removed a button? In big projects this happens very often. Thats why it is better to have Button reference in the code instead doing it via the inspector.
    That's why we used other event system. We now can use same thing without scriptableobject and with coding only. For instance we can do RegisterEvent(OnDamage). Everybody who register Damage will receive the Damage object. This works everywhere and has not dependency.
    The goods is IDE can show all references and connected scripts. You can wrote listener if you want to just as drag and drop component. Still works for designers as well.

  • @ThunderaRafa433
    @ThunderaRafa433 Рік тому

    I have a problem of accumulation time in a cooldown system... I make a cooldown system of 10 second to re spawn a new object useing a cooldown system... the problme when I got outside the play mode.. .the value changed... I mean is stored in the SO... sometimes can be ok, sometimes not.... the problem stast if I pass 90 secondes... I need to waitn 90 second for the next time to spawn a gabme object... for example , if I break the game at 10 second of playint time, I store 10 seconds, so the next time to spawn will be 20... the next one 30 , so far and so on.

  • @ferhatkaya9217
    @ferhatkaya9217 2 роки тому

    Samyam i need help! İ downloaded Starterassets. İ deleted mesh renderer of PlayerArmature and put my character obj into "geometry". Everything was fine,animations fine, i was able to put animations.. but i cannot apply animation rigging. Actually İ do but it gives errors. Do you have any idea about it?

  • @Shineglow
    @Shineglow 3 місяці тому

    I've seen the original video, but I still don't see how I can implement this architecture in a game where there is more than one playable object. Imagine I have a multiplayer game, with a variable number of players, maybe 2-8. And many, MANY enemies, at least hundreds of them. My characters have different properties, such as health, weapons, speed. Do I need to use SO for each character variant? But what if I need more than one copy of any character for enemies or players?
    Help me understand.

  • @chocobo678
    @chocobo678 2 роки тому +9

    Hi, great video! You've pointed some important insights about SRP, decoupling and singletons, which is all great. The only thing that I actually dont agree is using SO as a middleware... you basically implemented a Publisher/Observer pattern but adding a SO, you could just make a simple Event Manager to handle messaging without it, the code would still be decoupled and you wouldn't have to make another SO for each corner case. Also what if multiple objects have to implement the same health logic? They cant just reference the same SO because they will always trigger this SO (e.g: you have character A and character B both referencing the Health SO. You have slide A and Slider B, both listening to Health SO. If character A decreases Health, both slider A and B would trigger)
    About persisting the data between scenes, I believe just serializing into json/binary would do the work

    • @timothysdug5832
      @timothysdug5832 2 роки тому

      Hi! Sorry to bother but could you (or anyone reading this) elaborate on why is that usin SO as a middleman is unnecesary? I'm just getting started with this part of unity, but i'm not a begginer. I used Singletons in very basic proyects and now I kinda understand that they are bad when the project gets big. I started reading about unity events and how powerful they are, and now I encountered this SO based architecture in many vids that use SO as channels between triggers and listeners, that sounds powerful but I get the same vibe as you, is it really necessary to implement a channel for each communication? Doesn't it get messy? How would you implement a middleman that does what an SO does without it?
      Thanks for reading, and sorry for my bad english i'm a little rusty.

    • @chocobo678
      @chocobo678 2 роки тому +5

      @@timothysdug5832 hi Tomás. The approach on the video is an abstraction to the Publisher/Observer pattern, which consists in decoupling entities that need to react to events in an application.
      Taking the example of the video, imagine that you have a Health object, and when the Health value is updated, different entities must react to it (e.g: the screen must shake if HP is subtracted , the UI must update the HP bar, the Death Logic must validate if the character is dead, etc.). In a highly coupled code, the HP script would manually call all these callbacks. This is bad because you delegate tons of responsabilities for a single class (HP), which means this class would have to know details of every class that should react to the HP Update, leading to a convoluted code and violating the Single Responsability Principle.
      The Observer pattern is a solution to ensure that a publisher (in this case the HP class) doesn't have to know every single observer (all the classes that must react to the HP update) and vice versa. In this pattern, the publisher just publishes a message/event "announcing" that something happened, and every listener subscribed to the message/event should react. The idea here is that none of these entities should know details of each other, the only thing connecting them is a Middleware that manages to assign publishers and observers.
      On the video approach, the middleware is a Scriptable Object, and I pointed on my first comment some of the problems in using SOs for that purpose instead of having a simple class managing the events.
      Of course that this is not written in stone, and there a multiple uses for SOs and for some cases it might be enough, but I personally wouldn't recommend it. If you're interested, this blog post contains a different approach to event handling that I really enjoyed and am currently using in personal projects:
      theliquidfire.com/2015/06/15/better-than-events/

    • @timothysdug5832
      @timothysdug5832 2 роки тому +1

      @@chocobo678 I can't thank you enough for taking that time to write such a complete answer. You've given me a lot to think about and read. I couldn't find a straight answer to this issue anywhere.
      In the end i'll use both SO architecture and managers for events just to fully understand what each of them mean.
      Again, thanks a lot.

    • @FullMe7alJacke7
      @FullMe7alJacke7 Рік тому

      You're forgetting about how important it can be to make things in a designer friendly manner, therefore avoiding the need for changing any code.
      A designer can change these things by dragging SO files around.
      Also your mentioning of multiple instances being effected is easily fixable

  • @MickDarkstar1
    @MickDarkstar1 Рік тому

    Greatest problem with being a software developer starting with Unity is the absence of IoC and Dependecy Injection. I´ve seen third party solutions, but this should be available out of the box.

  • @TextGuy
    @TextGuy 7 місяців тому

    Not sure if you still read comments here, but I am curious why not we just use a static class to solve the issues or is there any other benefits that comes with this SO + event architecture that a static class cannot solve.

  • @bitmammothOG
    @bitmammothOG Рік тому

    So would DI be good for external dependencies or loading databases/caching, then using scriptable objects to pass around data between those dependencies without creating tighter coupling? (Great Video!)

    • @bitmammothOG
      @bitmammothOG Рік тому

      I mean can't we use DI to inject scriptable objects that already have the data availability/persistence deliverables filled by the di and updated by the game? Then move the data from SO's to db/cache using entities when persisting?

    • @bitmammothOG
      @bitmammothOG Рік тому

      Hmm only on client side, it would still need to be serialized on serverside, then it would need to update the SO's on client side from the deserialized data. Interesting :)

  • @No_Ghosts
    @No_Ghosts 10 місяців тому

    How is the scriptable object pattern more de-coupled than the singleton pattern? Seems identical

  • @madscientist338
    @madscientist338 2 роки тому

    Why use UnityEvent and add a NonSerialized attribute? You can just use Action or am I wrong?

  • @qin6409
    @qin6409 2 роки тому +1

    I come ti watch her video not only because of the tutorial, but also enjoyable voice

    • @samyam
      @samyam  2 роки тому

      Thank you :)

  • @HelPfeffer
    @HelPfeffer 2 роки тому

    I enjoyed the video :)
    New sub

  • @Barnzy_
    @Barnzy_ 5 місяців тому

    This is probably "bad to do" but I made my SaveManger a singleton this holds the player prefs and all I need to do when I save something is just set it in the instance save function, made using player prefs alot easier and seeing all I really store for saving and loading is world generation data & soon to be a list of objects+positions it's not dependent on anything but it's still something I'm very new with 🤔

  • @berliangur
    @berliangur 2 роки тому

    That's great, but about Depdency Injection, is there a way to initialize objects with correct references in code rather than drag&drop ?

    • @slimsXV
      @slimsXV 2 роки тому

      The drag drop method IS dependency injection.

  • @syriuszb8611
    @syriuszb8611 2 роки тому

    It's interesting, although I think that the leg work is done by the observer pattern.

  • @mahee1931
    @mahee1931 2 роки тому +2

    Ha!!! All 3 bad examples can be found in my current project. Thank you for the great content.

    • @samyam
      @samyam  2 роки тому +1

      😂 Well every project is different and maybe another way makes more sense! But for larger projects and teams SO’s are a great option 👌

  • @Luis96ef
    @Luis96ef 2 роки тому +2

    I was wondering if this approach would still be worth doing, for enemies for example; wouldn't you still need to spawn lots of instances of the scriptable object along with their monobehaviours?

    • @lvx969
      @lvx969 2 роки тому +2

      You wouldn't need this system for enemies. The main point here is the decoupling of UI from Player Health code. Enemies won't ever have this level of coupling between Health HUD elements. Enemy scripts can be designed independently from the player systems.

    • @akitoakito
      @akitoakito 2 роки тому +1

      It depends. Scriptable objects are just assets. You could create a simple enemy game object that has its AI and other starting stats stored in a Scriptable object. Then you could have a MonoBehavior reference it. That way you can easily swap the enemy AI to see which type of enemy works best in that given level. Unite 2016 has great talk about this.

    • @TheKr0ckeR
      @TheKr0ckeR Рік тому

      @@akitoakito still doesnt answer the question about +100 enemies

  • @peartreegames
    @peartreegames 2 роки тому +10

    Great content, nice breakdown of the concepts. My only two cents are regarding the thumbnail; this trend of putting viewers down by telling them they're "wrong" and they must do things a "right" way is just silly. I've been seeing it more often lately and even when done in a jokingly way it just makes the community seem elitist.

    • @Vastlee
      @Vastlee 2 роки тому

      That's marketing brother. We don't have to like it, but it gets clicks.

    • @samyam
      @samyam  2 роки тому +4

      It’s not meant literally or to bring anyone down, and this was actually the first time someone else made the thumbnail for me. Playing around with thumbnails to see what gathers more engagement. Sorry if it bothers anyone!

  • @ridlr9299
    @ridlr9299 2 роки тому +2

    Is there a reason to use UnityEvents instead of regular c# events?

    • @akitoakito
      @akitoakito 2 роки тому

      UnityEvents add convenient functions that can be used. It all depends on what the problem you are trying to solve is. If you aren't seeing any negative effects from using UnityEvents then they can be quite useful.

  • @stuffstuffington39
    @stuffstuffington39 2 роки тому

    Wasnt the decoupling part of the solution entirely due to using events? Couldnt the same decoupling be done with the singletoln pattern? Fire and forget health change events and if no singleton is listening, no worries. Im probably mising something. Interesting to hear about all the different approaches one could take

  • @Link89110
    @Link89110 4 місяці тому

    A scriptable objet has a single reference to all game object in the scene, so what should i do if, for example, i have to create multiples enemies with the same base stats, but not the same actual health ?

    • @ProfParzival
      @ProfParzival 3 місяці тому

      Instances. Or make life easy and use Unity Atoms

  • @someoneontheinternet3090
    @someoneontheinternet3090 2 роки тому

    I can't believe how much trouble I'm having wrapping my head around these things. Around all of it really. I get it eventually but man, I don't know if my brain was made for this stuff.

    • @samyam
      @samyam  2 роки тому +1

      Just keep going and making projects, it’s all about experience and practice; you’ll soon be an expert!!

  • @kobe_24
    @kobe_24 9 місяців тому

    Aren't the scriptable objects writable only in editor?

  • @iCraftix
    @iCraftix 2 роки тому

    That health manager scriptable object is fine for a player, but how would you do to keep track of the health of hundreds of enemies that can spawn at runtime?

    • @pogudesu
      @pogudesu Рік тому

      I believe it's not a good idea to make a health Scriptable Object for the enemies or any other object that requires a lot of instance.

  • @akn638
    @akn638 2 роки тому +1

    This video as good as ryan hipple's talk. I immediately subscribed! Keep up the good work and thanks for the video :)

    • @samyam
      @samyam  2 роки тому +1

      Thanks so much!! 🙂

  • @neozoid7009
    @neozoid7009 2 роки тому +1

    Awesome 👍

  • @cuttlas2955
    @cuttlas2955 2 роки тому

    I thought we cant change Scriptable object values in the build ... ( it only works in editor )
    or am I missed some thing ? or is it changed now ?

    • @no00ob
      @no00ob 2 роки тому +1

      You can change them they just wont get saved between sessions like in the editor

  • @OctoManGames
    @OctoManGames Рік тому

    To keep values over scenes you can simple use static values anywhere. The additive scenes should be more common practice, but is barely used. Delegates or Events should be used more often as well.

    • @dmas7749
      @dmas7749 Рік тому

      not to downplay statics, but you can only have one instance of a static variable. if you want to have a trap that damages foe and friend alike, you'd have to account for both a static variable for the player and the ones for enemies. or you'd have to consistently update the static variable through the player's health manager script

    • @OctoManGames
      @OctoManGames Рік тому

      @@dmas7749 Once anyone takes damage, you of course need to update values, this process is best used with em delegates as mentioned, once you leave scene, to load new scene you update the static. There are no constant updates on statics needed. But it's all about structure. The best thing on static, it doesn't have to be in your scene as well.

    • @dmas7749
      @dmas7749 Рік тому

      @@OctoManGames my understanding of delegates is pretty shit, what all do you know about them?

    • @OctoManGames
      @OctoManGames Рік тому

      @@dmas7749 As described in the above video, delegates are literaly events, any instance can subscribe to. Like a newsletter, if something happens, the message gets send to all listeners/subs and they can act with whatever they have subbed to the newsletter.

  • @TheKr0ckeR
    @TheKr0ckeR Рік тому

    Nice one, I really like SO's, But i have a question. What if we have 100 enemies in our game, are we gonna create 100 SO's for every enemy? Especially they are getting spawned?

    • @petunientopf42
      @petunientopf42 Рік тому

      Hey, I think I can help you there. If they are all the same enemy with the same stats, every instance can just have a reference to the same SO. In this case, you would probably have a single enemy prefab with a script that has a reference to the SO and instantiate it 100 times. But if each enemy is supposed to have different stats (I don't think that is what you mean, though), you would probably need a SO for each one of them, yes.

  • @akn638
    @akn638 2 роки тому

    I have enemies which use same implementation. When i deal an enemy it lowers scriptable object's value but also changing health other enemies. Can you help?

    • @dreamcatforgotten8435
      @dreamcatforgotten8435 Рік тому

      For things like enemies, they should have their own instance of a ScriptableObject that acts as their data.
      The reason why the Player has a use for Asset-level interactions is because the Player is designed to be a persistent entity, as well as other things that will be reused throughout the game (Items, UI, etc)
      Do you have a need for the same enemies to always exist throughout your scenes, in the same fashion as the Player?

  • @Barldon
    @Barldon 10 місяців тому

    Something that confuses me about this technique is; does this not create pretty tight coupling in of itself?
    If your player health lives inside an SO rather than the player itself, you run into the exact same scalability issue as a singleton does; it becomes incredibly difficult to change that SO significantly, you can't remove it if the health system changes, and you can't add another player without adding another SO and refactoring everything that depends on it. In essence, a SO kind of *is* a singleton - just one that doesn't live inside the scene.
    They're certainly one of the most powerful tools in Unity, but since watching that original talk this has always felt like a bit of an abuse of what they're intended for (That is, SO's are kind of meant to just hold persistent, usually constant data or logic that can be reused). If you took this approach to many things in a project, I just don't see how the amount of global state being managed wouldn't get out of hand.
    Some of these problems are solved by instantiating SO's at run time, as some people here have suggested. However, doing so you are then losing the core benefit of using the SO's in the first place, which is the ease of changing values.
    Just an observation on this method overall, super well made explanation and video nonetheless