Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Can you pool scriptable objects? You probably can but do you?

Discussion in 'Scripting' started by Aedous, Apr 8, 2017.

  1. Aedous

    Aedous

    Joined:
    Jun 20, 2009
    Posts:
    244
    Hello there!

    I have a general question about scriptable objects, simply put, does any body pool scriptable objects that are Instantiated at runtime?

    The only reason I am asking is because in my head it makes sense that you should be able to do so, but I thought I'd ask the community if anyone is doing something like that.

    To give you a breakdown of what I'm doing, it's very similar to the Ability System tutorial, which uses scriptable objects as it's core to create mutliple types of bullets a gun can fire out of a mixture of scriptable objects.
    I'm using scriptable objects to carry out certain functionality for a character for example listen to events that a character may fire, or modify the stats (things like HP / Damage / Stamina) that the character has.
    I instantiate a lot of these scriptable objects to make them unique to the Component that may be using it, for example with Items.
    At the moment I'm moving on to make it more extendable to other parts to stop me from repeating myself, but then I noticed that I may be instantiating quite a lot of these scriptable objects and not sure on what the performance cost will be when doing something like through out a couple of hours of gameplay.

    Has anyone composed a system or has an idea of how to handle a pooling system for scriptable objects?

    If you'd like some more details as to what I'm actually doing I've made a post about it over here if you're interested!
     
  2. Zaddo67

    Zaddo67

    Joined:
    Aug 14, 2012
    Posts:
    489
    I would certainly pool the scriptable objects. Obviously, this will be far more efficient than creating/destroying them all the time.

    I use pooling extensively. It wouldn't be hard to write your own pooling manager. I personally use PoolManager by pathological games. It is very good.

    I haven't checked it out. But from memory I am reasonably sure that with PoolManager you can pool objects you create in code. (I typically use it with Prefabs)
     
  3. Aedous

    Aedous

    Joined:
    Jun 20, 2009
    Posts:
    244
    Thanks for that, I ended up trying to learn to make my own just so I had more control over it and looked around to find some examples to go from. I've noticed that most of the pooling managers that are available specifically use prefabs and not scriptable objects, did some more digging and found some topics of someone trying to do it, so at least I know that it's not a waste of time to attempt as well :D

    https://forum-old.unity3d.com/threads/pooling-scriptableobjects.329813/

    Hopefully I can figure something out!
     
  4. Zaddo67

    Zaddo67

    Joined:
    Aug 14, 2012
    Posts:
    489
  5. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    I can't say I've ever Instantiate a scriptable object at runtime. As I tend not to Instantiate them, there tends not to be a reason to pool them.

    For me the reason for a scriptable object to exist is to have access to the inspector for something that is not a scene object. At runtime you don't have an inspector. So I struggle to see what advantage they offer over vanilla C# classes.

    I might be missing something here.
     
  6. Aedous

    Aedous

    Joined:
    Jun 20, 2009
    Posts:
    244
    Ah cool thanks for those, RecyclerKit more straight forward I should be able to convert it to some sort of Scriptable Object version.

    I'm not sure if it's the best way to achieve what I wanted to do, but I wanted to be able to compose a bunch of objects together to create a new a brand new object, similar to those on this video Ability System.
    I first tried it with the Items in the game which are randomly generated, and the only way I could think of storing a unique set of items, with different stats, was to create an instance of the original in game every time it was dropped from an enemy.

    Mostly because the modifiers ( which are also scriptable objects.. lol) that go into an item can be anything that changes the players stats, or grants them an armour piece, or sets a debuff on them. These modifiers are also instantiated per item, this was just because I couldn't figure out a way to make them always unique especially with modifiers hooking onto events on the character. So the best way I could think of doing it was create one at run time.

    Watching this guy as well also made me think maybe it's not so bad haha. Overthrowing the Monobehaviour Tyranny.

    Now I'm literally thinking that I need to somehow pool these scriptable objects as using Instantiate all the time can't really be a good thing :confused:
     
  7. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Pooling ScriptableObjects doesn't make any sense to me, in my head. A ScriptableObject, to me, is an easily accessible class instance. If I make one, I don't make more than 1 (copy)? If that makes sense. They're useful for data only situations, and because they aren't duplicated.. that is part of the point (at least how i see it), to use a SO.
     
    Kiwasi likes this.
  8. Aedous

    Aedous

    Joined:
    Jun 20, 2009
    Posts:
    244
    Not for the way I'm using them, like I understand that normally you just make 1 copy of the scriptable object and you should be good. But lets say I have a scriptable object with the attributes of the character:
    Health - 100
    Stamina - 50
    Damage - 20 - 30
    This scriptable object doesn't just store the data but also stores the current amount in game as well, and in order to keep it unique you'll instantiate it at run time so that your original copy doesn't get overwritten with in game data.
    So for each character that you have in game that uses this scriptable object as their attributes, they all need to have a unique copy as soon as they are loaded in game.

    I'm guessing that maybe if you used it just as data and then used a separate script that just copies the data from scriptable object onto it self then you don't have to instantiate it but just copy the values over from Awake, Start and you're good to go, but that just simply means that you have 2 places to add attributes. So if I was to add another attribute like "Flinch" I would have to add it in the scriptable object and then add it in the script that copies the data, rather than just adding it in one place. Do you have any other suggestions of how you would do it?
     
  9. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Well, I kinda maybe see what you're saying. I've never put a lot of thought into considering that approach. My usual thoughts are to use the SOs for base values and/or non-changing stats. Values that I can reference, but may or may not even need to store (beyond that reference).
    I can get your view about pooling them, maybe, in the case you mentioned.. just not something normal to me :)
    To each their own.. many different ways to play/code/etc ;)
     
  10. Aedous

    Aedous

    Joined:
    Jun 20, 2009
    Posts:
    244
    Ah cools, was thinking that I may have just been doing the whole thing wrong haha! Had me worried there for a second :D
     
  11. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    just different. :)
     
    Aedous likes this.
  12. Aedous

    Aedous

    Joined:
    Jun 20, 2009
    Posts:
    244
    Hey @superpig sorry to bother you, but it's really only because of those videos you made the first person I thought of was you haha, but what are your views on what I'm doing? It's simply making scriptable objects with more than just data but something that has functions in there and listens to events from the component it's attached to etc?

    For example a character's attributes that an enemy get's from a single scriptable object GoblinAttributes ( HP / Stamina / Damage ), but then when in game it creates a copy of GoblingAttributes for itself, and uses it as it's own unique attribute that will be listening to any messages that can be passed down from the character.

    Your input will be greatly appreciated :D
     
  13. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,614
    So, to answer the initial question: yes, you can indeed pool ScriptableObjects.

    For your specific use case - in particular:
    Why do you want to use SOs for this rather than just using a Goblin prefab?
     
  14. Aedous

    Aedous

    Joined:
    Jun 20, 2009
    Posts:
    244
    Ah nice! I figured you could just glad to hear it from a Unity Developer.

    Just to have a global data point for all the attributes for the different enemy types, so if I wanted to change any attributes to balance the game a bit, I only have to change it in that one place, I've also had problems with prefabs where some values of an instance on the scene that has been changed doesn't get the settings of the prefab. Scriptable objects just made the work flow a lot less painful haha!

    I wanted more than just data storage though, and used them to build the item system in the game, so I can have a sort of Unity Database of scriptable objects for different types of things in the game, and because the stats on the items are randomly generated each new item that dropped had to be unique in order to not overwrite the original base item, so ended up Instantiating a new scriptable object every time the game requests an item.
    Then expanded it and use it for other things, and starting getting into the habit of instantiating them..

    ..That's pretty much when I started thinking that I probably need to pool these things! but I'm glad that it's possible :D.
     
    superpig likes this.
  15. dylanfries

    dylanfries

    Joined:
    Jul 11, 2012
    Posts:
    16
    I found this tutorial really useful for anyone that is looking at this thread. It doesn't use ScriptableObjects but you could certainly adapt it to do so. I just changed this to a ScriptableObject and it runs as is.


    I have further questions though. Should I be clearing the Queue when the scene ends? Also, it "seems" to work, is there any reason why keeping an Object Pool in a ScriptableObject would cause issues?

    Thanks in advance!
     
  16. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    No, but I also can't think of any good reason to make poolable objects extend ScriptableObject either. Poolable objects are, sort of by definition, instantiated at runtime, and all of the advantages of ScriptableObject have to do with them being created at Edit or Design time.