Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What are the problem?
@yambowcto

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

はじめに

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

おわりに

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
1
Help us understand the problem. What are the problem?