(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

(:3[kanのメモ帳]

「描画範囲が足りなければスクロール」を実装するたった3行のコード【Unity】【エディタ拡張】


このエントリーをはてなブックマークに追加


この記事でのバージョン
Unity 2018.3.0f2


はじめに

Unityのエディタ拡張で何かしらの機能を作る際、ウィンドウを作る事はよくありますよね。


f:id:kan_kikuchi:20190207101106g:plain:w700


ただ、ウィンドウのサイズは人や状況によって変わってくるので

「描画範囲が足りなければスクロール」が実装されていると利便性が増します。

そしてその実装は、Unityのエディタ拡張ではなんとたった3行で出来るのです。


という事で今回はその実装方法の紹介記事になります。

なお、イメージとしては以下のような感じ。

//スクロール位置
private Vector2 _scrollPosition = Vector2.zero;

//表示するGUIの設定
private void OnGUI() {
  /*スクロールしない描画処理*/

  //描画範囲が足りなければスクロール出来るように
  _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition);

  /*スクロールする描画処理*/

  //スクロール箇所終了
  EditorGUILayout.EndScrollView();

  /*スクロールしない描画処理*/
}


f:id:kan_kikuchi:20190303095439g:plain


「描画範囲が足りなければスクロール」を実装するたった3行のコード

では「描画範囲が足りなければスクロール」を実装するたった3行のコードを1行づつ説明していきます。


まず、現在のスクロール位置を記録する変数の宣言です。

private Vector2 _scrollPosition = Vector2.zero;


次にEditorGUILayout.BeginScrollViewを使ってスクロール開始位置を指定します。

この時、引数で現在のスクロール位置を渡し、返り値で新しいスクロール位置を受け取ります。

_scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition);


最後にEditorGUILayout.EndScrollViewを使ってスクロールの終了位置を指定します。

EditorGUILayout.EndScrollView();


たったこれだけです!Unity(のエディタ拡張)恐るべし……!


描画範囲が足りなければスクロールするウィンドウ

「描画範囲が足りなければスクロール」する部分は3行で書けると言っても、

実際にはクラスの定義やウィンドウを開く処理なども必要になります。

なので参考に「描画範囲が足りなければスクロールするウィンドウ」のコードを書いてみました。

using UnityEngine;
using UnityEditor;

/// <summary>
/// スクロールするだけのウィンドウ
/// </summary>
public class ScrollWindow : EditorWindow {

  //スクロール位置
  private Vector2 _scrollPosition = Vector2.zero;

  //=================================================================================
  //初期化
  //=================================================================================

  //メニューからウィンドウを表示
  [MenuItem("Tools/Open/Scroll Window")]
  public static void Open() {
    GetWindow(typeof(ScrollWindow));
  }

  //=================================================================================
  //表示するGUIの設定
  //=================================================================================

  private void OnGUI() {
    //描画範囲が足りなければスクロール出来るように
    _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition);
    Debug.Log(_scrollPosition.x.ToString("F2") + ", " + _scrollPosition.y.ToString("F2"));

    //テキトウにUI表示
    for (int i = 0; i < 20; i++) {
      GUILayout.Button("特に意味のないボタン" + i.ToString(), GUILayout.Width(300));
    }

    //スクロール箇所終了
    EditorGUILayout.EndScrollView();
  }

}


これをEditorディレクトリに入れると、


f:id:kan_kikuchi:20190304113247j:plain


Tools -> Open -> Scroll Windowからウィンドウが開けるようになります。


f:id:kan_kikuchi:20190304113305j:plain


このウィンドウは描画範囲が足りなくなるとスクロール出来るようになっています。

なお、現在のスクロール位置をログで出すようにもしています。



f:id:kan_kikuchi:20190303101638g:plain


また、BeginScrollViewとEndScrollViewの外に描画処理を書けば、

スクロールしないGUIを作成する事ももちろん可能です。

EditorGUILayout.LabelField("スクロールしないラベル");
EditorGUILayout.Space();

//描画範囲が足りなければスクロール出来るように
_scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition);

//テキトウにUI表示
for (int i = 0; i< 20; i++) {
  GUILayout.Button("特に意味のないボタン" + i.ToString(), GUILayout.Width(300));
}

//スクロール箇所終了
EditorGUILayout.EndScrollView();

EditorGUILayout.Space();
GUILayout.Button("スクロールしないボタン", GUILayout.Width(300));
EditorGUILayout.Space();


f:id:kan_kikuchi:20190303095439g:plain


さらに、描画範囲が足りている場合にスクロールバーを表示させておく事も可能です。

やり方はEditorGUILayout.BeginScrollViewの引数にある

alwaysShowVertical(縦)やalwaysShowHorizontal(横)をtrueにするだけです。

_scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition, alwaysShowVertical:true, alwaysShowHorizontal:true);

f:id:kan_kikuchi:20190303100734j:plain


なお、「上下か左右のどちらかだけは常にスクロールさせない」みたいな事は出来ないようです。