自己紹介
とある事情で様々な方とお会いしてUnityモチベーションえぐい大学生。
これについても許可が出れば記事にします!
本記事の趣旨
App UIに入門するにあたって、サンプルコードを読もうと思ったので、ついでに記事を書く。
全体の概要を掴みつつ、少し機能に触れていこうと思う。
もととなるUI Toolkitに関しては触れないこととする。
App UIとは
突如として界隈でちょこっと有名になったUI Toolkitベースの公式UIフレームワーク。
ランタイム・エディター拡張ともに対応しており、テーマも複数あるなど今までのUnityとは思えない雰囲気。
Drag and Dropとは
App UIのサンプルプロジェクトの1つ
このような見た目でItem0を除いて全ての要素がドラッグアンドドロップできるUIを実現している。
サンプルコードを読む
始める前に少し言わせてほしい。なぜDragAndDropSampleScript
のStart
メソッドはコンストラクタではいけないのだ…
GridView
まず最初に、目につくのがGridViewというVisual Elementだろう。
これは「項目リスト」「表示項目の見た目を制御するメソッド」「実際の値を入れるメソッド」の3つを持つ。
今回のサンプルでは
今回のサンプルでは以下のような関数が使用されていた。
static VisualElement MakeItem()
{
Debug.Log("Make");
var item = new VisualElement();
item.AddToClassList("dnd-item");
var text = new Text();
text.AddToClassList("dnd-item__label");
item.Add(text);
return item;
}
void BindSrcItem(VisualElement el, int idx)
{
Debug.Log("Bind");
var item = (Text)el.ElementAt(0);
item.text = (string)m_SrcList.itemsSource[idx];
}
その他の機能
ドラッグの検知や複数個同時選択などの機能があるようだ。
ドラッグに関してはdragCanceled
というイベントがあったがどうあがいても実行されなかった。
気になったところ
ドラッグアンドドロップするたびに全てのVisual Elementが再描画され上記2つのメソッドも呼び出されていた。
私もUI Toolkitがそこまで詳しくないためどこの仕様なのか分からないが、ちょっと気になった。
また、ドラッグアンドドロップで移動したのち選択が残るという挙動に違和感を覚えた。
DropZone
こちらはDropする挙動を設定できるVisualElementのようだ。
Dropされようなとき(dragStarted
)Dropされたとき(dropped
)Dropされた後処理(dragEnded
)がある。
今回のサンプルでは
void OnDropped(IEnumerable<object> objects)
{
var selection = objects.Where(o => o is string).Cast<string>().ToList();
if (selection.Count == 0)
return;
// Add dropped items to the destination list
var dstItems = new List<string>(m_DstList.itemsSource?.Cast<string>() ?? Enumerable.Empty<string>());
dstItems.AddRange(selection);
m_DstList.itemsSource = dstItems;
// Remove dropped items from the source list
var srcItems = new List<string>(m_SrcList.itemsSource?.Cast<string>() ?? Enumerable.Empty<string>());
foreach (var item in selection)
{
srcItems.Remove(item);
}
m_SrcList.itemsSource = srcItems;
// Hide the dropzone if the destination list is not empty
m_Dropzone.visibleIndicator = m_DstList.itemsSource != null || m_DstList.itemsSource.Count == 0;
}
void OnEditorDragStarted()
{
// Accept every path from the editor
m_Dropzone.visibleIndicator = true;
m_Dropzone.state = DropZoneState.AcceptDrag;
}
void Reset()
{
m_Dropzone.state = DropZoneState.Default;
m_Dropzone.visibleIndicator = m_DstList.itemsSource == null || m_DstList.itemsSource.Count == 0;
SetDraggedObjects(null);
}
さいごに
App UIなんもわからんという状態からこの記事を書いているので全然深く掘れなかったのですが、なんでこんな書き方してるんだろうと思うとこともちらほらあったり。
もうちょっと洗練されたコードも書けそうな気がしたので、今後機会があればまた記事にしたいと思います。
今回はDropZoneがあるということが既に結構大きい発見でした。
App UIの開発はイベントを登録していく形でとてもWeb風だなと、流石UI Toolkitや!!