ScriptableObject seem like they do not need to be attached to game objects. But, in that case, how do you reference them in an actual gameobject? It seems JS code cannot be called unless it’s instantiated in a gameobject?
You can tweak the values of a ScriptableObject's variables and save it with your project like other serialized assets.
I'm not saying this is right or wrong, but here is a way that we're using ScriptableObjects in our project:
We have a ScriptableObject that we call ProjectNameGuiData. It contains all kinds of configuration information used for our GUI.
For example, it has an array of GUIStyles that are used for all the different GUI controls.
It has a list of Rectangles that are used for GUI control layout.
It also has a list of helper objects that we create to handle things like popup windows and data classes. A popup window might have something like an array of images that the user can cycle through. These objects are tedious to initialize in the Inspector and might change for different platforms.
One thing that's nice about the ScriptableObject is we can initialize these objects (maybe in the Inspector, maybe with Editor scripts) then play with them in the Inspector. We can even tweak these values while we're playing our game. When we're done tweaking them, we can save an instance of our ScriptableObject with the project (and on Asset Server).
One reason this is nice, is we can assign an Instance of our ScriptableObject to a script that we attach to a Prefab (Maya Scene). Sure, you can just assign a normal script with a bunch of variables to a Prefab, but sometimes you loose all the linking you've done in the Inspector (maybe due to nested prefabs) when you import a new Maya Scene into your project (for example). At other times you might want to make a bunch of changes to the script's variables, which can be tedious and hard to maintain from a version control perspective.
ScriptableObjects are helping us avoid lengthy re-linking sessions in the above situations.
And the real cool thing we're doing with them is....
Once we get our ScriptableObject all dialed in... We make an instance of it for every platform we plan to build for. This allows us to tweak every piece of GUI data for every platform.
When we want to switch platforms, all we have to do is change the instance of the gui data ScriptableObject that is assigned to some Gui Data variable in a script.
I don't know if any of that that makes any sense... but it allows us to instantly switch a bazillion pieces of platform specific gui config data in a split-second by drag/dropping a ScriptableObject or with an editor script.
We end up having a folder in the project named Configuration that contains ScriptableObject instances that look like this:
StandaloneWinGuiData
StandaloneMacGuiData
TabletGuiData
PhoneGuiData
WebGuiData
They get assigned to a variable in a GUI Controller script named guiData(one at a time).
This is an ever evolving approach that we started to implement after Unite.
I hope some of it makes sense.
One other application of ScriptableObjects we intend to explore is localization. We'll have a scriptable object instance for every translation of our game and will assign different instances to the GUI Controller when appropriate.
-- Edit to answer the question from ina's comment --
For our project, the definition of the ScriptableObject is VERY simple:
`
class FunkyGameGuiData extends ScriptableObject { var styles : FunkyGameStyleBundle; var dimensions : FunkyGameDimensionBundle; var helpers : FunkyGameHelperClassBundle; }`
Those are all custom classes that contain project/build specific data. FunkyGameStyleBundle, for example, might contain a number of GUIStyles:
`
class FunkyGameStyleBundle { rightMenu : GUIStyle; leftMenu : GUIStyle; homeButton : GUIStyle; saveScoreBox : GUIStyle; }`
A FunkyGameHelperClassBundle, however, has all kinds of different objects in it: ScreenshotManager, PictureScrollerPopupManager, ScoreSaver, etc... Each of these objects has properties that get assigned and edited with editor scripts and in the Inspector. Re-linking them after re-importing a new Maya prefab could take hours! Saving them as ScriptableObjects allows them to persist in the project and on AssetServer.
Oh yeah... Another thing that's nice about ScriptableObjects is if you use them this way it helps you organize your Inspector. You end up with a bunch of objects that you can expand and hide to keep things organized.
The only way I've instantiated a ScriptableObject is using an Editor script using ScriptableObject.CreateInstance. You call this function and save the instance it creates using AssetDatabase.CreateAsset.