【Unity】UIBuilderで作った画面をとりあえずゲームに乗せる

# はじめに

※2021/01/10追記
UIElementsRuntimeがパッケージになったので、個別にインポートする必要がなくなりました！
この記事はお役目終了ですね。
下記の記事が参考になります。
https://qiita.com/grevo-y-okusa/items/c89252b2ee8bc09abd07

UnityのGUIは今後UIElementsなる技術によって、nGUIから新GUIシステムに置き換わっていくそうな。
現状だとUIElementsをコードベースでガリガリ書いていくほかないのだが、Unity2019.3より**UIBuilder**なるエディタが追加され、UIElementsを使用した画面をプレビューしながら作れるようになった。
イメージとしてはWPFとかに近い？　印象（アプリ開発にあまり詳しくないので、適切な例ではないかもしれません…。）

面白そうだったので、軽く触ってみたところ、UIBuilderで画面を作ったまではいいものの、これをゲーム画面に出す方法がわからない。

そこで、Unite2019の動画を勉強していたところ、なにやら**PanelRenderer**なるコンポーネントをつけている。
なにそれしらない…。

■参考にしたUnite2019の動画
https://youtu.be/t4tfgI1XvGs

調べたところ、下記のフォーラムより、**PanelRendererなどのランタイム部分は、現在UIBuilderのパッケージに含まれていない**とのことで、Unity2020.1での完成を目指しているそう。
プレビュー版なので仕方ないとはいえ、当分公式パッケージには入らないとのこと。
https://forum.unity.com/threads/help-with-getting-started-with-ui-builder.772274/

しかし、上記のUnite2019でのデモはソースがGithubにて公開されており、当然ランタイムも含まれているので、
今回はデモからランタイム部分だけ抜き出して、自分のプロジェクトで**とりあえずゲームに乗せる**ところまでやってみた。

# 環境

- Unity 2020.1.0b3
- UI Builder preview-0.10.2

# やり方

## 1.とりあえず画面を作る
本記事ではUIBuilderの操作方法については省略する。
おそらく上記の動画を見るだけでもある程度の操作ができるようになると思われる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540876/6cb21cec-fdb1-0482-2dc5-7be36a47ce80.png)

## 2.Githubからソースを落とす

■Github -UIElementsUniteCPH2019RuntimeDemo
https://github.com/Unity-Technologies/UIElementsUniteCPH2019RuntimeDemo

落としたら、**Assets/UIERuntime**フォルダを、自分のプロジェクトのどこでもいいので適当にコピーする。

## 3.PanelRendererをつける

適当なGameobjectをシーンに配置する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540876/0d9099de-b479-03f7-cc8a-6043a2956bda.png)

配置したGameObjectにPanelRenderer、PanelScalerをつける。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540876/97b401d1-76c1-b153-72c6-fa3cd9e5be0d.png)

ここでの注意点としては、GameObjectはCanvas以下にしないこと。（nGUIのシステムで動かすわけではないので、Transformコンポーネントを持った通常のGameObjectとして作ること）

PanelScalerはnGUIのCanvasScalerと同様に設定すればOK。

PanelRenderer設定する場所は下記の通り。
- Uxml: 先程UiBuilderで作ったUxmlファイルを指定
- Unity Style Sheet: **ランタイムに含まれているDefault.ussを指定。先程作ったussファイルではないことに注意！**

あとのプロパティはソースを読み込んでないので理解していない…。（詳しい人教えて下さい。）

## 3.適当なスクリプトから、UIを有効化する

シーンコントローラなり、適当なスクリプトをシーンに配置して、下記のコードを呼ぶ。

```csharp
public class SceneController : MonoBehavior
{
    //表示するUIへの参照（インスペクタで設定する）
    [SerializeField]
    private PanelRenderer _mainUI = null;

    private void Start()
    {
        SetScreenEnableState(_mainUI, true);
    }

    //UIの表示制御
    //state==trueで表示、falseで非表示にする
    void SetScreenEnableState(PanelRenderer screen, bool state)
    {
        if (state)
        {
            screen.visualTree.style.display = DisplayStyle.Flex;
            screen.enabled = true;
            screen.gameObject.GetComponent<UIElementsEventSystem>().enabled = true;
        }
        else
        {
            screen.visualTree.style.display = DisplayStyle.None;
            screen.enabled = false;
            screen.gameObject.GetComponent<UIElementsEventSystem>().enabled = false;
        }
    }
}

```

# 結果

表示できた！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540876/c25452fd-4a01-af5b-5543-bed7b05badfb.png)

# おわりに

おそらく年内にはパッケージからランタイムが提供されるので、上記のような手間は必要なくなるかと思いますが、
いち早く新機能を触ってみたい方の参考になれば幸いです。