ゲームバランスをUnityのEditor上で設定できるScriptableObjectを試す

ゲームバランスをUnity Editor上で設定したい時に手軽な方法として、ScriptableObjectを使う方法があります。
ScriptableObjectを使うと、GameObjectにアタッチしない状態で独立したAssetとして持つことができます。

今回は以下のように、白文字と黒文字を切り替えれる、２つの設定を作ります。

![main_unity_-_ScriptableObjectSample_-_PC__Mac___Linux_Standalone.png](https://qiita-image-store.s3.amazonaws.com/0/30079/f67d146d-fd1d-f82d-6528-d681fb854cd6.png)
![main_unity_-_ScriptableObjectSample_-_PC__Mac___Linux_Standalone 2.png](https://qiita-image-store.s3.amazonaws.com/0/30079/d7e7e66d-b303-30cf-d50c-ea1ddb3abce9.png)

# 手順
まずScriptableObjectのコードを[Scripts/ScriptableObjectSample.cs]に作成します。

```csharp
public class ScriptableObjectSample : ScriptableObject {
    public Color textColor;
    public int textSize;
    public string text;
}
```

ScriptableObjectはそのままではAssetに追加されないので、メニューからAssetに追加できるようにするコードを[Scripts/Editor/CreateScriptableObjectSample.cs]に作成します。

```csharp
using UnityEngine;
using UnityEditor;
using System.Collections;

public class CreateScriptableObjectSample : MonoBehaviour {
    [MenuItem("Assets/Create/ScriptableObjectSample")]
    public static void CreateAsset()
    {
        CreateAsset<ScriptableObjectSample>();
    }

    public static void CreateAsset<Type>() where Type : ScriptableObject{
        Type item = ScriptableObject.CreateInstance<Type>();
        
        string path = AssetDatabase.GenerateUniqueAssetPath("Assets/Data/" + typeof(Type) + ".asset");
        
        AssetDatabase.CreateAsset(item, path);
        AssetDatabase.SaveAssets();
        
        EditorUtility.FocusProjectWindow();
        Selection.activeObject = item;
    }
}
```

Project->Createを押すと一番したにScriptableObjectSampleができています。[Data]フォルダを`Assets`直下に作った後に、これをクリックするとScriptableObjectが`Assets`直下に作られます。

![スクリーンショット_2014-10-07_17_47_16.png](https://qiita-image-store.s3.amazonaws.com/0/30079/1ab6d589-b1cf-d041-11c8-9f99d9fff3d7.png)

適当に設定します。

![main_unity_-_ScriptableObjectSample_-_PC__Mac___Linux_Standalone_と_新規作成_-_Qiita.png](https://qiita-image-store.s3.amazonaws.com/0/30079/6610c41d-fd09-5cab-f998-4880e9800ee7.png)

次にシーンに先ほど作成したScriptObjectの設定をGUI表示できるようにGameObjectを作り、以下のスクリプトをアタッチします。

```csharp
using UnityEngine;
using System.Collections;

public class GameManager : MonoBehaviour {
    [SerializeField]
    private ScriptableObjectSample setting;

    void OnGUI() {
        string   str    = setting.text;
        GUIStyle style  = new GUIStyle();
        style.fontSize  = setting.textSize;
        style.normal.textColor = setting.textColor;
        Vector2  size   = style.CalcSize(new GUIContent(str));
        GUI.Label(new Rect(Screen.width / 2 - size.x / 2, 
                           Screen.height / 2 - size.y / 2,
                           100, 
                           200
                           ), 
                  str, 
                  style);
    }
}
```

設定を反映するために、アタッチしたGameManagerのプロパティにScriptableObjectをセットします。

![main_unity_-_ScriptableObjectSample_-_PC__Mac___Linux_Standalone 3.png](https://qiita-image-store.s3.amazonaws.com/0/30079/6e273512-1d74-cadb-00bc-8bac286bc92e.png)

実行すると設定が反映されていることがわかります。黒色も作る場合には同じ手順を繰り返し、GameManagerに設定するとできます。

![main_unity_-_ScriptableObjectSample_-_PC__Mac___Linux_Standalone 4.png](https://qiita-image-store.s3.amazonaws.com/0/30079/738bb1c5-a318-ac18-7e71-ad230e02592a.png)

# おまけ

以前作ったScriptableObjectのアセットをコピーして使いたいときがあるかもしれません。しかし、アセットを右クリックしてもコピーできる方法がないので、これもAssetのMenuに追加してみました。どのファイルでもいいのですが、今回はついでなので、[Scripts/Editor/CreateScriptableObjectSample.cs]に以下のコードを追記しました。

```csharp
public class DuplicateAsset : MonoBehaviour {
    
    [MenuItem("Assets/Duplicate")]
    public static void Duplicate()
    {
        var item = Selection.activeObject;
        string path = AssetDatabase.GetAssetPath(item);
        string newPath = AssetDatabase.GenerateUniqueAssetPath(path);
        AssetDatabase.CopyAsset(path, newPath);
        
        AssetDatabase.Refresh();
        
        EditorUtility.FocusProjectWindow();
        Selection.activeObject = Resources.LoadAssetAtPath(newPath, typeof(object));
    }
}
```

これでアセットを
右クリックしてDuplicateをクリックするとコピーできます。

![スクリーンショット_2014-10-07_17_57_15.png](https://qiita-image-store.s3.amazonaws.com/0/30079/46fff82a-82f2-f4ab-8bfd-fa8332b86ed8.png)

赤色を作っていれてみました。目が痛いですねorz...

![main_unity_-_ScriptableObjectSample_-_PC__Mac___Linux_Standalone 6.png](https://qiita-image-store.s3.amazonaws.com/0/30079/d6a21f12-7ce5-1cf5-ebb6-8efdc0c84879.png)