Scriptable Objects: What are they? How do you use them?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Great explanation! I see so many questions about SO here. Hopefully this will help people. Looking forward to your video on Odin. It's an asset I've been curious about but haven't made the leap to purchasing yet. Thanks!

👍︎︎ 3 👤︎︎ u/alanmthomas 📅︎︎ Dec 18 2019 🗫︎ replies

Never stores non setup functions in scriptables, always used it to store variables or events. Is this something you utilize often?

👍︎︎ 1 👤︎︎ u/Cowsepu 📅︎︎ Dec 18 2019 🗫︎ replies
Captions
scriptable objects if you're not using them in your project you probably should if you are using them there might be even more ways to use them to make your project easier to maintain or make it easier to add features scriptable objects in Odin are a great combination which is what I'll be looking at in the next video so make sure you're subscribed and don't miss that video in this video I'm going to take a look at the basics of scriptable objects how to create them a few examples of how to use them plus some pros and cons for using them in your projects if you want to skip ahead or see something in particular check out the timestamps in the description below a scriptable object is just a script it inherits from Unity engine object just like a mono behavior does but it's not a modded behavior this means they won't receive the most callbacks such as start or update but they can contain variables and functions this also means that they can't be attached to a game object in the same way that a mana behavior or a component can be they are objects but they aren't game objects and they don't have a transform rather they live in your project folders and this is where a lot of their power and usefulness comes from description box allow the separation of design data from runtime data what does that mean let's say you want to add a new enemy to your game if each enemy has their own script then you'll need to create a new script with a lot of the same functionality as other enemies or if you have one large enemy script this can lead to long chains of if statements or a bulky switch statement check and see what type of enemy and then running code specific to that enemy and that's okay unless you want to add two enemies or ten or a hundred it can get out of control in a hurry making debugging hard and testing nearly impossible instead if all the design data for the enemies such as visuals speed damage etc are all contained in a single scriptable object then all that needs to be created for a new enemy is a copy of that scriptable object the values of the fields can then be adjusted for the new enemy that data can then be loaded into a generic enemy object that then reads the data and adjust settings as needed and that can be a real game-changer for how you build and create your games so let's start with a simple example to create a scriptable object simply create a new C sharp script open in visual studio or whatever you're using to edit your code and change its inheritance from mana behavior description below object and that's it you've got a scriptable object but it's not terribly useful instances can be created through code using the command scriptable object create instance and then specify in the type while this has its uses I found that creating a project asset is the more general use case and can offer the most benefits and we can do this by adding the create asset menu attribute at the top of the script this will allow a copy of the scriptable object to be created from the asset menu or by right-clicking in the project folder the file name of the newly created asset as well as where in the asset menu it should show up can be added as arguments to the attribute like so subgroups can also be created by adding a forward slash after a group name like this we can then go into unity and create a copy of our scriptable object with that done it's now time to add some functionality adding some basic fields will create a scriptable object that acts like a data container I'll delete the start and update functions as they won't get called by unity and I won't be needing them for this example I'll then add a field for the enemy name a description for the enemy a game object for the enemy model as well as a few generic stats for each of the enemies and with that done more copies of the scriptable object can be created in unity and the data populated for different enemy types now this is all well and good but the data is just sitting in a project folder we need something to handle the data we need a script that will do something with that data now trying to keep things simple but still showing the usefulness of this pattern I've created an enemy controller script that has a field for the enemy data this will allow the scriptable object to be dropped into the inspector so the data can be used by that script I've also created a load enemy function that gets called from inside the start function this function can do any number of things with the data but in this case I'll delete any and all children and replace them with the instance of the enemy model I'm also going to set the nav agent speed to the speed value in the data scriptable object this approach can allow designers and developers to have one generic enemy prefab and simply load in different scriptable objects with different data and the player will see different enemies I can demonstrate this by creating two empty objects attaching the enemy controller script of both and then dragging in different enemy data scriptable objects when I push play I can see that the visuals for each enemy is different and matches the data in the scriptable object and of course other data can be used to differentiate the behaviors of enemies as well so what this is done is separate all the design data such as the model speed and health from the runtime data or the code that uses that data it also means that all the data for a given enemy is in one place it's not stored in a component that has a copy on each instance of the enemy you change the properties on the scriptable object and then changes for all enemies in the scene and in every scene in your game this is a huge step forward and keeping your code clean and making your project easy to maintain and expand but let's dive a little bit deeper now imagine that you were creating a turn-based game and each enemy in your game has different actions for their turn you could create an enemy manager that loops through all the enemies in the game that's all well and good but if each enemy has its own behavior then the enemy manager might quickly get clogged with a chain of if statements or if you're using an enum you might have a complicated switch statement that calls different code based on different enemy types this gets messy and can quickly become very hard to manage or debug and this is where the key word abstract comes in since scriptable objects are just normal classes we can define an abstract descriptive elect for a base enemy and then all other enemy data scripts can inherit from that base and what does this get us well we can define abstract functions such as do turn this function will be implemented on each and every enemy scriptable object so this function can be called from the enemy manager regardless of what type of enemy is and what type of behavior the enemy may have then each different enemy can define its own version of do turn in a scriptable object by overriding the base function the enemy manager doesn't have to know or care about the enemy's behavior the enemy takes care of its turn all by itself this separation can make your code far easier to debug and it allows the creation of a new enemy type without having to change or modify the enemy manager and once again that's a game changer in how you design and how you create your games we can still go one step further but this time we're gonna go a little bit more abstract and a little bit simpler in my opinion that this next approach can go too far if you use too liberally but in some cases it could be very very useful as we've seen scriptable objects can be very simple data containers these data containers may contain as little as one field for example a color now why would you bother to do this doesn't this just add more files to a project yes it does but it also means that a given chunk of data is stored in just one place so if you want to store a color for your UI and you want to access that color from many different elements or many different scenes then all that needs to be done is to add a reference to the scriptable object and drop it in no more copying hex codes from object to object or scene to scene change the color in one place in your project folders and all your scripts have access to that new value this approach can be made even more versatile using Odin to create a custom inspector this can allow a designer to switch back and forth between using the scriptable object or a typed-in value if you're interested in seeing how to do this with Odin then leave a comment below and we'll add it to our list of video ideas so hopefully those examples have piqued your interest and maybe giving you some ideas of how to use scriptable objects in your projects if you want to dive deeper into scriptable objects there are great videos from unity look at these ideas and more you can find links in the video description below but before we finish let's talk about some pros and cons of scriptable objects so let's start with the pros the scriptable object can be an asset and is accessible by any object in any scene which makes for far easier design workflow it also has the effect of decoupling the data from scripts multiple objects or scripts can access the data and those objects or scripts don't need to be aware of each other at all also because of the way unity serializes data using scriptable objects can reduce the amount of data that needs to be serialized and can speed up the scene load times while you're working in the editor and the last one values don't get reset at runtime so that means if you change the value on a scriptable object and you go out of play mode they don't get changed now talk about the cons or maybe not really cons but just things you should be aware of when using scriptable objects in your scene now I just said that one of the pros is that the values don't get reset at runtime I also think that's kind of one of the cons or one things you need to be aware of I personally like to use scriptable objects for values such as Max or min dives rather than current values for this very reason scriptable objects are unity objects that means that changing the scriptable object can result in loss of data rename a field and poof your data's gone is disappeared Unity's not going to get it back the last one here is not really calm but it is a trap especially for people new to unity scriptable objects can appear like a save solution changes in the scriptural object could easily cause loss of data there are far better save solutions than scriptable objects it's also worth noting that changes made to a scriptable object in a standalone build will not save whereas in the editor they will save and once again this is giving the appearance of a save system and one of the reasons that I tend to use scriptable objects more for max and min values rather than current values so there you go we've talked about scriptable objects and three different ways you can use them in your projects and stay tuned for our next video where we're gonna look at using odin inspector with these scripted objects hopefully that was useful and interesting and until next time happy game design
Info
Channel: Sirenix
Views: 44,416
Rating: undefined out of 5
Keywords: Unity, scriptable objects, game data, devdog, Unity3D, unity scriptable objects, Unity Tools, scriptable object unity
Id: W5ECIJyoW80
Channel Id: undefined
Length: 10min 38sec (638 seconds)
Published: Tue Dec 17 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.