Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
37
Question by CHPedersen · Nov 30, 2011 at 09:46 AM · scriptableobjectmemory managementoop

What is the purpose of ScriptableObject versus normal class?

Hey all,

This should be a pretty simple question. :) I think the documentation is pretty vague on this point, and only states that ScriptableObjects can be used when you *"want to create objects that don't need to be attached to game objects."*

Okay, so far so good. But how exactly does that make a ScriptableObject any different from any other class I define, and then instantiate objects of with the new keyword? Those are also pretty much "objects that don't need to be attached to game objects".

I understand that with ScriptableObject, I get access to inherited methods such as UnityEngine.Object's Destroy and DestroyImmediate, but what exactly do I gain from Destroy()'ing something as opposed to just setting its reference to null, and then letting the GC clean it up?

I've been defining and using lots and lots of my own classes and creating instances of them with the new-keyword all along, like any other programmer who's been trained outside Unity. But when I create a class, should I actually be inheriting from ScriptableObject all the time, and should I always be using Destroy when I want to release memory? I get this cold feeling running down my back that there's something here that it's seriously about time I understand right. >_<

Can anyone describe some examples where you've used ScriptableObject, and explain to what end?

Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image cj_coimbra · Nov 30, 2011 at 11:20 AM 3
Share

"I get this cold feeling running down my back that there's something here that it's seriously about time I understand right."

I have this same feeling but I just use my regular classes without inheriting from ScriptableObject when I see fit so I don´t get bad (if it is a bad habit) habits from using Unity. Regular program$$anonymous$$g is still out there and I find some concepts confusing when program$$anonymous$$g in Unity C#.

avatar image slippdouglas · May 06, 2014 at 09:46 PM 2
Share
  • for sass in response to Unity's vague documentation.

4 Replies

· Add your reply
  • Sort: 
avatar image
44
Best Answer

Answer by Bunny83 · Nov 30, 2011 at 01:13 PM

Serialization!

Unity uses it's own serialization methods to save and load objects. This serialization methods only supports classes that are derived from UnityEngine.Object.

You may say: "wait Unity can serialize every class with a [System.Serializable] attribute", well that's just partly true. If you have a MonoBehaviour class that has a public variable of your own class, Unity serializes the custom class as part of the MonoBehaviour. Unity doesn't take the true type into account.

If you have a variable of a base class in your MonoBehaviour but you hold an instance of a derived class, the class will be lost / converted into an instance of the base type when serialized / deserialized.

ScriptableObjects are true standalone objects. They are serialized on their own and the MonoBehaviour will just hold the reference to the instance, even when serialized.

If you don't need the serialization feature, use normal classes.

Keep in mind that if you want to use serialization Unity does serialize / deserialize your objects quite often.

Entering playmode: current scene is serialized, saved and immediately deserialized
Leaving playmode: The saved scene is deserialized.

Personally i don't like the ScriptableObject and Unitys serialization. Usually i use either my own way to serialize / save objects or use MonoBehaviours on empty GOs because it makes debugging easier ;).

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image CHPedersen · Nov 30, 2011 at 07:23 PM 2
Share

Thanks a lot for a good answer, @Bunny83! :) I don't use/need the serialization features, though. $$anonymous$$y question was actually more memory-oriented. The one and only time I remember ever seeing Unity's memory consumption actually go down is when objects are disposed of using Destroy. Due to its non-generational nature, I can't remember ever seeing memory returned to the OS by the GC, and as far as I'm concerned, I think that garbage collector is laughably inferior and should be garbage collected itself. ;-) So the main reason I'm asking is actually if there's something to be won, memory-wise, from letting my classes inherit from ScriptableObject, since it seems using Destroy does something else than, say, implementing IDisposable in the .Net way.

I considered attaching $$anonymous$$onoBehaviors to empty GOs too, but refrained from it, because to be honest with you (no offense intended ;-) ), I think that's a little hackish. The fact that GameObjects all have transforms seems to suggest that they should always represent something visual or something that is a 3D entity in some manner. I'm not fond of the notion of abusing that just to get access to $$anonymous$$onoBehavior's callbacks.

avatar image Bunny83 · Dec 01, 2011 at 01:38 AM 2
Share

:) Absolutely, it is hackish :D, but i actually had far too much trouble that Unity can't serialize my normal classes. I've build my nodebased editor completely on $$anonymous$$onoBehaviours and GameObjects. First i thought to attach all classes to one GameObject but in the end it's much easier to handle and to debug when each node is a seperate GO. I can also directly use the transform's position ;)

$$anonymous$$emory wise, well, Unity is written mostly in C++ so every managed (Unity) object have it's counterpart somewhere in the native code. That's why you have to / should use Destroy for those objects. If you have your own pure managed objects it's all handled by the GC.

Until now i didn't care much about memory consumption of Unity. If you want to keep the required memory small, use normal classes. All objects derived from UnityEngine.Object get some overhead (like an InstanceID, Hideflags, ...). I guess not all of them are carried over into the engine since they are only relevant for the editor but it's still something you don't need.

I'm not sure if Unity have problems to free unused memory. I guess it's not that simple because the whole $$anonymous$$ono-environment runs inside another application as some kind of plug-in :D. There are many instances that have to acquire memory from the instance above (If you are on a windows machine that means windows is the top most instance which could be literally the root of the problem :P).

So in conclusion, i don't have any special recommendations how to design your classes Unity-memory-management-friendly ;)

avatar image
28

Answer by timbojones · Jan 21, 2017 at 06:45 AM

Use ScriptableObject to represent shipping static configuration data. Use normal objects to hold runtime data structures like priority queues, R/B trees etc.

For example, if you have many types of enemies in your game, make a ScriptableObject holding health, attack types, AI tuning, etc. If you have a crafting system, make ScriptableObjects to represent resources and recipes.

Populate your GameObject configuration using your ScriptableObjects as configuration containers, instead of exposing public fields across a bunch of different components. Use the [CreateAssetMenu] attribute on your ScriptableObject to add an entry to the Assets | Create menu.

Don't create ScriptableObjects with new. Create and load them using the Asset system.

Now, with a game designer hat on, you can churn out dozens of enemy variations or build a giant economy right in the editor.

With a bizdev or release management hat on, you can do some cool things with AssetBundles to support content patches, DLC, in-app purchases, etc.

The serialization story is actually important and you do use those features all the time: whenever Unity builds the game for you on the way to play mode. As your project grows larger in serialized size, your iteration speed goes down; your launch, load, and download times go up.

If you populate your scene with hundreds of entities that store configuration data with simple data types and Serializable objects, you'll get hundreds of copies of that data in your build. If you populate your scene with hundreds of entities referencing the same ScriptableObject, you'll get exactly one copy of it in your build.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image dugmcdug · Jun 30, 2017 at 07:42 PM 0
Share

This is the correct answer.

avatar image
2

Answer by RElam · Oct 16, 2015 at 09:42 PM

I use ScriptableObject cause Unity's editor really wants me to. If you wanted to reference an asset with a MyMonoBehavior instance on it that's intended to be a shared data set, you can do that, but the editor will not bring up a list of those objects when assigning it, forcing you to manually find it and drag/drop it. So if you had a concept like Material where you would like it to be a shared resource but also a usage unique/animated resource then you have to accept reduced usage quality or the hackey, bug spawning solutions like Renderer.Material/SharedMaterial.

IMO, ScriptableObject is a symptom of a design flaw, and I abhor using it... But I still do for the editor.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by gdbjohnson3 · Mar 01, 2019 at 02:28 AM

Don't try to save references to SO's to a flat file tho (ie: serialize), since Unity doesn't retain the identifiers between builds. Sadly, this really cuts the usefulness of SO's in half, or even less than half. A great enhancement to Unity would be to reserve the internal identifiers for SO's so you can simply serialize references to them. I followed the tutorial about SO's where they claimed you can use SO's like Enums. Everything was great until I realized I need to serialize it, which required me to create my Enum list in C# anyways as a complete duplicate of my SO structure, and also then create a Dictionary lookup of Key to Data values, and create a reference list of them too on a GO. None of that would be needed if Unity just retained these internal id's...

so close... but still so far.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

14 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

creating instances 1 Answer

An OS design issue: File types associated with their appropriate programs 1 Answer

Item data structure - Scriptable Object Inheritance problems 1 Answer

Self contained function override in scriptable object? 0 Answers

How can I display the fields of a ScriptableObject in an editor window? - Any SO even if I don't know the fields within. 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges