It’s not full-feature, I just spent a couple hours throwing it together but I feel like it covers the basics of how to use Interfaces, and a little bit about why you might want ScriptableObjects.
Feel free to post thoughts! Feedback would be appreciated. =)
You missed a couple of things about scriptable objects that really make them useful/powerful.
They are references to the original, not clones. Meaning that if you change any values in the SO, everything that uses it, sees those changes. (Unlike a regular class). It makes great for things like inventory and things of that nature.
Since it’s data is self contained, it persists across modes, so if you change at runtime or in edit mode, it’s values are maintained. Makes it great for tooling.
As they are actual project assets, they are great for pluggable data sets, like maps and things of that nature. I use them for maps and levels during development.
And lastly, you don’t need to use scripting to create them anymore. just add:[CreateAssetMenu(fileName = "MapData", menuName = "Map Data Container", order = 1)]
And it will show up in the editor under the Asset > Create menu.
They are super useful. I learned about them about a year ago, and since then use them all the time.
One great use I’ve found is as a proxy during development for remote data. Rather than build out a database and remote connection, I just build a data connection class and make a scriptable object that holds everything. That way I can easily tweak and play with stuff very quickly. When I have locked down my data structure, later, I can just swap the object for a connection in that class. It is a very fast way to develop/iterate.
I don’t know that I 100% agree with that. I know that as per recent(ish) discussions from Unity people the implementation of the Resources system leaves much to be desired, but I still think it provides valuable workflow options for small-scale projects.
Valid point. The resources folder isn’t actually used in Pond Wars.
In general I’ve used the resources folder when I want to load assets via code without actually having scene references to the assets. It’s a quick and dirty solution for procedural stuff in small projects.
I’m well aware of that, but even that talks about where it’s ok to use, in section 2.2. Sure, I could engineer a different equivalent solution, but why?
Speaking of scriptableobjects, I’ve been using them as configs, and recently hit an issue where some of the objects started breaking for no reason whatsoever. Couldn’t locate the issue.
Am interested to know what would be your solution for the following.
I have ScriptableObjects for string tables. I have a custom importer that reads an Open Office spreadsheet and creates a ScriptableObject in a Resources folder for each language. At runtime I detect the device language and load one of the ScriptableObjects as appropriate.
Instead I could have my script reference all the ScriptableObjects but this would load all of them and I only even need one.
Yeah Interfaces are a nice way to abstract away concrete implementations to a common access pattern. I used to like them a lot and relied on them quite heavily. Recently I completely threw them (along with other things) out the window and focused on simplifying everything. Using basically an 80s approach to software architecture and geesh I can’t see going back anytime soon.
EDIT: I’ll have to check out your article after work to see what these scriptable objects are. Might be something useful. If it saves effort and time I am all for it.
Giving yet more attention to ScriptableObjects… I don’t think anyone’s mentioned yet that you can use them to serialize lists of subclasses.
This doesn’t deserialize properly:
[Serializable] public class Shape {...}
[Serializable] public class Circle : Shape {...]
[Serializable] public class Square : Shape {...}
List<Shape> shapes; //<--THIS.
When Unity deserializes the list, all of the elements will be the base type, Shape, even if you’ve added Circles and Squares.
But if you make them ScriptableObjects and add them as sub-assets using AssetDatabase.AddObjectToAsset(), they’ll deserialize back into the original class types.
I use interfaces for my state machine. It used to make sure that every state machine had a StateUpdate() (for update), StateFixedUpdate() (for fixed update) and ShowIt() (for ongui). I recently removed ongui since I am using the new UI.
I still haven’t wrapped my head around scriptable objects. I’m still not sure what I’d use them for.
So what is the recommended way of doing this if you are not supposed to be using resources?
Project-wide config file that can be stored as an asset within project inspector. You can also add some functionality to them. Or a global singleton, except the singleton is a “thing” that sits in asset browser/project manager/whatever it is called.