【Unity】【UIElements】USS(スタイルシート)を使って装飾を行う方法まとめ

UnityのUIElementsでUSSを使って装飾を行う方法をまとめました。

Unity2019.3.0

はじめに

この記事ではUIElementsでUSSファイルを使って装飾を行う方法をまとめます。
UIElementsの基本的な使い方については以下の記事で説明しています。

light11.hatenadiary.com

UXMLとUSSをスクリプトで紐づける方法なども上の記事にまとめています。
本記事はこのあたりの知識を前提としますので、必要に応じて参照してください。

USSの基本

いま、UXMLで下記のようにボタンを一つだけ配置したとします。

<engine:Button text="Example Button"/>

すると表示は次のようになります。

f:id:halya_11:20200222001056p:plain

これに対してUSSを定義するとボタンに色々な装飾を加えられます。
例えば以下のように書きます。

Button {
    height: 100px;
    width: 100px;
    color: red;
}

なんとなくわかると思いますが、Buttonの縦横を100pxに、文字色を赤に指定しています。
これを適用すると以下のような表示になります。

f:id:halya_11:20200222001431p:plain

用語として、上記のUSSでButtonと書いてある部分、つまり対象のUIを指定する部分をセレクタと呼びます。
またheightやwidthなど装飾の種類を示す部分をプロパティと呼びます。

f:id:halya_11:20200222002102p:plain

セレクタの種類

さて、前節のUSSのようにセレクタにButtonと指定すると、
UXMLでButton型を使っているボタン全てにそのスタイルが適用されます。
つまり以下のように二つボタンを配置すると、

<engine:Button text="Example Button 1"/>
<engine:Button text="Example Button 2"/>

下図のような見た目になります。

f:id:halya_11:20200222002716p:plain

実際にはボタン毎にスタイルを変えたい場合も多いと思います。
そのような場合にはUSSの「クラス」という概念を使います。
クラスを使うには以下のようにセレクタの表記を.(ドット)から始まる任意の名前にします。

.square_button { /* ドットの後にクラス名を指定する */
    height: 100px;
    width: 100px;
    color: red;
}

そしてこれを適用したいUXMLの要素に対して以下のようにクラス名を指定します。

<engine:Button text="Example Button 1" class="square_button"/> <!-- 1つ目のボタンにのみsquare_buttonクラスを適用 -->
<engine:Button text="Example Button 2"/>

結果は以下のようになります。

f:id:halya_11:20200222003240p:plain

1つ目のボタンにだけスタイルが適用されていることを確認できました。

また、セレクタを以下のように#から始めると一致するnameを持つUXML要素にのみスタイルを適用できます。

#button01 { /* #の後に名前を指定する */
    height: 100px;
    width: 100px;
    color: red;
}

UXMLは以下のように一つ目のボタンにnameを指定します。

<engine:Button text="Example Button 1" name="button01"/>
<engine:Button text="Example Button 2"/>

結果は以下のようになります。

f:id:halya_11:20200222003732p:plain

また、ワイルドカードを指定すればすべての要素に適用するスタイルを作れます。

* {
    color: white;
}

このように、セレクタの種類は以下の4つに分かれます。

セレクタの種類 説明 表記例
この型の要素すべてに適用 Button
クラス 対応するclass属性を持つ要素に適用 .square_button
名前 対応するname属性を持つ要素に適用 #button01
ワイルドカード すべての要素に適用 *

ちなみにセレクタは,(カンマ)で区切れば複数指定することが可能です。

Button, TextField { /* ButtonとTextFieldの両方に適用する */
    margin: 8px;
}

疑似状態(Pseudo-states)

次に疑似状態という機能を紹介します。
これを使うと例えば「ボタンの上にカーソルが乗っているときだけ色を変える」などといったことができます。
疑似状態は以下のように:(コロン)の後に状態名を書くことで表現します。

Button:hover{ /* hover状態のボタンにだけ適用する */
    color:red;
}

これをボタンに適用すると以下のようにカーソルが乗った時にだけ色が変わることが確認できます。

f:id:halya_11:20200222005430g:plain

疑似状態には以下の種類があります。

名前 説明
hover カーソルが乗っている状態
active インタラクションしている状態
(ボタンであれば押されている状態)
inactive インタラクションしていない状態
focus フォーカスされている状態
(テキストフィールドの選択中など)
enabled 使用可能状態
disabled 使用不可能状態
checked トグルがチェックされている状態
root ルート要素である状態

セレクタの優先順位

例えば以下のようにUSSを書くと、ボタンには両方のセレクタが対応することになります。

Button {
    color: red;
}
* {
    color: green;
}

このような場合には以下の優先順位に基づいて適用されるスタイルが選択されます。

  1. 名前セレクタ
  2. クラスセレクタ
  3. セレクタ
  4. ワイルドカードセレクタ

つまり上記の例ではボタンにはcolor: redが適用されます。
また、スクリプトからVisualElements.styleの持つ変数に値を代入すると、その値は最優先で適用されます。

入れ子になっている要素に対してセレクタを指定する

いま、下記のようにBoxの中に1つボタンが含まれ、さらにそのBoxの下にボタンが配置されているUIを考えます。

<engine:Box>
  <engine:Button text="Example Button 1"/>
</engine:Box>
<engine:Button text="Example Button 2"/>

見た目は次のようになります(わかりやすくマージンを設けています)。

f:id:halya_11:20200222013049p:plain

このとき以下のようにUSSを指定してみます。

Button{
    border-color: red;
}

すると当然ですが両方のボタンの枠線の色が変わります。

f:id:halya_11:20200222013516p:plain

ここでBoxに囲まれたButtonにだけこのスタイルを適用したいとします。
このような場合には「親のセレクタ (半角スペース) 子のセレクタ」と書きます。

Box Button{ /* Box配下のButtonだけに適用 */
    border-color: red;
}

これでBoxに含まれるButtonだけにスタイルを適用できます。

f:id:halya_11:20200222014045p:plain

ちなみに上記の書き方だと、Boxの孫以降の階層として配置されているButtonにもスタイルが適用されます。
もしBoxの直接の子として配置されているButtonにだけ適用したい場合には、
以下のように「親のセレクタ(半角スペース)>(半角スペース)子のセレクタ」とします

Box > Button{/* Box直下のButtonだけに適用 */
    border-color: red;
}

プロパティの指定方法

さて次にプロパティを指定する方法についてまとめます。

まず長さについてはpxか%で指定します。
%で指定した場合は親要素との比較した時の割合となります。

Button{
    width: 50%;
    height: 100px;
}

色は様々な指定方法があります。

Button{
    color: #FF0000; /* カラーコード指定 */
    color: rgb(255, 0, 0); /* 関数指定(RGB) */
    color: rgba(255, 0, 0, 0.5); /* 関数指定(RGBA) */
    color: red; /* 色名指定 */
}

最後に画像の指定方法です。
画像をResourcesやEditor Default Resourcesフォルダから読み込むにはresource関数を使います。

Button{
    background-image: resource("Images/img") /* Resourcesから読み込む(拡張子つけない) */
    background-image: resource("Images/img.png") /* Editor Default Resourcesから読み込む(拡張子つける) */
}

またプロジェクトからの相対パスやUSSファイルからの相対パスで指定する場合にはurl関数を使います。

Button{
    background-image: url("/Assets/Editor/Images/img.png") /* プロジェクトからの相対パスで指定 */
    background-image: url("../Images/img.png") /* USSファイルからの相対パスで指定 */
}

USSで使えるプロパティ

最後にUSSで使えるプロパティを紹介します。

これに関してはまだ今後増えそうなので、マニュアルへのリンクで済ませます。
(なんかすでに載ってないものとかありそうな気がしてますが...)

docs.unity3d.com

関連

light11.hatenadiary.com

参考

docs.unity3d.com

docs.unity3d.com