徳島ゲーム開発ごっこ 技術ブログ

ゲームを作るために役に立ったり立たなかったりする技術を学んでいきます!

【Unity】指定したファイルをハイライトさせたいの

今回も前回に引き続きエディタ拡張関連です。
EditorGUIUtility.PingObject() の挙動についてちょっとだけ調べてます。
f:id:urahimono:20211011235850p:plain


この記事にはUnity2020.3.20f1を使用しています。
.Netのバージョン設定には.Net4.x を使用しています。

Selection では物足りない

さて、先日AssetDatabase.FindAssets()を使って、プロジェクト内のファイルと探してみたよ、というお話をしましたね。
www.urablog.xyz

このスクリプトの最後にUnityEditor.Selectionを使って、探し出したファイルを選択状態にするところで終わりました。
でもこれじゃちょっと物足りないのです。
docs.unity3d.com

こちらのコードの挙動をご覧くだされ。

// FindTest.cs
using UnityEngine;
using UnityEditor;
using System.Linq;
public class FindTest
{
    [MenuItem("MyGame/Find")]
    private static void FindTestMenu()
    {
        // Photon フォルダ以下の Sprite ファイルを探してみるよ.
        string[] guids = AssetDatabase.FindAssets("t:Sprite", new string[] { "Assets/Photon" });
        string[] paths = guids.Select(guid => AssetDatabase.GUIDToAssetPath(guid)).ToArray();

        // とりあえず先頭のパスのファイルを選択状態にする。
        if (paths.Length > 0)
        {
            Object[] objects  = AssetDatabase.LoadAllAssetsAtPath(paths[0]);
            Selection.objects = objects;
        }
    }
} // class FindTest

f:id:urahimono:20211011235100j:plain

Inspector ビュー上では確かに検索結果のスプライトが選択されているようですが、
Project ビュー上ではなんの変化もないんです。
スプライトがあるファルダまで開けてみましょうか。

f:id:urahimono:20211011235114j:plain

確かに選択されてはいました。
しかしなぁ……、もう少し自己アピールしてほしいものですよね。
フォルダが閉じた状態だと結局どこにあるか分からないってのは困りものです。

UnityEditor.Selection も選択状態になるという利点はあるのですが、
「このファイル見つけたよ!」というリアクションを欲しい時には向かないみたいです。

そんな芸人さんのようなリアクションを望む人には、こちらの関数がピッタリですよ。

ハイライトさせる EditorGUIUtility.PingObject()

docs.unity3d.com
この EditorGUIUtility.PingObject() はリアクション芸人さんご用達の関数ですから、僕らの期待に答えてくれますよ。
先ほどのスクリプトを少し修正しましょう。

// FindTest.cs
using UnityEngine;
using UnityEditor;
using System.Linq;
public class FindTest
{
    [MenuItem("MyGame/Find")]
    private static void FindTestMenu()
    {
        // Photon フォルダ以下の Sprite ファイルを探してみるよ.
        string[] guids = AssetDatabase.FindAssets("t:Sprite", new string[] { "Assets/Photon" });
        string[] paths = guids.Select(guid => AssetDatabase.GUIDToAssetPath(guid)).ToArray();

        // とりあえず先頭のパスのファイルを選択状態にする。
        if (paths.Length > 0)
        {
            // 見つけたら元気よく返事をしよう!
            Object[] objects  = AssetDatabase.LoadAllAssetsAtPath(paths[0]);
            EditorGUIUtility.PingObject(objects[0]);
        }
    }
} // class FindTest

f:id:urahimono:20211011235126g:plain

フォルダをこじ開けて、元気よく自己アピールしてくれましたね。
この関数の気を付けてほしい点は、「選択状態になっているわけではない」というところです。
選択した状態にもする場合は、先ほどのUnityEditor.Selectionも併用する必要があることにお気をつけください。