Rethink Everything with Scriptable Object VARIABLES

Поділитися
Вставка
  • Опубліковано 5 бер 2022
  • Richard Fine and Ryan Hipple really paved the way with their Unite talks in how you can use Scriptable Objects to completely transform your project.
    Introducing the Scriptable Object Variable you can make in your Unity Asset folder. This approach blew people's minds back in the day, and it still acts as an incredibly powerful tool to decouple your code and remove unnecessary dependencies. There is a bit of a learning curve though, so its not recommended to get too deep into this without being somewhat experienced with Unity.
    Also, this approach favors teams who favor a workflow that heavily relies on the Unity inspector (like a team of game designers), and its worth mentioning it may be more overhead than its worth for your game, but its nonetheless valuable to rethink your architecture approach.
    ~Links discussed in the video~
    ➤Richard Fine Talk 2016: • Unite 2016 - Overthrow...
    ➤Ryan Hipple Talk 2017: • Unite Austin 2017 - Ga...
    ➤FREE Unity Asset for Scriptable Object Architecture: assetstore.unity.com/packages...
    ✨Want to support the channel?
    Buy me a coffee ☕: ko-fi.com/bmoli
    Make sure to SUBSCRIBE for the followup to this series of learning valuable skills to decouple your code.
    ➤LIKE the video if you enjoyed, it really helps the channel!
    ➤Join our DISCORD SERVER: / discord
    We have channels to help you with your problems!
    Thanks for watching!
    #bmo #unity #tutorial

КОМЕНТАРІ • 89

  • @oOAjjOo
    @oOAjjOo 2 роки тому +37

    This is helping me understand the value of scriptable objects. When my games get more complex I get so frustrated because one missing piece can stop the entire game from working. You end up spending hours just to realise you didnt put an "s" in the right place, lol.

    • @BMoDev
      @BMoDev  2 роки тому +8

      Haha, yup - the better you get at programming the more you realize how important code design is

  • @marc8150
    @marc8150 Місяць тому +2

    Great summary of the Scriptable Object Talk from the Unite Austin!!!!

  • @MercenarySed
    @MercenarySed Рік тому +12

    A game changer in game development for me was learning design patterns. Try the observer pattern in this situation. Trust me. Good luck!

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

    9:40 maybe someone already suggested it, but you could use operator overloading to still be able to call operations on the variable without referencing its value directly

  • @VoonNBuddies
    @VoonNBuddies Рік тому +38

    I think it would have been nice to expand on Hipple's initial talk. Your presentational style is great and easy to follow! But there honestly isn't any information here that isn't present in the first talk. And that was 6 years ago. There are questions that this pattern raises: How do you handle multiple values? If there are more than one characters with health values, how do you handle that? How do you handle Scriptable Objects' data persistence when editing? How do you track down unused variables? It would have been nice to explore some of these questions or at the very least give an example of another use case besides the one that Hipple already gave. The quality of this video is high but at the end I'm left wondering, why make this video? I'd honestly rather hear your thoughts and ideas on the pattern than just hearing Hipple's again in your voice.

    • @ParkingLotStudioGames
      @ParkingLotStudioGames Рік тому +5

      same thought, this just slipped to my recommended after watching Ryan's talk and he just repeated exactly what Ryan said and used the exact same examples...

    • @krishnarai4854
      @krishnarai4854 8 місяців тому +2

      @@ParkingLotStudioGames it is good for people like me who is absolute beginner.

    • @trunghieu974
      @trunghieu974 6 місяців тому +2

      totally agree. Nothing new, completely the same as Hipple's talk. There are alot of questions need to solve when we want to use scriptable object to architech our game like your mentions.

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

    Dear Bmo Hipple, these floats will help me from drowning in script. Thanks my man 🤙

  • @64imma
    @64imma 10 днів тому

    Very interesting point. A problem I often have is trying to cram too much into a single script or object. This isn't necessarily an issue now since the games I've made thus far on my own are very small and simple. I know that as I eventually will make larger, more complex games, this will become an issue. I'm trying to get better about making, say, a player object composed of smaller pieces that control different aspects of that game object, rather than one massive script that multiple objects have to reference.

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

    Damn it, this is awesome. Thanks for explaining this so well

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

    A wonderful tutorial. I started unity about 2 years ago as a small hobby, and I did not understand the value of scriptable objects. I watched the lectures on scriptable objects as well, but it did not click with me. This tutorial simplified it a lot, and has opened my eyes to how powerful scriptable objects can be! Bless you.

  • @_Garm_
    @_Garm_ 2 роки тому +6

    I love your teaching style keep up the good work! :D

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

      Appreciate it!

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

    Very Useful stuff ,Please keep them coming

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

      Thanks, ima do my best 🙏

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

    This is the type of content I'm here for!

  • @GordonArber
    @GordonArber Рік тому +8

    Wouldn't you be afraid of all the public variables and not knowing which script was setting it? I feel like this would be hard to debug.

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

      In my case, I use specific scriptable objects for each function. For example I'll make a PlayerDataVariable containing both health, max health, and etc instead of FloatVariable. Calling it makes more sense too like, playerData,Health or playerData.MaxHealth.

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

    What's interesting with this is that these are basically global variables. Like if Unity gave you access to the game loop like other libraries do you'd get the same effect by making global variables outside the loop which would be frowned on by almost everyone. So it's kind of strange it's praised here in Unity which is throwing me for a loop. I clearly see the benefit here in Unity for it, but when you consider they are global variables you'd never do something like that in normal game code to share data because it would get messy fast. My gut tells me event systems passing data around are better for sharing data between systems. More work to setup but in general better than global variables to share data. IDK it's weird thinking about this like that.

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

      I guess the main difference is that you still have to pass them manually to the scripts that want to use them, they are not readily accessible from every part of the code, unless you load them from resources. Their main appeal for me is having a single place where the designer can look up and edit the variables I want him to be able to edit, and storing values that are used by the world UI so that I don't need to have it reference objects in whole other places in the scene hierarchy. These look like good tradeoffs for having something akin to global state, although I don't know how well this design would scale in a large project. I still try to pass around everything else using object references and events.

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

    thank you, you've opened my eyes

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

    Rethinking the process of rethinking
    Another solid video BMo.

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

    thank you. This has seriously helped me. immediate sub'd !!!

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

    This changes everything

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

    Cool, it's the same with the conference talk, but it cut short for me to revise.

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

    Thank you

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

    This is super neat, I'm curious how this would work but in a multiplayer setting? or with multiple enemies, would they all have the same health if you use the same scriptable object, where you'd need to create specific Scriptable objects(being the health variables) for each player/enemy?

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

      Correct don’t reference the same scriptable object instance for multiple game objects who wishes to be different. You’d have to create a new hp SO instance for per enemy so not optimal to use for in that case.

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

    Very good tutorials...

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

    I feel like this is against best practices for maintaining clean data states. Mutable data inside a scriptable object persists between editor sessions and isn't cleanly initialised to defaults. You would have to build that initialisation into the monobehaviour which uses it. It also breaks data ownership contracts in classes. For this simple use case it's probably not an issue, but if you're using it for more complex data like lists of objects, you could run into some quite annoying bugs.

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

    I am just watching your video to see if I can learn something more about Scriptable Objects, and saddly for me I learned this 5:45 the bad way, I ended up making a bullet pool in them and I had to work around that
    Either way the Scriptable objects were incredibly useful to allow many of my game's enemies to have a shared common value that affects all of them sorta like an inspector static value, that holds their death audio files, and the color they turn on whenever they are damaged (some enemies are red so that meant the damage color had to be green)

  • @jacobs.7925
    @jacobs.7925 Рік тому

    is it possible to change all those SOs during runtime? there must be some downside for using them. I remember fiddling with it a bit - some things that worked inside the editor wouldn't work inside the real game once the build was compiled.

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

    Still learning Unity so forgive me if this question is obvious, but what are the advantages of using these VariableSO's vs just using native C# event system to decouple these objects?

    • @chrisflynn5192
      @chrisflynn5192 Рік тому +3

      Different design patterns. Both have their pros and cons but can both do the job of decoupling really well. It actually works very well to use them in tandem

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

    Good stuff. I've used a similare way for events in my game to avoid a middle man singleton in the scene.

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

    Me: "oh! I get it!"
    Also me: proceeds to destroy entire project.

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

    Isn’t this just a fancy way of creating a global public variable? What benefit does this have over a static class which holds the same information?

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

      For one, you don't have to maintain that variable in code - anyone, you, a game designer, an artist, can all make and utilize a variable in your components without the need of writing any code (assuming you design your components to accept them).

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

    ty

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

    What if you incorporated events into this?

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

    Wow, that's cool! O_O I got confused with the coding around 8:30 since I'm not familiar with getters, let alone using ?'s in my code. lol. But I'll definitely watch those videos you recommended. :)

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

      The question mark referenced here is the ternary operator, or conditional operator. It's basically an if else statement, except it returns a value.
      In this case, it's being used in a getter and being returned right away, but you may see it assigned to a variable like var result = condition ? valueIfTrue : valueIfFalse;
      A getter is basically a hidden method associated with a property. When he calls .Value, he's invoking the Value property's get functionality. It's the same as if you made a method called Value() that returned the constant or variable value.
      You can Google C# get accessors and C# ternary operators for the Microsoft Documentation which should be the first result.

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

      @@JTux_ Thanks a lot! :) Ok, so the ? is basically a shorthand if/then statement. It's probably because I'm still new but I would much prefer it being spelled out. It's just easier to read and understand.
      From my understanding, getters and setters are for variables you have to make public (like a singleton) but don't want anyone to fiddle with its values. So it's a "read-only" variable.

    • @JTux_
      @JTux_ 2 роки тому +6

      ​@@suicune2001 Sort of, I'd say that's an okay understanding for a beginner. Generally a property has 3 parts, a "backing field" (the private field), a getter, and a setter. The setter is invoked when you say Property = ____; and a getter is accessed when you say _____ = Property;. The backing field is just hidden behind the scenes, but with no setter you're just using that read only variable, yes.
      The if/else spelled out definitely makes sense. It's one of those things that can definitely help make code smaller/easier to parse at a glance once you understand the syntax. Consider the following:
      private string GetCanVote(int age) {
      if (age >= 18) {
      return "You can vote!";
      } else {
      return "You cannot vote.";
      }
      }
      While it's a simple example, this method takes an integer as a parameter and then decides if it's over 18 or not, and returns a string that can be returned to the user. This could be simplified to something like:
      private string GetCanVote(int age) {
      return age >= 18 ? "You can vote" : "You cannot vote.";
      }
      Alternatively, you could also create a field called age, a property called CanVote, and a property called Message like so:
      public int age;
      public bool CanVote {
      get { return age >= 18; }
      }
      public bool Message {
      get { return CanVote ? "You can vote!" : "You cannot vote."; }
      }
      While there are better ways to accomplish this, there are two properties and a field (age is a field because it doesn't have a getter or a setter) that demonstrate both the ternary (?:) and the getters.
      Some of this is not as applicable with basic Unity and plays a more common role in C# development in general, but I hope this helps. I probably went way overboard, but hey it's fun.

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

      @@JTux_ Not at all! It was great. :) It helps me a lot to see how the code can look different but do the same thing. Thanks a lot!

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

    This works perfectly for monobehavior scripts but I can't seem to get access to the scriptable object inside of a namespace. What am I doing wrong?

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

    This is great and super helpful but doesn't it end up scaling poorly for larger projects because they all need to drag and drop this variable via inspector? Does anyone have any examples of injecting this automatically?

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

      As I understand, drag and drop via inspector is a designer-friendly way making a game.

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

    can you do an example with enums as scriptableobject please?

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

    great video, very informative thank you for the information!!

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

    Can anyone help me? At 6:40 he creates a float variable in his assets folder. When I right click in my assets and go to the create menu, I don't have the option to create a float variable. Has this option been moved or renamed or what??

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

      His float variable is a custom scriptableObject he named FloatVariable you have to write. So that’s not going to be available for you without first writing it. Then To make it available when you right click, all scriptable objects files must declare a special line above the class something like [createMenuAsset…] which you can look up.

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

    What would you suggest for a person trying to get into the field? Do they need to go to a 4 year university or is the environment so advanced that its hard to get into? Amazing video btw.

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

      short answer no, you dont need Uni .You only need passion and grit to get in to this field.. but its far from easy. Uni will give you a good and solid foundation and more or less give you a foot in to the market.

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

      If you got the skills and passion just build a personal portfolio around various projects showcasing your skills and you can skip university. Keep in mind the Game industry is vast. Pick your poison and concentrate your skills into a clear focus vs trying to do everything. You could do everything but they all better be strong and well balance otherwise focus on a central skill and showcase that instead in your resume and interviews.

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

    how can you group the values in the inspector? (sorry for the off-topic, I always feel the Inspector very limited)

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

      ahh, it is the ScriptableObject itself ...

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

      ​@halivudestevez2 Not sure if this helps, but I just learned recently that there's a Header property similar to [SerializeField] that lets you create named groups for your variables in the Unity editor, pretty handy if one script has a lot of public or serialized vars. You just pass it a string like so: [Header("name of the section")]

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

    Wouldn't it be better to do this via events? Player takes damage and announces it. Everything that needs to know about the change then does something based on it.

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

    Is this available on Steam?

    • @TeurastajaNexus
      @TeurastajaNexus 4 дні тому

      What? :D

    • @weckar
      @weckar 4 дні тому

      @@TeurastajaNexus it's a baby ago I don't remember

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

    I think scriptableObject variables is an anti-pattern in most situations except for something singleton like single charactor or single stat, in a more common situation, such as multiply units and enemies, it's not extensiable and add unnecessary complexity

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

      I do agree, but I also think making this for single value is overkill to my liking. While this is great for non-coders, I don't think it is worth in single developer projects. Though I do believe scriptableobjects can achieve same feats without these complexities, which I still try to understand and discover. I'd like to think them as "multiscene singletons" and still try to figure out a better way of handling all of this.

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

      Learn, experience more, you will see differently.

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

      yup, try it first.

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

    I feel like this is basically like global variables or singletons. Yes they are much fancier and provide means to manage them from the editor but that's what they boil down to. I'm struggling to understand whether this is good or not. Usually globals and singletons are considered bad practice as they run into a lot of issues. How is this any different?

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

      my main takeaway is its pretty much singletons without the need for a gameobject in the scene for the singleton to live on. TBH i think event system is still a more robust way to handle decoupled passing of data. But this is a very easy beginner friendly way to do it, and being inspector based makes it good for non-savy designers and artists to do things without having to poke around in code.

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

    There are much more powerful techniques than this one in Unity , but sure better than Monobehaviours

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

    What I don't understand is, what is the need for the FloatReference? Why can't I just use FloatVariable in the other two scripts?

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

      You can, the value of the FloatReference lets you use the ScriptableObject or just a constant value you can put in the editor, great for testing and debugging and also sometimes you have a case where you just dont need to make another asset for a variable

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

      @@BMoDev Cool. Thanks. I had watched Ryan's video a while ago, but couldn't wrap my head around how to actually implement what he was talking about. This made it easy to understand.

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

    Writing to scriptableobjects is a bad practice tho. It's better to use them readonly

  • @archibaldc.1833
    @archibaldc.1833 Рік тому

    I'm starting to make games and right now I don't really see the value of this, but I'm sure it's only a matter of time before it becomes readily apparent.

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

      7 months ago. you should have seen the light by now, right? hehehe

  • @lambda-snail
    @lambda-snail Рік тому

    I can see using scriptable objects is a powerful way to architect your system! But it also looks a lot like a global variable to me. If I have 10,000 different objects and systems in my project, how do I ensure that only those who should have access to the player's health can actually access it?

    • @monkey7218
      @monkey7218 11 місяців тому +1

      For something to have access to the "player health" you need to go into its class, add an exposed reference to the SO asset, then go back to the inspector and drag that SO asset onto the right field in the Inspector.

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

    This instantly breaks when you have another player, since they reference the same SO. You then have to start to add code to manage that which adds complexity. Plus wrapping simple types like floats in Objects that then also are persitet to the harddrive can't be great for performance. Would not recommnd using this approach.

  • @monkeyrobotsinc.9875
    @monkeyrobotsinc.9875 Рік тому +1

    Yawn

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

    You really should avoid the conditional (ternary) operator due to its lack of readability. The same goes with the arrow notation. Not everything fancy is also good.

    • @BMoDev
      @BMoDev  Рік тому +8

      Bad advice!

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

      @@BMoDev Bad attitude. Ternary operators are considered bad practice by professionals ever since they were invented.

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

      LMAO

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

      lol

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

      There are a great many cases where I think they are easier to read, and some cases where I would agree with you. Most of the time, I find having to explicitly deal with the two states of a variable at the time of its declaration, makes it easier for me to reason about the state it should end up having as I'm reading the code. However, I would say that repeatedly assigning the same variable with the ternary operator within the same variable scope probably gets into some messy territory where it's really just an attempt to hide what should be necessary complexity. The same goes for nesting them, as most of the time the nesting ends up becoming equivalent to some much simpler boolean expression. That said, I don't think their misuse is any reason to write it off the way you have done. It's been around since C and it's clearly not going anywhere.