LoginSignup
1

More than 3 years have passed since last update.

よく使うシーンなどを登録して便利に…

Last updated at Posted at 2020-11-24

はじめに

Unityで作業をしていると、シーンやフォルダを探すことがよくあります。
今回は自分が昔作ったお気に入り機能をちょっと見栄えを整えて紹介します。
まあ Two Column Layout を使ってる方は標準のFavorites機能を使えば全て解決なんですが…

使い方

・メニューのWindow/Favoriteでウィンドウを開きます。
・お気に入り登録したいものをDrag&Dropします。
登録名:選択、開く:シーンを開く、Show:フォルダを開く、除外:登録を外す
 という感じで使用します。
2020-11-24_10h56_08.png

動作環境

動作を確認した環境です。
・Unity2017.4.24f1
・Unity2019.4.12f1
・Windows10

コード

以下のスクリプトをEditorフォルダに入れて使用します。

FavoriteWindow.cs
using UnityEngine;
using UnityEditor;
using UnityEditor.SceneManagement;
using System.Collections.Generic;
using System.Linq;
using System.IO;

public class FavoriteWindow : EditorWindow
{
    Vector2 scrollPos = Vector2.zero;
    const string saveFile = "/Workspace/JumpFavorite.txt";
    HashSet<string> hashGuid = null;

    // お気に入り選択
    [MenuItem("Window/Favorite")]
    static void ShowWindow()
    {
        var win = GetWindow<FavoriteWindow>();
        // お気に入りのBuilt-in Icon取得して設定
        var fav = EditorGUIUtility.IconContent("Favorite Icon");
        fav.text = "Favorite";
        win.titleContent = fav;
    }
    void OnGUI()
    {
        // NULLだったら読み込み
        if(null == hashGuid)
            LoadFavoriteGuid();

        GUILayout.Space(5);
        Object obj = null;
        obj = EditorGUILayout.ObjectField("お気に入り登録", obj, typeof(Object), false);
        if(null != obj) {
            // お気に入りを登録
            var path = AssetDatabase.GetAssetPath(obj);
            var guid = AssetDatabase.AssetPathToGUID(path);
            hashGuid.Add(guid);
            // 保存
            SaveFavoriteGuid();
            return;
        }

        if(0 == hashGuid.Count)
            return;

        using(var scroll = new GUILayout.ScrollViewScope(scrollPos)) {
            scrollPos = scroll.scrollPosition;
            string remove = "";
            foreach(var n in hashGuid) {
                using(new EditorGUILayout.HorizontalScope()) {
                    var path = AssetDatabase.GUIDToAssetPath(n);
                    var name = Path.GetFileNameWithoutExtension(path);
                    var ext = Path.GetExtension(path);
                    // 選択
                    var icon = AssetDatabase.GetCachedIcon(path);
                    GUILayout.Label(icon, GUILayout.Height(20), GUILayout.Width(20));
                    if(GUILayout.Button(name, GUILayout.Width(200)))
                    {
                        if (!string.IsNullOrEmpty(n))
                            Selection.activeObject = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(n), typeof(Object));
                        break;
                    }
                    // 開く(シーンなら)
                    using(new EditorGUI.DisabledGroupScope(ext != ".unity"))
                    {
                        if(GUILayout.Button("開く", GUILayout.Width(40))) {
                            if(EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
                                EditorSceneManager.OpenScene(path);
                            break;
                        }
                    }
                    // Show in Explore
                    if(GUILayout.Button("Show", GUILayout.Width(50))) {
                        if(Directory.Exists(path)) {
                            var fullPath = Application.dataPath + "/../" + path;
                            System.Diagnostics.Process.Start(fullPath);
                        }
                        else
                            EditorUtility.RevealInFinder(path);
                        break;
                    }
                    // 除外
                    if(GUILayout.Button("除外", GUILayout.Width(40))) {
                        remove = n;
                        break;
                    }
                }
            }
            if(!string.IsNullOrEmpty(remove))
            {
                // 除外
                hashGuid.Remove(remove);
                // 保存
                SaveFavoriteGuid();
            }
        }
    }

    void SaveFavoriteGuid()
    {
        string path = Application.dataPath + saveFile;
        string dir = Path.GetDirectoryName(path);
        // フォルダがなかったら作る
        if(!Directory.Exists(dir))
            Directory.CreateDirectory(dir);
        // 保存
        string[] arrGuid = hashGuid.ToArray();
        var str = string.Join("\n", arrGuid);
        File.WriteAllText(path, str);
        AssetDatabase.Refresh();
    }
    void LoadFavoriteGuid()
    {
        hashGuid = new HashSet<string>();
        string path = Application.dataPath + saveFile;
        if(!File.Exists(path))
            return;

        var str = File.ReadAllText(path);
        var arrGuid = str.Split("\n"[0]);
        // 無かったら無視
        foreach(var n in arrGuid) {
            if("" != AssetDatabase.GUIDToAssetPath(n))
                hashGuid.Add(n);
        }
    }
}

解説

注意が必要なのは、OpenSceneを使用すると現在編集中のシーンが破棄されてしまうのでEditorSceneManager.SaveCurrentModifiedScenesIfUserWantsToで編集中のシーンを保存するかの確認をとった方がいいです。

あと、EditorUtility.RevealInFinderでフォルダを開く場合、ファイルを指定していればそのフォルダを開いてくれますが、フォルダを指定していると親フォルダが開かれます。
なので、Process.Startを使用してフォルダは開いています。

管理はGuidをHashSetで行ってるだけなので並び順は気にしてません。まあ、並び替えが必要なほど登録する時点でもはやこの機能を使う意味がないと思いますが…

おわりに

すでに便利なアセットや似たようなことをやってる方たちがいるので今更感がありますが
自分の好みな感じに仕上がっています。
もし好みに合えば使っていただければと思います。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1