Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8901

XMLとか知らねぇよ!!C#だけでUIElements式エディタ拡張をする入門~基礎編~

$
0
0

はじめに

こんにちは、アドベントカレンダー2日目担当の避雷です。お仕事でエディタ拡張する必要があり、たまたまバージョン的にもUIElementsが使える感じだったので試しに使ってみたところ結構便利だったので紹介します

  • 基礎編(ここ)
  • style編

UIElementsとは

Unityが公式でサポートしている新しいUIデザインの手法です。xamlやCSSと同様の記法によってUIのデザインができます。Unity的にはuGUIからこちらへの移行を試みているようで、uGUIの方はスタメンから外されてpackageManagerへの流刑を食らっています。主観としてはUnityはゲームエンジンからソフトウェア開発プラットフォームになろうとしていて、ゲーム以外のUI設計を可能にしたい、みたいなモチベなのかなと思いました。
https://blogs.unity3d.com/jp/2019/04/23/whats-new-with-uielements-in-2019-1/

メリット

  • OnGUIコールバックベースからの脱却
  • UIにeventを登録する感じでかけるので可読性が上がる。
  • コードが書きやすい。
  • xamlによってデザインするタイプの開発経験があると同じようなスタイルで触れる。

デメリット

  • 必要になる技術が多い
  • プロジェクトメンバー全員がxamlとかCSSとか触れるスキルセットじゃないと属人性がキツくなりがち
  • 普通にuGUIの代替にはならないと思う

実装

導入

右クリックから「UIElements Editor Window」を選択して元となるスクリプトを生成しましょう。Editorフォルダ無いじゃないと生成出来ないよって怒られるので注意。
image.png

生成されるウィンドウを見てみよう

デフォルトだとWindow/UIElementから先ほど作成したwindowを呼び出すことができます。
image.png
HelloWorldって生成されていますね。

生成されたコードを読んでみよう

先ほど生成したC#を覗いてみましょう。

Test.cs
usingUnityEditor;usingUnityEngine;usingUnityEngine.UIElements;usingUnityEditor.UIElements;publicclassTest:EditorWindow{//メニューバーから呼び出すためのattribute[MenuItem("Window/UIElements/Test")]publicstaticvoidShowExample(){Testwnd=GetWindow<Test>();//↓タイトルの設定wnd.titleContent=newGUIContent("Test");}publicvoidOnEnable(){//rootVisualElement(表示されるUIすべての親となるVisualElementの取得)VisualElementroot=rootVisualElement;//VisualElementの一つ、ラベルを生成VisualElementlabel=newLabel("Hello World! From C#");//rootの子要素として追加、デフォルトだと子要素は上から下にstackされていくroot.Add(label);}}

なるほど、C#でもrootを根とした樹状構造を構築してUIを表現することが出来るみたいです。早速色々作ってみることにしましょう。

ラベルをつける

これに関してはそのままLabelというクラスがあるのでこれをインスタンスしてAppendして行きます。

Labellabel=newLabel("Hello World! From C#");root.Add(label);

コレでラベルを付けることが出来ます。label.textを用いれば後からテキストの変更もできます。

Labellabel=newLabel("Hello World! From C#");root.Add(label);label.text="aa";

ボタンをつける

ButtonというクラスがあるのでこれもインスタンスしてAppendします。

Buttonbutton=newButton(()=>Debug.Log("aaa"));button.text="Button";root.Add(button);

image.png

Buttonコンストラクタの第一引数はイベントです。button.textでボタンのテキストを変更することが出来ます。

入力ボックスを作る

TextFieldコンポネントを利用します。

TextFieldtextField=newTextField("textField");root.Add(textField);

コンストラクタの引数はラベルの名前です。
image.png

入力された値を取るにはtextField.valueを用います。
textField.RegisterValueChangedCallbackを用いて変更時のコールバックを設定することもできます。

textField.RegisterValueChangedCallback(x=>Debug.Log(x.previousValue+"=>"+x.newValue));

複数行入力に対応したいときは

textField.multilineから入力形式を変更することが出来ます。ついでに style.heightから入力欄の高さを調整しておくとそれっぽいでしょう。

textField.multiline=true;//レイアウトにかかわる部分はXX.styleから変更できるtextField.style.height=50;

image.png

ドロップダウンを作る

PopUpListというクラスがあるのでそれを使いましょう。

List<string>choices=newList<string>(){"A","B","C"};PopupField<string>popupField=newPopupField<string>(choices,0);

image.png

コンストラクタの引数は第一が選択肢、第二が初期値です。
選択中のIdを取るには popupField.index、選択中の値を取るにはpopupField.valueを用います。
また、TextField同様コールバックを登録することもできます。

popupField.RegisterValueChangedCallback(x=>Debug.Log(x.newValue));

VisualElementを使う

VisualElementはVisualElementを親として持つことが出来ます。Unityのオブジェクト群やCSS同様にヒエラルキー構造を持たせることが出来るということですね。

varelement=newVisualElement();

試しにmarginを設定してみます。

element.style.marginTop=10;element.style.marginBottom=10;element.style.marginLeft=10;element.style.marginRight=10;

ついでにborderLineも付けてみましょう

element.style.borderColor=newStyleColor(Color.black);element.style.borderBottomWidth=3;element.style.borderTopWidth=3;element.style.borderLeftWidth=3;element.style.borderRightWidth=3;

先ほどまで作っていたUIの親をrootではなくこのelementにしてみます。

// VisualElements objects can contain other VisualElement following a tree hierarchy.Labellabel=newLabel("Hello World! From C#");element.Add(label);label.text="aa";Buttonbutton=newButton(()=>Debug.Log("aaa"));button.text="Button";element.Add(button);TextFieldtextField=newTextField("textField");textField.RegisterValueChangedCallback(x=>Debug.Log(x.previousValue+"=>"+x.newValue));element.Add(textField);textField.multiline=true;textField.style.height=50;List<string>choices=newList<string>(){"A","B","C"};PopupField<string>popupField=newPopupField<string>(choices,0);element.Add(popupField);popupField.RegisterValueChangedCallback(x=>Debug.Log(x.newValue));root.Add(element);

描画結果はこんな感じです。
image.png

親要素であるelementの中に子要素のUIが入っていることがわかると思います。

おわりに

コレでC#オンリーでも雑にUIを組めるようになったのではないでしょうか?明日はUIをもうちょっとマシなレイアウトで表示するための「style」について考えてみましょう。


Viewing all articles
Browse latest Browse all 8901

Trending Articles