2018年6月22日金曜日

UnityのGameViewのScaleを1に強制的に戻すエディタ拡張

UnityのGame Viewが勝手に拡大されるというMASAさんのツイートを見ました


そう言われてみると、思い返せば確かにプレイ時に手動でスケールを戻すことをよくしてる気がします。



非プレイ時にマウスのセンターホイールをスクロールするとここのスケールが変わるので、多分プレイボタンを押す際に間違ってセンターホイールに触れてるんじゃないかと推測してます。

プレイ時にスケールが拡大されてて戸惑うことはあってもうれしいことはほぼありません。
そこで、プレイ時に強制的にスケールを1に戻すエディタ拡張を書くことにしました。


UnityEditor.GameViewは公開されてないので、リフレクションを使ってアクセスします。
 
                var asm = typeof(Editor).Assembly;
                var type = asm.GetType("UnityEditor.GameView");
                EditorWindow gameView = EditorWindow.GetWindow(type);

というコードで、GameViewのインスタンスにアクセスできます。

問題は、GameViewのどの内部関数を呼べばスケールを1に出来るかです。

それを調べるために、GameViewのソースを見てみましょう
 https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/GameView/GameView.cs

Scaleに関することなので適当にScaleで文字列検索してソースを読むと、SnapZoomの引数を1で呼べばスケールが1に戻りそうな気がします。

試してみましょう。

#if UNITY_EDITOR

using UnityEditor;

static class GameViewUtil
{   
[InitializeOnLoadMethod]
    static void CheckPlaymodeState()
    {
        // プレイモードが変わったときのコールバックに登録する
        EditorApplication.playModeStateChanged += x =>
        {
            // Playモードに変わったときに処理する
            if (x == PlayModeStateChange.EnteredPlayMode)
            {
                var asm = typeof(Editor).Assembly;
                var type = asm.GetType("UnityEditor.GameView");
                EditorWindow gameView = EditorWindow.GetWindow(type);

                // GameViewクラスのSnapZoomプライベートインスタンスメソッドを引数1で呼び出す
                var flag = System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance;
                type.GetMethod("SnapZoom", flag, null, new System.Type[] { typeof(float) }, null).Invoke(gameView, new object[] { 1 });
            }
        };
    }
}

#endif
このコードをファイルに保存し、どこでもいいので配置します。
(Editorフォルダの中に入れるならば、#ifdef UNITY_EDITORは必要ありません)

そして実行してみると、Unity 2018.1では無事実行するたびにスケールが1に戻ることがわかります。

ただし、リフレクションで公開されてない内部関数にアクセスしてるため、バージョンが違うと動作しなくなることも十分ありえます。

おわり

1 件のコメント:

  1. URLクリックしたらNotFoundになっておりました。

    https://www.blogger.com/%C2%A0https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/GameView/GameView.cs

    なぜか「www.blogger.com/%C2%A0https://」が含まれてしまっているようでした。
    今更な報告ですが、一応お知らせいたします!

    返信削除