【Unity】UIElements Expansions

UIElements ExpansionsはUnityエディター用の拡張アセットです。

UIElements Expansions

UIElements Expansions」シリーズはUnity2019.1から導入が始まった「UIElements」を強力にサポートします。

UIElementsとは

UIElementsとはUnity2019.1から導入が始まった現在のUnityエディターのGUIシステム(IMGUI)を置き換える機能です。

Unity向けのHTML「UXML」、Unity向けのスタイルシート「USS」を組み合わせてHTMLとCSSでwebページを作るかのごとくUnityのGUIを制作できます。

もちろんこれまでのようにエディタースクリプトでエディター用の処理を記述できますし、jQueryのようなメソッドが用意されているため、HTML5のような動的なGUIを作ることができます

将来的にはエディターだけでなくランタイムのGUI(現在のuGUI)を置き換えると計画されており、将来のUnityのGUIを任せられると期待される存在なのです。

ただポテンシャルは高いのですがまだ導入されたばかりなので本格的に使用するにはまだまだ機能が足りません

UIElements Expansions」はその足りない部分を強力にサポートするアセットです。

この「UIElements Expansions」シリーズでは現在主に下記のアセットの配信を行っています。

ここではこれらのアセットに共通する機能を紹介していきます。

  • グローバルスタイルシート
  • インスペクター自動アサイン機能
  • 追加タグ / 機能

グローバルスタイルシート

USSの元となったCSSは通常共通のファイルをひとつ以上作り、それをHTMLのヘッダーでまとめて読み込む、という使い方をします。

グローバルスタイルシートはCSSと同じような使い方を実現することができるようになります。

インスペクター自動アサイン機能

UnityではコンポーネントやスクリプダブルオブジェクトなどのインスペクターのGUIを自由に書き換えることができます。ただその場合、そのコンポーネント用に独自にエディタースクリプトを記述する必要があります。

UXMLで構成をHTMLのように記述することができるようになりましたが作成したUXMLをどのコンポーネントにアサインするかをエディタースクリプトで記述する必要があり若干面倒です。

インスペクター自動アサイン機能」はエディタースクリプトを記述せずともUXMLのファイル名だけでどのコンポーネントで利用するかを自動で判別し、自動でアサインしてくれるようになります。

追加タグ / 機能

UIElementsでは独自のUXMLタグを追加して スタイルを適用したり機能を持たせることができます。UIElements Expansionsでは複数の便利なタグを追加しておりUIElementsの利用をサポートします。

現在追加されているUXMLタグは以下のとおりです。

  • Div
    • VisualElementのエイリアスです。機能は特に無く、USSの指定に利用します。
  • Header、Footer、Main、Article
    • VisualElementのエイリアスです。 機能は特に無く、 USSの指定に利用します。
  • H1~H6
    • Labelのエイリアスです。 機能は特に無く、 USSの指定に利用します。
  • Binding-Image
    • シリアライズされたプロパティから画像を取得し表示できます。また外部のURL(http://~)の利用も可能です。
  • Editor-Button
    • Editor専用のButtonです。UXML上からメソッド名や値を指定してスクリプトを記述することなく静的メソッドの実行を指定できます。また、テンプレートと組み合わせて、テンプレートの切り替えを行うことも可能です。
  • Binding-Label、Binding-H1~H6
    • シリアライズされた文字列変数をラベルとして表示できます。
  • Editor-ListView
    • PropertyFieldの配列/List専用のエイリアスです。配列/ListのUSSの指定に最適化されています。

利用方法

インポート

下記の「UIElements Expansions」シリーズのいずれかをご購入ください。

この記事に記載されている機能は「UIElements Expansions」シリーズで共通して利用することができます。

購入後「マイアセット」からインポートすることができます。

グローバルスタイルシート

そのままでも利用できます。

スタイルを変更したい

Assets/Masamune/Modules/unity.style/Styles」フォルダにある「PersonalStyle」と「ProStyle」を編集してください。

通常の場合は 「PersonalStyle」 、Unity ProやPlusで使用できるプロスキン(黒ベースのスキン)をお使いの場合は「ProStyle」を編集することで即座にスキンが反映されます。

独自のスタイルシートを使いたい

Assets/Masamune/Modules/unity.style/Resources」フォルダにある「EditorStyleInfo」 を選択します。インスペクターに編集画面が表示されます。

StyleSheet Settings」のタブを開くと「Style Sheets」と「Style Sheets For Pro Skin」のリストが表示されるはずです。それぞれ通常のエディタープロスキンを適用したエディターのスタイルファイルを指定しています。

ここからスタイルファイルを追加することができます。下にあるほど優先順位が高いので必要に応じ順番を入れ替えてお使いください。

インスペクター自動アサイン機能

作成した「MonoBehaviour」や「ScriptableObject」を継承したクラスと同じ名前のuxmlファイルを作成することで作成したクラスのインスペクター画面にuxmlを適用することができるようになります。

「MonoBehaviour」を継承した「MyMonoScript」を作成します。

// MyMonoScript.cs
public class MyMonoScript : MonoBehaviour {
  public string name;
  public int age;
  ...
}

同じ「MyMonoScript」というuxmlファイルを作成します。(Assetsフォルダ以下であればどこでもOK

// MyMonoScript.uxml
<?xml version="1.0" encoding="utf-8"?>
<engine:UXML
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:engine="UnityEngine.UIElements"
    xmlns:editor="UnityEditor.UIElements"
    xsi:noNamespaceSchemaLocation="../../../../UIElementsSchema/UIElements.xsd"
>
  <editor:PropertyField binding-path="name" class="box" />
  <editor:PropertyField binding-path="age" class="box" />    
</engine:UXML>

これでUIElementsのスタイルが適用された インスペクター画面が表示されます。

MonoBehaviourやScriptableObject以外での利用

Listや配列内の独自クラスなど「MonoBehaviour」や「ScriptableObject」でこの機能を利用したい場合、「SerializableBehaviour」を継承することで実現することができます。

利用方法は、「MonoBehaviour」や「ScriptableObject」継承クラスと同じように「SerializableBehaviour」を継承したクラス「MySerializable」を作ります。独自クラスはシリアライズ可能なことを明示しなければいけないため[System.Serializable]属性を付与します。

// MySerializable.cs
[System.Serializable]
public class MySerializable : SerializableBehaviour {
  public string name;
  public int age;
  ...
}

同じように「MySerializable」というuxmlファイルを作成します。

// MySerializable.uxml
<?xml version="1.0" encoding="utf-8"?>
<engine:UXML
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:engine="UnityEngine.UIElements"
    xmlns:editor="UnityEditor.UIElements"
    xsi:noNamespaceSchemaLocation="../../../../UIElementsSchema/UIElements.xsd"
>
  <editor:PropertyField binding-path="name" class="box" />
  <editor:PropertyField binding-path="age" class="box" />    
</engine:UXML>

これで「MySerializable」クラスもインスペクターでUIElementsが適用された状態で表示されます。

エディタースクリプトとの併用

すでにエディタースクリプトを作成している方もいらっしゃるかもしれません。エディタースクリプトで特定のクラスのインスペクター画面を変更されている場合は作成したエディタースクリプトが優先されます。

追加タグ / 機能

Div

Div」タグは「VisualElement」のエイリアスです。 VisualElementと同じ機能が使えます。

<engine:Div>
  他のUXMLタグ
</engine:Div>

Header、Footer、Main、Article

Header」「Footer」「Main」「Article」タグは「VisualElement」のエイリアスです。 VisualElementと同じ機能が使えます。

<engine:Header>
  他のUXMLタグ
</engine:Header>

H1~H6

H1」「H2」「H3」「H4」「H5」「H6」タグは「Label」のエイリアスです。 Labelと同じ機能が使えます。

表題用に追加されたタグで、表題用のUSSクラスが予め適用されています。

<engine:H1 text="1番大きいタイトル" />
<engine:H2 text="2番目に大きいタイトル" />
<engine:H3 text="3番目に大きいタイトル" />

Binding-Image

Binding-Image」は「Image」タグの拡張を行うEditor専用のタグです。 Imageの機能に加え、いくつかの機能が使えます。

外部URL画像の表示

src」属性を利用することで外部URLの画像を読み込んで表示することができます。

<editor:Image src="外部URL" />

インターネットに接続されていないとき、外部URLにアクセスできないときは画像が表示されないことにご注意ください。

シリアライズされた変数からの読み込み

binding-path」属性を利用することで、「PropertyField」などと同じ様にシリアライズされた値を読み込むことができます。

<editor:Image binding-path="シリアライズされた変数名" />

Editor-Button

Editor-Button」は「Button」タグの拡張を行うEditor専用のタグです。 Buttonの機能に加え、いくつかの機能が使えます。

メソッドの実行の指定

アセンブリ名(省略可)」「タイプ名(namespace込み)」「メソッド名」を指定することで、ボタンが押された際のメソッドの実行をUXML上から指定できます。

<editor:Button class="list" text="Beep" assembly="UnityEditor" type="UnityEditor.EditorApplication" method="Beep" />

また「value」属性を指定することで引数が文字列のメソッドに値を渡すことができます。

<editor:Button class="list" text="mathru.net" assembly="UnityEngine" type="Application" method="OpenURL" value="https://mathru.net" />
テンプレートの切り替え

Template」タグと組み合わせて、UXML内のテンプレート切り替えを行うことも可能です。

<engine:Template path="Assets/Masamune/UIElements.Expansions.ResponsiveGrid/Assets/Styles/Articles/About.uxml" name="About" />
<engine:Template path="Assets/Masamune/UIElements.Expansions.ResponsiveGrid/Assets/Styles/Articles/ResponsiveGrid.uxml" name="ResponsiveGrid" />
<engine:Template path="Assets/Masamune/UIElements.Expansions.ResponsiveGrid/Assets/Styles/Articles/ReorderableList.uxml" name="ReorderableList" />
<engine:Template path="Assets/Masamune/UIElements.Expansions.ResponsiveGrid/Assets/Styles/Articles/Card.uxml" name="Card" />

<engine:Instance template="About" name="main">
</engine:Instance>

<editor:Button text="About" template="About" target="main" />
<editor:Button text="Reorderable List" template="ReorderableList" target="main" />
<editor:Button text="Responsive Grid" template="ResponsiveGrid" target="main" />
<editor:Button class="list" text="CardView / CardList" template="Card" target="main" />

上記例の場合、最初にAbout.uxmlの中身が「name="main"」に表示されます。各ボタンをクリックすることにより「template」属性に記載されてある名前のテンプレートが「target」属性に記載されてある名前の場所、つまり「name="main"」の中身に反映されます。

Binding-Label、Binding-H1~H6

Binding-Label」「Binding-H1~H6」 は「Label」タグの拡張を行うEditor専用のタグです。 Labelの機能に加え、いくつかの機能が使えます。

シリアライズされた変数からの読み込み

binding-path」属性を利用することで、「PropertyField」などと同じ様にシリアライズされた値を読み込むことができます。

<editor:Label binding-path="シリアライズされた変数名" />
<editor:H1 binding-path="シリアライズされた変数名" />
<editor:H2 binding-path="シリアライズされた変数名" />
<editor:H3 binding-path="シリアライズされた変数名" />

Editor-ListView

Editor-ListView」は「PropertyField」タグを配列/List用に最適化させたEditor専用のタグです。PropertyFieldのクラスパスに変更を加えています。

Editor-ListView」では配列の各子要素をチェックしており、子要素が下記条件の場合「unity-listview-field__content」クラスを付与したVisualElementをそれぞれの子要素の外側に配置しております。

  • 子要素が配列/Listでない
  • 子要素にPropertyDrawerが設定されていない

これにより配列が単一要素複数要素に分類可能になり、単一要素のときのみボックスで囲むといったUSSの指定が可能になります。

// 単一要素のみ囲む
ListView .unity-listview-field__content {
    margin: 2px 0 2px 0;
    padding: 2px;
    color: #888;
    border-width: 1px;
    border-color: #212121;
    background-color: #2f2f2f;
}

まとめ

UIElements Expansions」シリーズはUnity2019.1から導入が始まった「UIElements」を強力にサポートします。特にこれまでエディタースクリプトを書く必要があったインスペクターのデザインを簡単に記述することができるようになります

デザインはフラットデザインを導入し一気にカッコよくなるUnity2019.3にマッチする形に整えているので気持ちよく使うことができるでしょう。

気になりましたらアセットストアで販売・配布していますので是非ご検討ください!

コメントを残す

メールアドレスが公開されることはありません。