SCRIPTABLE OBJECTS in Unity


Often while making a game, you need a good way of storing data Say if you’re making an RPG You need to make a whole bunch of items each with their own stats and properties Of course you could create an item prefab and then make copies of it with different values, but this is both prone to error and very inconvenient. So instead we use scriptable objects ♫ [Heavenly Choir] ♫ Scriptable objects are basically just data containers First, you create a template that defines what information each object should hold and then you create objects from that template. So in this video we’ll learn how to use scriptable objects by looking at the example: creating cards for Hearthstone. Alright Let’s go. So here’s a simple scene with an empty card. If we have a look at it in the hierarchy, we can see that I have all of these different UI elements. I have a text object for the name, description, mana, attack and health As well as an image for an artwork And I’ve made sure to mask it out so it fits the card Let’s now create a scriptable object that contains all of this information. To do that, we go to the project ->right click Create, C# script and let’s call it “Card”. Let’s now click to open it Now we want to delete both our methods and this time we don’t want to derive from MonoBehaviour Because this script is not gonna be sitting on another object It’s more going to act as a template for all of the data that we want to store. To do that we want to derive from ScriptableObject. And now we’re ready to define what values we want these objects to store And this is pretty simple: we want a string with the name of our cards, so we’ll call this “name”. We also want a string with the description of our card, we’ll call that “description”. Now we also wanna be able to define the artwork for our card So this is going to be some kind of image So we create a public sprite And we’ll call it “artwork”. And then finally we need the game-play stuff So we need a public int with the mana cost, a public int for the attack value and a public int for the health and here we have all information that each card will contain. Notice how we have a green line under the “name” That’s because by default any object has a variable called “name”. So we can either rename this to say “cardName” or we can just tell the object to use this definition of name from here on out To do that, we write “public new” string. And now every time we write “card.name”, this is what it’ll use So if we’re now save this and go into unity Not much will happen here. You’ll notice that I don’t have any cards in the project. If I select this script it just shows the script here and for some reason we have a field for the artwork here, but none of the other stuff. Remember, this script is only the template for our cards. So how do we go ahead and create a card from this template? Well that’s exactly what we need to define Unity makes this really easy with an attribute called “CreateAssetMenu”. We need to always put this right above our class This will basically tell Unity to make it possible to create this object through the create asset menu Which means every time you right click in the project and go Create. So we’re basically now adding a new object To this list. Now we need to define a few things here. Set default file name to something like ‘New Card’. As well as the “menuName” to something like “Card” And if you have multiple cards you can create a submenu by going “Cards” and then “/” and then you can have all the specific cards in here But we only have one so we’ll stick to Card. If we now save this and go to Unity (wait for the editor to compile here) and if we then right click go create, you can now see that there’s indeed a card here If we press it, it’s going to create an object. By default it says “New Card”. Let’s call this one “Edwin” Then at the top here we can set the name to “Edwin” We can create a description: “the baddest guy in town” Select some artwork I’m gonna open up here. I’ve already imported a sprite that we can use Set the Mana Cost, I’m gonna set that to 3, and attack value And the health value. So here we go. We’ve now created an object that is as simple as can be All it does: it stores information about a given card. And we can go ahead And create as many as these as we want. We can right click again. Go Create, “Card”. This time we can create Tirion. His name is going to be “Tirion”, his description is going to be: “His light shall burn you!” We can select some artwork. A Mana Cost, let’s set that to 6, an attack value, and some health so now we’ve defined these two cards. But currently they’re just sitting inside of the editor. We need some way of putting these cards Into the game. In other words we need to display them on the UI I’ve created here To do that we need another script. So let’s select our card Add Component, and let’s call this one “CardDisplay”. Let’s again select C# and hit create and add.
Let’s open up Visual Studio. This time we want to delete our update method But let’s leave our start method in here, because it’s at the start of the game that we want to setup our card But in order to do this, we first need a reference to the scriptable object That we want to display. To do that, we’ll simply create a “public” “Card”. And we’ll call it “card” with a non-capital “c”. And it’s actually that easy. Now inside of Unity we get this empty field where we can take any of our two scriptable objects. I’m gonna take Edwin here and drag him in. And now inside of our script we can access all of the data that we stored inside of this object So if we want it, we can just print out the name of the card By going “card.name”. If we now save this and play the game, it’s going to show “Edwin” in the console. So that’s really cool. In fact we can also add symbol methods to our scriptable objects. We can go in here and create a public void called “Print” And this method will simply show some of the card information in the console. So we’ll throw a Debug.Log And here we’ll print the name of the card, followed by a description. So, a description on the card And then we can print, say, the mana cost, so we’ll go The card costs and then the “manaCost”. So if we save that and go into CardDisplay, we can simply call “call.Print();” And if we save this and hit play It’s going to print: “Edwin, the baddest guy in town. The card costs 3.” Awesome! But we can do better Instead of just showing this stuff in the console Let’s show it on the UI To do that, instead of printing the card to the console, let’s go and reference all of our UI elements To do that, we need to be using “UnityEngine.UI;” and now we can create a public Text This is going to be our “nameText” We’ll also create a public Text “descriptionText” then we need a public Image this is going to be our artwork image And then a public Text manaText public Text attackText And you guessed it, a healthText. Then in Unity we’ll setup these references So we’ll put name into the nameText slot Then description, then the artwork image is under here, so there’s an artwork image the manaText, the attackText and the healthText. And now in the start method, we can simply set nameText.text equals to “card.name;” and descriptionText.text=card.description; we can really just continue this way for the artwork image We need to make sure to access the sprite And set it equal to card.artwork. And for the manaText we’ll go manaText.text equals card.manaCost. But we remember that manaCost is a number, it’s an integer, so we need to convert this to a string. To do that, we simply call .toString(); And we do the same thing for the attack and health. ♫ [Music Break] ♫ And there we go! That should be all of the code that we need. If we now save this and try and play the game. We can see all of our UI elements get updated to show Edwin’s information. And we can input any scriptable object here If you want to show Tirion instead, we simply drag in Tirion and hit play, and there we go! Our card is now Tirion. In fact, we can easily copy this card and place them side by side, let’s make one of them Tirion and the other one Edwin. When we now play the game We can see our two cards. And right now we’re just doing This in the start method. You can easily update this while the game is running. Because we’re just swapping out simple information. And each of these scriptable objects are extremely small. You can see both Edwin and Tirion is only 1 Kb. So yea, scriptable objects are super cool. That’s pretty much it for this video. If you enjoyed it, make sure to subscribe, so you don’t miss the next one. I hope you guys had a Happy New Years, and I’m looking forward to an awesome 2018 With plenty of game dev goodness! On that, thanks for watching! And I will see you in the next video. Thanks to all of the awesome Patreon supporters who donated in December and a special thanks to: @Youdaman, Armin Noroozi, Yorai Omer, beffio, UnnecessaryRoughness, InfinityPBR, Cyborgmummy Cole Cabral, Dan Evans, John Beauregard, SupermanTheG8, James P, Jason Lotito, Derric Heemskerk, Fasal Marafie, Erasmus, Rob Fearn James Rodgers Alex Rakitsky, Manolis and Robert Bund

100 thoughts on “SCRIPTABLE OBJECTS in Unity

  1. Why don't more developers use string interpolation when it's available
    For instance:
    Debug.Log($"{name}: {description} The card costs: {manaCost}");

  2. Been looking at a lot of camera tutorials for Unity, this is so far the best by far. You explain things well, and the camera mechanics are more advanced and better coded.

  3. Nicely Done! i love learning from you. you motivate me, I was going to shift to web due to recession in game dev field in my country but i am staying because of you. Because i know game dev is Awesome!!!!

  4. Thank you so much. I have been trying to learn about SerializableObjects for a few days now and this is the best thing ever! Clear and concise. Thank you!

  5. I cannot use this tutorial with Unity 2018.2.17f1 (64-bit), see the issue: https://forum.unity.com/threads/scriptableobject-image-and-sprite.589255/

  6. I'm making a Tycoon game, about making games… like video game tycoon… I think I should use that scriptable object for the player's games. How would I make it so they can make scriptable objects and change the variables? Any response helps,
    _RED

  7. I just came from a 1 hour video in the unity site knowing less about scriptable objects than what I originally knew, but you really make stuff easy to understand, can you make a video about state machines?

  8. Yeah… Thank you very much for the information. It looks like everyone talking about Scriptable Objects take the "lazy" approach of plugging the reference for the object assets manually directly in the inspector. What about if the card is created at run-time and you don't have the possibility to drag and drop that asset in? Can you reference an Scriptable Object from the assets folder (without using the Resources.Load, since Unity discourages its use)?

  9. I implemented this in my project and it works in the editor but when I build it to my android phone it doesn't work. What is going wrong?

  10. I used to create arrays/lists that were part of scene, but looking at how often unity crashes, I am definitely going for scriptable Objetcs. Thanks Brackeys.

  11. I regret no learning about Scriptable Objects before… instead I used Singletons… 🙁
    Time to change that!
    Q: How do I [SerializeField] its data?!

  12. A bit late to the party here, but awesome video!
    Really great information here for a beginner!
    I've been subscribed for about 2 weeks now, and I've been going through all the old content. I've learned so much already!

  13. One very newbie question – how prone to error and inconvenient it is to do things the prefab way NOW when we have nested prefabs and new prefab workflows? What would be the advantage of using scriptable objects at this point?

  14. I was thinking on how to do enemies for a rpg, and remembered this video. Seems to be working perfectly, so thanks!

  15. Yeah yeah yeah. It’s just a bloody class like in any other programming language. They should have just called it class to eliminate the confusion.

  16. I've wondered about this.
    What if you want a lot of enemies. Each with their own size, scale, weight, model and animations.
    Would you just store that in a scriptable object and then on an empty game object, just have a script using this scriptable object and applying the model, animation and other stats to the enemy?

  17. I'm so sorry if I'm asking some stupid question) How can we apply one "window/player panel" for different cards/characters? Because if we create a new character during the game, we cannot create a new UI panel with all links between script and UI elements. Or should we make them private?

  18. how can I identify a private object?

    for example, in the scene there is a cube, and I want to make a reference of it:

    ————————————————– —————————-

    private GameObject Cube;

    void Start {

            Cube = GameObject ("cube"); <- ???

    }

    void ButtonPressed () {

            Cube.SetActive (false);

    }

  19. god dammit, you again, whenever I type [do whatever] unity, I get one of your videos.
    not that I'm complaining, they are well made and answer what I want.

  20. Hey,
    I advise you to open a book about photography and read the paragraph about focal lengths for portaits.

  21. Question: Im creating a quiz game and im planning on making questions by making them into scriptable objects. Would that be ok? If i had 1000 questions, that means Unity would have to load 1000 objects into the game. Would that encounter possible problems?

    PLEASE SOMEONE ANSWER

  22. I wonder how this is affected by the new ECS scripting system.
    And how well would it be to use structs in scriptable objects when making new guns and such?

  23. Whenever I need help with anything unity-related, it turns out Brackeys already did that specific thing. Thanks Brackeys!

  24. Thank you so much amazing content. But i cant quite understand the part that he added Text and Image and Sprıte to end of variables. Can anyone explain it to me ? Why does he adds Text or etc to end of it?

  25. What do we do if we want to add a field to our scriptableobject that is a 2d array? Since you can't instantiate it in code (as far as I understand?) and 2d arrays don't show up in the inspector natively.

  26. So how can you retrieve these GameObjects without them being in the scene, more specifically, if you want to create an array/list of a certain type via another script? Can't really wrap my head around that one, and I don't feel like this is very useful without knowing how to do that. Drag and drop is not going to work in the long run.

  27. you gave value to Edwin [3:37], by manually not run time. Is it possible to give value to the SCRIPTABLE OBJECT by code in the run time? for example by reading xml data. we read data from XML and give them to the SCRIPTABLE OBJECT.

  28. search for "unity scriptable objects" see brackeys had made a video about it, so naturally I immediately press it, pause it, like it, make some popcorn and hit play

  29. How to save sprite from scriptableobject to serialize json
    In mine it show instanceID and resulting type mismatch when loaded. Pls send help

  30. Would be cool if he expanded upon this and showed us how to add cards to a deck and then once you purchase the deck with ingame currency or real money you click it and it randomly picks 3 cards based on rng….

  31. I'm confused. What's the point of doing this? Why inherit form scriptable object when you can just not inherit from anything? I just found out about this thing's existence but so far I'd just been making the classes not inherit from anything and setting them in code. So I'd just have a card class, not inheriting from anything and instead I'd have the CardDisplay class be a static class (probably called CardDisplayer) which has functions that take in a card and a canvas then go and set everything in the canvas up according to the information on the card and draw it.

    The only difference I see is that I cannot make instances of the class in the unity editor unless I use scriptable objects but I never plan on doing that any ways because all my classes are for things that automatically generate. Like a room class or an item class. I'm never going to add an item into the editor by hand

    Should I switch to this or keep doing what I was doing?

  32. I am not sure if the method here was for illustration purposes only or is an ideal use case. I am beginner to Unity btw and have seen some of your guides already, this one however confuses me because when I used the ScriptableObject and assign it to a GameObject (ex: your card), and I plan to make multiple versions of it, anything that affects one will affect all instances of the cards using that ScriptableObject. so how I see it is that its one instance being referenced by several UI cards. in that case, how would we use it if we are to generate a deck of cards which may contain any number of "Tirion" and "Edwin" :s and when an effect on either does not affect all instances in that deck? is this still a job for ScriptableObjcts or do I need to go code level and just instantiate in a card array?

  33. Ok I struggle a lot to understand programming concepts. Why not just make 1 "card" script with public members the way you did here and add the card script component to each duplicate of a card you're going to make anyway and change the info in the inspector? This method seems like you're creating duplicate scripts (2 of the same script) for each card.

  34. is it useful for another game objects ? for example bridges that always plays the same animation ? or some any object which need to be repeatable actions ? thx.

  35. yay
    Importer

    UnityEngine.Debug:Log(Object)

    Machine_Variables:Start() (at Assets/Scripts/Machine_Variables.cs:11)
    lol, thankyou.. seems like you always save the day.. lol.. do you have any videos on grid snapping in game and moving a prefab from a ScriptableObject to the mouse via buttons??

  36. Still i had no situation were i just need to change some values, commonly or i have one object, or i have multiple similar objects each of which must do different things in terms of mechanics, i mean in scriptable objects you can't change code of some function from object to object, for example, i have main class Spell, inherited from monobehaviour, it's have method "cast", i can't make it scriptable object and vary content of method from spell to spell, instead of this, i'm creating abstract Spell : Monobehaviour and just creating more classes inherited from Spell like Spell_Fireball, Spell_Teleport e.t.c., and in each of them i'm adding unique logic

  37. How can I see the right size of the card and how 2 make the basic card .like make a square card with the image place.thx for your videos

  38. Any idea why I cannot drag the text objects from the hierarchy into the inspector card displays script boxes on the right just like you did in the 2nd half of the tutorial? I am using TMPrp text boxes and they are attached to a card object in the Hierarchy just like you have in the beginning.

  39. I figured it out. This will not work with a TMPro text box. Maybe you could update with another video using TMPro text box?

Leave a Reply

Your email address will not be published. Required fields are marked *