Closed18

UnityのUI Toolkitを触ってみる

Hiroki KodamaHiroki Kodama

https://unity.com/ja/features/ui-toolkit

UI ツールキットは、ユーザーインターフェースとエディターの拡張機能を開発するための機能、リソース、ツールのコレクションです。2021 LTS では、ゲームとアプリケーションのランタイム UI の作成とデバッグをサポートし、アーティストとデザイナーがより迅速に始めるのに役立つ直感的なワークフローを備えています。

Hiroki KodamaHiroki Kodama

Unity では新規 UI 開発プロジェクトに UI ツールキットを使用することを推奨していますが、Unity UI(uGUI)や IMGUI に用意されている機能により、古いシステムを使用したほうがよいケースも引き続き存在します。Unity の UI システムを比較して、自分にとってどれが適しているかを評価してください。

https://docs.unity3d.com/Manual/UI-system-compare.html?_ga=2.264251015.92040627.1675672536-980707570.1664257091

Hiroki KodamaHiroki Kodama

Runtime

uGUI is the recommended solution for the following:

  • UI positioned and lit in a 3D world
  • VFX with custom shaders and materials
  • Easy referencing from MonoBehaviours

UI Toolkit is an alternative to uGUI if you create a screen overlay UI that runs on a wide variety of screen resolutions. Consider UI Toolkit to do the following:

  • Produce work with a significant amount of user interfaces
  • Require familiar authoring workflows for artists and designers
  • Seek textureless UI rendering capabilities
Hiroki KodamaHiroki Kodama

Editor

IMGUI is the default solution for most use cases and is especially recommended for the following :

  • Unrestricted access to editor extensible capabilities

  • Some specialized control such as the TreeView

  • Light API to quickly render UI on screen

  • UI Toolkit is an alternative to IMGUI if you create complex editor tools. Consider UI Toolkit for the following:

  • Better reusability and decoupling

  • Visual tools for authoring UI

  • Better scalability for code maintenance and performance

Hiroki KodamaHiroki Kodama

Runtime = ゲームのユーザーインターフェース
Editor = エディターの拡張機能

という理解。今回焦点を置いてるのはRuntime UI。

Hiroki KodamaHiroki Kodama

https://blog.unity.com/ja/technology/ui-toolkit-at-runtime-get-the-breakdown

思いっきりWebのUI開発に寄せた設計思想で、

  • html的なUXMLで構造化を行い
  • css的なUSSでスタイリングを行い
  • js的なC#でインタラクションの制御する

ということらしい。

UXMLドキュメントはAssets > Create > UI Toolkit > UI Document で作成できる。
空のゲームオブジェクトにUI Documentコンポーネントを追加し、
UXMLとPanel Settingsを割り当てる。
Panel SettingはUXML をどのようにインスタンス化、視覚化するかを定義している。

UXMLの構築にはUI Builderを使用する。

Hiroki KodamaHiroki Kodama

UI Builderの Containersがそれぞれどういう役割のものか調べる。

https://docs.unity3d.com/ja/2019.4/Manual/UIElements.html
(UI ElementsはUI Toolkitの旧称)

VisualElement

https://docs.unity3d.com/Manual/UIE-VisualTree.html
https://docs.unity3d.com/ja/2019.4/Manual/UIE-VisualTree.html

VisualElement は、ビジュアルツリー内のすべてのノードの共通基本クラスです。VisualElement 基本クラスには、スタイル、レイアウトデータ、ローカルの変換、イベントハンドラーなどのプロパティが含まれています。

VisualElement には、特別なコントロールなどの、追加の動作と機能を定義するいくつかのサブクラスがあります。VisualElement は子要素を持つ場合もあります。

UIElement を使用するために、VisualElement 基本クラスから派生させる必要はありません。スタイルシートとイベントコールバックを使って、VisualElement の外観と動作をカスタマイズすることができます。

Hiroki KodamaHiroki Kodama

ScrollView

https://docs.unity3d.com/Manual/UIE-uxml-element-ScrollView.html

ScrollView displays its content inside a scrollable area. When you add content to a ScrollView, the content is added to the content container (#unity-content-container) of the ScrollView.

ListView

https://docs.unity3d.com/Manual/UIE-uxml-element-ListView.html

A ListView is a vertically scrollable area that links to and displays a list of items.
Note: The horizontal and vertical Scroller elements are standard UI Toolkit Scrollers.

IMGUI Container

https://docs.unity3d.com/ScriptReference/UIElements.IMGUIContainer.html

Element that draws IMGUI content.
エディター拡張用IMGUIのラッパーであるという理解。

GroupBox

https://docs.unity3d.com/Manual/UIE-uxml-element-GroupBox.html

A GroupBox is a container element for a logical group of multiple visual elements
. You can use a combination of GroupBox and RadioButton if you want to have multiple groups of options in the same panel.

あまりVisualElementとの違いがわからないが、editor向けなのだろうか。

Hiroki KodamaHiroki Kodama

操作としてはUI BuilderでVisualElementでどんどん構造を作っていきつつ、レイアウトを整え、
共通化したい部分はスタイルを新規作成して、クラス名を新たに定義してVisualElementに個別にアタッチしていく形。レイアウトはFlexBox。Web開発に極めて近いが、エディターで直接コードを編集することはない。あくまでBuilder上で操作する。

Hiroki KodamaHiroki Kodama

UI Builder上のPreviewの画面解像度がGame Viewと異なるのが気持ち悪いので、どう調整するか調べる。

Hiroki KodamaHiroki Kodama

https://fabterrace.site/2022/04/04/unity-ui-toolkitに触れてみた/

今回は、キャンバスサイズを1280×720に設定し、UI画面を作成していきます。キャンバスサイズはUI Builderウィンドウにて、Sample.uxml要素を選択することでインスペクター上にキャンバスサイズが表示されるので、そちらから変更します。

Match Game Viewというトグルもあるので、とりあえず実解像度はこれで合わせられる。

Hiroki KodamaHiroki Kodama

https://forum.unity.com/threads/is-there-a-panelsettings-configuration-to-undo-retina-displays.1044373/

With a mobile device you usually want to go with "scale with screen size" for scale mode (at least for your HUD, probably some if not all menus) because that would make sure it works with all the form factors you need to support (you'd of course test out on either the Editor with those form factors on in actual devices). You'd use the "reference resolution" to make it scale and look good in all cases, including retina display. You can set multiple different resolutions on the Game View to test it out.

Hiroki KodamaHiroki Kodama
  • PanelSettingsのScale ModeScale With Screen Size
  • Reference ResolutionをGameViewのviewportに合わせたデバイスの論理ピクセルに
  • UI BuilderのHierarchy欄のルートを選択してSizeにデバイスの論理ピクセルを入力
  • Viewportの右上部分のプルダウンでUnity Default Runtime Themeを選択

これでGameViewのプレビューとUI Builderのプレビューが一致する。サクサクとUIを組む準備ができた。

Hiroki KodamaHiroki Kodama

https://blog.unity.com/ja/technology/ui-toolkit-at-runtime-get-the-breakdown

同じくこちらの記事で考え方は理解。UI Document Componentを持っているgameObjectはUIDocumentとしてスクリプトから参照できる。UIDocument.rootVisualElementでルート要素を取得し、.Query<T>("name")で特定の要素を取得できる。このへんの設計はまんまJavaScriptのDOM。

public class UIEventHandler : MonoBehaviour
{
   [SerializeField]
   private UIDocument m_UIDocument;
 
   private Label m_Label;
   private int m_ButtonClickCount = 0;
   private Toggle m_Toggle;
   private Button m_Button;
 
   public void Start()
   {
       var rootElement = m_UIDocument.rootVisualElement;
 
       // This searches for the VisualElement Button named “EventButton”
       // rootElement.Query<> and rootElement.Q<> can both be used
       m_Button = rootElement.Q<Button>("EventButton");
 
       // Elements with no values like Buttons can register callBacks
// with clickable.clicked
       m_Button.clickable.clicked += OnButtonClicked;
 
       // This searches for the VisualElement Toggle named “ColorToggle”
       m_Toggle = rootElement.Query<Toggle>("ColorToggle");
 
       // Elements with changing values: toggle, TextField, etc... 
// implement the INotifyValueChanged interface,
       // meaning they use RegisterValueChangedCallback and 
// UnRegisterValueChangedCallback
       m_Toggle.RegisterValueChangedCallback(OnToggleValueChanged);
 
       // Cache the reference to the Label since we will access it repeatedly.
       // This avoids the relatively costly VisualElement search each time we update
       // the label.
       m_Label = rootElement.Q<Label>("IncrementLabel");
       m_Label.text = m_ButtonClickCount.ToString();
   }
 
   private void OnDestroy()
   {
       m_Button.clickable.clicked -= OnClicked;
       m_Toggle.UnregisterValueChangedCallback(OnToggleValueChanged);
   }
 
   private void OnButtonClicked()
   {
       m_ButtonClickCount++;
       m_Label.text = m_ButtonClickCount.ToString();
   }
 
   private void OnToggleValueChanged(ChangeEvent<bool> evt)
   {
       Debug.Log("New toggle value is: " + evt.newValue);
   }
}
このスクラップは2023/02/10にクローズされました