ScriptableObjectのAsset作成系

※この記事は2017年05月25日にqiitaに投稿した内容です。

環境

Unity5.6.1f1

概要

ScriptableObjectのAsset作成系色々です。

プログラム

EditorCreateAssets

using System.IO;
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;

public class EditorCreateAssets : EditorWindow
{
    //-------------------------------------------------------------------------
    //メニューから独自にアセットを作成する
    //Windowメニュー
    //-------------------------------------------------------------------------
    [MenuItem( "TestCreateAssets/Create/TestAssetA" )]
    public static ScriptableObject CreateAsset()
    {
        var obj = ScriptableObject.CreateInstance( "TestAssetA" );
        ProjectWindowUtil.CreateAsset( obj, "TestAssetA.asset" );
        return obj;
    }

    //-------------------------------------------------------------------------
    //メニューから独自にアセットを作成する サブアセットも作成
    //Windowメニュー
    //-------------------------------------------------------------------------
    [MenuItem( "TestCreateAssets/Create/TestAssetA And TestAssetB" )]
    public static ScriptableObject CreateAssets()
    {
        var obj = ScriptableObject.CreateInstance( "TestAssetA" );

        var endNameEditAction = ScriptableObject.CreateInstance<EndNameEditActionTestAssetA>();
        endNameEditAction.onCreate = OnCreate;
        var icon = AssetPreview.GetMiniThumbnail( obj );
        ProjectWindowUtil.StartNameEditingIfProjectWindowExists( obj.GetInstanceID(), endNameEditAction, "TestAssetA.asset", icon, "" );
        return obj;
    }

    private static void OnCreate( TestAssetA TestAssetA, string pathName )
    {
        var TestAssetB = ScriptableObject.CreateInstance( "TestAssetB" );
        AssetDatabase.AddObjectToAsset( TestAssetB, TestAssetA );
        AssetDatabase.ImportAsset( AssetDatabase.GetAssetPath( TestAssetA ), ImportAssetOptions.ForceUpdate | ImportAssetOptions.ImportRecursive );
    }
    //-------------------------------------------------------------------------
    //ファイルダブルクリック時
    //コンテキストメニューでOpenを選択時
    //-------------------------------------------------------------------------
    [OnOpenAssetAttribute(1)]
    public static bool OpenStep1( int instanceID, int line )
    {
        var obj = EditorUtility.InstanceIDToObject( instanceID );
        var name = obj.name;
        Debug.Log("Open Asset step: 1 ("+name+")");

        var TestAssetA = obj as TestAssetA;
        if( TestAssetA == null )
            return false;
        TestAssetA.Open();
        return false;
    }
    [OnOpenAssetAttribute(2)]
    public static bool OpenStep2( int instanceID, int line )
    {
        Debug.Log("Open Asset step: 2 ("+instanceID+")");
        return false;
    }

    //-------------------------------------------------------------------------
    //値を変更
    //独自のコンテキストメニュー
    //Assets/が必要
    //-------------------------------------------------------------------------
    [MenuItem( "Assets/TestCreateAssets/ChangeValue" )] 
    public static bool ChangeValue()
    {
        //GetObjectFolder( Selection.activeObject );

        var obj = Selection.activeObject;
        if( obj == null )
            return false;
        if( ( obj as TestAssetA ) != null )
        {
            var testAssetA = obj as TestAssetA;
            Undo.RecordObject( testAssetA, "ChangeValue:" + testAssetA.name );
            testAssetA.ChangeValue();
        }
        else if( ( obj as TestAssetB ) != null )
        {
            var testAssetB = obj as TestAssetB;
            Undo.RecordObject( testAssetB, "ChangeValue:" + testAssetB.name );
            testAssetB.ChangeValue();
        }
        else
            return false;

        //保存
        EditorUtility.SetDirty( obj );
        AssetDatabase.ImportAsset( AssetDatabase.GetAssetPath( obj ), ImportAssetOptions.ForceUpdate | ImportAssetOptions.ImportRecursive );

        return true;
    }
    //-------------------------------------------------------------------------
    //サブアセット追加
    //独自のコンテキストメニュー
    //Assets/が必要
    //-------------------------------------------------------------------------
    [MenuItem( "Assets/TestCreateAssets/AddSubAsset" )]
    public static bool AddSubAsset()
    {
        var obj = Selection.activeObject;
        if( obj == null )
            return false;
        var TestAssetA = obj as TestAssetA;
        if( TestAssetA == null )
            return false;

        var TestAssetB = ScriptableObject.CreateInstance( "TestAssetB" );
        AssetDatabase.AddObjectToAsset( TestAssetB, TestAssetA );
        AssetDatabase.ImportAsset( AssetDatabase.GetAssetPath( TestAssetA ), ImportAssetOptions.ForceUpdate | ImportAssetOptions.ImportRecursive );

        return true;
    }

    //-------------------------------------------------------------------------
    //サブアセット削除
    //独自のコンテキストメニュー
    //Assets/が必要
    //-------------------------------------------------------------------------
    [MenuItem( "Assets/TestCreateAssets/RemoveSubAsset" )]
    public static bool RemoveSubAsset()
    {
        var obj = Selection.activeObject;
        if( obj == null )
            return false;
        var TestAssetB = obj as TestAssetB;
        if( TestAssetB == null )
            return false;

        var mainAsetPath = AssetDatabase.GetAssetPath( TestAssetB );
        Object.DestroyImmediate( TestAssetB, true );
        AssetDatabase.ImportAsset( mainAsetPath, ImportAssetOptions.ForceUpdate | ImportAssetOptions.ImportRecursive );
        return true;
    }

    //-------------------------------------------------------------------------
    //オブジェクトのフォルダを取得
    //-------------------------------------------------------------------------
    private static string GetObjectFolder( Object obj )
    {
        var path = AssetDatabase.GetAssetPath( obj );
        if( obj == null || string.IsNullOrEmpty( path ) == true )
            path = "Assets/";
        else
        {
            if( ProjectWindowUtil.IsFolder( obj.GetInstanceID() ) == false )
                path = path.Replace( Path.GetFileName( AssetDatabase.GetAssetPath( obj ) ), "" );
        }
        Debug.Log( "OpenFolder:" + path );
        return path;
    }
    //-------------------------------------------------------------------------
    //エディタスクリプトのフォルダを取得
    //-------------------------------------------------------------------------
    private static string GetEditorScriptFolder( ScriptableObject sobj )
    {
        //var ms = MonoScript.FromMonoBehaviour( sobj);
        var ms = MonoScript.FromScriptableObject( sobj);
        return GetObjectFolder( ms );
    }
}

EndNameEditActionTestAssetA

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.ProjectWindowCallback;
using UnityEngine;
using UnityEngine.Events;

public class EndNameEditActionTestAssetA : EndNameEditAction
{
    public UnityAction<TestAssetA, string> onCreate = null;

    public override void Action( int instanceId, string pathName, string resourceFile )
    {
        var TestAssetA = EditorUtility.InstanceIDToObject( instanceId ) as TestAssetA;
        AssetDatabase.CreateAsset( TestAssetA, pathName );
        AssetDatabase.ImportAsset( pathName );
        ProjectWindowUtil.ShowCreatedAsset( TestAssetA );

        if( onCreate != null )
            onCreate.Invoke( TestAssetA, pathName );
    }
}

TestAssetA

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//アセットAの作成
//ContextメニューのCreateに追加される
[CreateAssetMenu( fileName = "TestAssetA", menuName = "TestCreateAssets/TestAssetA", order = 1 )]
public class TestAssetA : ScriptableObject
{
    [SerializeField] private int _intValue0 = 0;
    [SerializeField] private float _floatValue0 = 1.0f;

    public void Open()
    {
        Debug.Log( "Open!" + name );
    }

    public void ChangeValue()
    {
        Debug.Log( "ChangeValue!" + name );

        _intValue0 ++;
        _floatValue0 += 1.0f;
    }
}

TestAssetB

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//アセットBの作成
//ContextメニューのCreateに追加される
[CreateAssetMenu( fileName = "TestAssetB", menuName = "TestCreateAssets/TestAssetB", order = 1 )]
public class TestAssetB : ScriptableObject
{
    [SerializeField] private int _intValue0 = 10;
    [SerializeField] private float _floatValue0 = 11.0f;

    public void Open()
    {
        Debug.Log( "Open!" + name );
    }

    public void ChangeValue()
    {
        Debug.Log( "ChangeValue!" + name );

        _intValue0 ++;
        _floatValue0 += 1.0f;
    }
}