Unity3D ScriptableObject helper script

If you’ve ever wanted to save some data in Unity that multiple gameobjects need to reference then you should lookup ScriptableObject this is very similar to a GameObject except it does not live in the scene. Instead you create them in your project window and you can then drag them and reference them in GameObjects etc. When selected in the project window you get the usual inspector allowing you to edit them.

In this post I have a small script to simplify this and an example Palette object in just a few lines of code.

There’s a bit of work involved in creating a scriptable object so I use a base class to do that for me. This just defines the function to be called by a create menu item and the function creates a new scriptable object at the currently selected project location:

using UnityEngine;
using System.Collections;
#if UNITY_EDITOR
using UnityEditor;
using System.IO;
#endif
public class PhiObject<T> : ScriptableObject where T : PhiObject<T>
{
        #if UNITY_EDITOR
        public static void Create(string name)
        {
                string path = AssetDatabase.GetAssetPath(Selection.activeObject);
                if(path.Length == 0){
                        // no asset selected, place in asset root
                        path = "Assets/";
                }
                else if(Directory.Exists(path)){
                        // place in currently selected directory
                        path += "/";
                }
                else{
                        // place in current selection's containing directory
                        path = Path.GetDirectoryName(path) + "/";
                }              
               
                if (path.Length > 0)
                {
                        T o = (T)ScriptableObject.CreateInstance(typeof(T));
                        o.name = name;
                        AssetDatabase.CreateAsset(o, path + o.name+".asset");
                        AssetDatabase.SaveAssets();    
                }
        }
        #endif
}

Here’s an example of using this class, it shows you how easily you can now create an object to hold whatever data you want. The example is a palette, a simple array of colors:

using UnityEngine;
using System.Collections;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class PhiPalette : PhiObject<PhiPalette>
{
	// Add the parameters you want to store here
	public Color32[] colors;

	// And then replace Palette with a name of what this is
	#if UNITY_EDITOR
	[MenuItem("Assets/Create/Phi/Palette")]
	public static void CreatePalette()
	{
		Create("New Palette");
	}
	#endif
}

That’s it you can now create a palette object by right clicking in the project window and selecting Create/Phi/Palette, then when you select it you can edit it in the inspector.

Now you have your object you can reference it in other GameObjects like so:

using UnityEngine;
using System.Collections;

public class CycleColors : MonoBehaviour {
    
	public PhiPalette palette;
	Material mat;

	void Awake () 
	{
		MeshRenderer renderer = GetComponent<MeshRenderer>();
		if(renderer != null)
		{
			mat = renderer.material;
		}
	}
	
	void Update () 
	{
		// Use our palette - just cycle through it one color every second
		mat.color = palette.colors[(int)(Time.time % palette.colors.Length)];
	}
}

And you can drag your created palette to the palette field on your object:

Capture

Leave a Reply