今日から始める!TouchDesigner UI構築
TouchDesignerは高い柔軟性から、多くのクリエイターに愛用されているビジュアル構築ツールです。しかし、アウトプットだけを重視すると、実際の運用で必要となるUIの操作性や視認性が後回しになりがち。
本記事ではメディアプレイヤーの作成を例に、あらゆるプロジェクトへ応用できるUI構築の実践テクニックを解説します。
デザインと機能を両立させるノウハウを、初心者の方にもわかりやすく紹介しているので、ぜひ参考にしてみてください!
本記事はTouchDesigner Advent Calendar 2024の16日目の記事です。
今回のゴール
メディアプレイヤー
選択した映像を再生・停止できる
各クリップのサムネイルを表示する
サンプルプロジェクト
TouchDesigner 2023.11340で作成しています。
概要:忙しい人はここだけでOK!
Container COMPによるレイアウト設計
Layout Modeの使い分け(Fixed, Fill など)やMargin/Spacingの設定が重要。
ChildrenのAlignをTop to BottomやLeft to Rightに切り替え、パネル内のUI要素を並べる。
Lookで薄く色を付けておくと配置が分かりやすい。
幅やマージンは 8の倍数 を使うとレイアウトを管理しやすい。
replicator COMPの活用
同じパーツの大量複製に最適。オペレーター数が動的に増減するケースにも対応しやすい。
folder DAT と組み合わせることで、フォルダ内のファイルをまとめてUIに反映可能。
me.parent().digitsが便利。
replicator callbacks を用いて、複製直後にdisplayをOnにしたり、CHOPへ自動接続するなど処理を仕込める。
Button Groupとラジオボタン化
Button Group DAT と opFind DAT を活用し、ボタン同士の連動を作成(ラジオボタン形式)。
fan CHOP を使って選択中ボタンのインデックスを取得し、ファイル選択やプレビュー表示を連動させる。
UIパーツのカスタマイズ
TouchDesignerの Palette にある BasicWidgets(masterButton など)を使うと、デフォルトButtonより柔軟なカスタマイズが可能。
LookやBorder設定、Face Color、フォントなどを組み合わせて、使いやすく見栄えのいいボタンを作る。
サムネイルの作成
Movie File In TOP を使いつつ、メモリ効率のために低解像度読み込み&Playをオフに。
インデックス位置をトリムして、黒や単色シーンが目立たないフレームをサムネイルにする。
プレビュー画面と操作部の実装
OPviewer COMP とレイアウト設定(Fixed Aspectで16:9など)で画面プレビューを配置。
info CHOP で動画の再生状況(index_fraction)を取得し、シークバー風に表示。
materialDesignIcons フォントを活用し、再生・停止ボタンなどをアイコンベースで作成。
パネルのレイアウト
TouchDesignerでUIを作成する際、最初に重要なのは「全体像をざっくりとイメージすること」です。細かい部分に取り掛かる前に、まずは全体のレイアウトを設計しましょう。
Container COMP
UIを作成する際には主にContainer COMP を使用します。
最低限知っておきたいContainer COMP の重要パラメータ
Layout:パネルの配置やサイズ等を設定する
Width / Height:パネルの 幅 / 高さ
HorizontalMode / Vertical Mode:パネルの 幅 / 高さ をどのように決めるか
Fixed Width / Height:上述のWidth / Height の値に準じる
幅や高さを数値指定したいときに使う
デフォルトだとこれ
修正しにくくなるのであまり使いたくない
Fill:親要素のサイズに準じる
基本これを使用している
同階層に子要素が複数ある場合は等幅で分割される
分割される割合を別途指定することもできる
Horizontal / Vertical Fill Weight
Align Order:他の子要素に対する並び順の優先順位
同階層に子要素が複数ある場合に数字が若い順に上位に来る
-1等の負の数を設定することもできる(0より優先される)
優先度をさらに高めたい場合に活用するテクニック
同じ優先度のものが複数ある場合はオペレーターの名前順になる
Children:自身の子要素をどのように配置するかを設定する
Align:子要素をどのように配置するか
None:並べずに重ねる
Top to Bottom:上から下に並べる
Left to Right:左から右に並べる
Spacing:子要素同士の隙間
Margin:親要素に対するマージン(隙間)
マージンやスペースを適切に設定すると良い感じになります。
関係が近い要素は近づけ、関係が遠い要素は離しましょう。
また、こだわりがなければサイズやマージンは8の倍数に設定することをお勧めします。
これにはいくつかのメリットがあり、
多くのディスプレイは解像度が8の倍数になっているため綺麗に割り切れることが多い
マージンを10にするか11にするか(それとも12?13?)だと迷いが生まれるが、8にするか16にするかだと判断が速いから
等があげられます。おすすめです。
Lookで色を付けるとわかりやすい
ボタン等のUIパーツがない状態でパネルを配置していると、なにがどこに配置されているのかが分からなくなります。
そういう時には、LookタブのBackground Color と、BackgroundAlphaを設定すると、並び順やサイズが正しく設定されているかを確認することが出来ます。
レイアウトしてみる
project1:container COMP
Children
Align:Top to Bottom
Margin:8, 8, 8, 8
layout:container COMP
Layout
HorizontalMode:Fill
Vertical Mode:Fill
Children
Align:Left to Right
select_buttons:container COMP
Layout
HorizontalMode:Fill
Vertical Mode:Fill
preview:container COMP
Layout
HorizontalMode:Fill
Horizontal Fill Weight:2
Vertical Mode:Fill
Align Order:1
footer:text COMP
Layout
HorizontalMode:Fill
Height:24
Align Order:1
replicator COMP の実践的な使い方
UIを作成していると、同じパーツがたくさん必要になることがよくあります。
今回の場合は、各クリップを選択するボタンがそれにあたります。
Container COMP を複製しながら作成しても良いですが、変更が生じた際に複製しなおさなければならなかったり、途中で要素数を動的に変更したい場合等に対応できません。
そのようなときに、TouchDesignerでは replicator COMP を使用します。
これを機に使い方を覚えてしまいましょう。
まずは先ほど作成した select_buttons オペレーターに入ってください。
folder DAT
特定のフォルダのファイルをを一括で読み込みたいときにはfolder DATを使用します。
Folder
Root Folder:動画ファイルがあるパスを設定
Basic Widgets
通常GUIを作成する際はbuttonCOMPや、sliderCOMPを使用するかと思うのですが、実はデフォルトのそれらのCOMPはあまり使い勝手がよくありません。
PaletteのBasicWidgetsに便利にカスタマイズされたUIパーツ集があるので、そちらを使います。
button COMP と masterButton の比較
masterButtonでは、デフォルトでOnの時とOffの時の色やテキストをそれぞれ設定することが出来ます。また、他にもフォント等の様々なパラメータを下の階層に入らずに設定することが出来ます。
masterButtonをPaletteから配置したら、(後続の処理のために)masterButton1にリネームしておきましょう。
また、パラメータも設定します。
Layout
HorizontalMode:Fill
Height:24
replicator COMP
Replicator
Replication Method:By Number
複製する方法:数字
Number of Replicants:op('folder1').numRows - 1
複製する数:op('folder1')の行数-1
タイトル行を抜くため-1している
Master Operator:masterButton1
複製元にするオペレータ:masterButton1
Layout:Vertical
複製したオペレータのレイアウト:垂直
グリッドより縦に並んでた方が見やすい気がするので垂直にしています。グリッドのままでも問題ありません。
ここまで設定出来たら親COMPのselect_buttonsオペレータを
Children
Align:Top to Bottom
に設定します。
Master Operator は非表示
select_buttonsオペレータを見てみると、動画ファイルが3つしかないはずなのに、ボタンが4つ表示されています。
これは、Master Operatorも表示されてしまっているためです。
そこで、Master OperatorのPanelのdisplayをOffにし、非表示にしておきましょう。
(Number of Replicants を op('folder1').numRows - 2にしてReplicants Suffix Start を2にする方法もありますが、それだとファイルが0個の時にもボタンが残ってしまうため個人的には非推奨です。)
ですが、このままではreplicatorで複製した際に、複製したオペレーターも非表示になってしまします。
replicator callbacks
そこで使用するのが replicator COMPの下にくっついているreplicator callbacksです。
なにやら文字がたくさん書いてあってとっつきにくいですが、使い方を覚えればとても便利です。
replicator callbacksは、replicator COMPを使用してオペレーターを複製した際にその複製したオペレーターに対してどのような処理を行うかを書くことが出来ます。
早速使ってみましょう。
コメントアウトされている(#が先頭についている)
c.par.display = 1
上記の行の先頭の#を削除し、コメントアウトを解除してください。
この状態で再度複製すると、displayがonになった状態で複製されます。
これは、オペレーターが複製された後に、
複製されたオペレーターのdisplayパラメータに1を代入
という処理が行われたためです。
複製した際に自動で接続
もっとダイナミックな処理も書くことが出来ます。
後段にmerge CHOP を配置し、
c.outputConnectors[0].connect(op('merge1'))
と記述してください。
そして、再度複製してみると、複製したオペレーターが自動的にmerge1オペレーターに接続されたと思います。
この処理はreplicator COMPを使用する際はほとんどセットで使用するため、是非どこかに保存しておいてください。
Button Group
現状、これらのボタンはそれぞれ独立して動作しています。
しかし、メディアプレイヤーとして使用する場合は、あるボタンが押された場合それまで選択されていたボタンの選択は解除されなければなりません。
このようなボタンをラジオボタンといいます。
ラジオボタンを作成する際にはButton Groupというものを設定する必要があります。
今回はopFind DATと組み合わせて使ってみましょう。
まず、opFind DAT を配置し、FamiliesをPanel COMPのみOnにします。
次にColumnsをPathのみに設定します。
設定出来たらmasterButton1オペレーターのButton Group DAT にopfind1を設定します。ButtonのTypeをRadio Button に変更し再び複製します。
先ほどまで独立して動作していたボタンがラジオボタンとして機能するようになりました。
fan CHOP
merge CHOP からの入力をインデックスに変換するためにfan CHOP を使用します。Operation を Fan In に設定することで、複数チャンネルの入力をインデックスに変換することが出来ます。
null CHOP に接続し、select DAT で選択したファイルを抽出します。
me.parent().digits
次に、ボタンの見た目を設定していきます。
まずOnの時とOffの時のカラーを好きに変更してください。
次に、LookでBorderを設定して下さい。
Border A Alphaに、
me.par.Value0
と記述してください。ボタンがOnの時だけ枠線がつきます。
Panel
Display:Off
パネルの非表示
Look
Border A:好きな色
枠線の色
Border A Alpha:me.par.Value0
枠線の透明度
Left/ Right/ Bottom/ Top Border:Border A
Border Over Childrn:On
枠線を前面に表示
Button
Off Face Color:0, 0, 0, 0
Offの時のボタンの色
Background TOP を表示したいため透明にしておく
On Face Color:0, 0, 0, 0.8
Onの時のボタンの色
Background TOP を暗くしたいため、黒を透明度0.8にしておく
Off Font Color:1, 1, 1, 1
Offの時の文字色
On Font Color:好きな色
Onの時の文字色
Align Horizontal:Left
水平方向の整列:左寄せ
Offset:4, 0
文字のオフセット
次に、ボタンのテキストをファイル名にします。
ボタンの中の階層に入りin DAT を配置します。
1階層上のfolder1オペレーターを入力し、
select DATを繋ぎ設定します。
Select
Include First Row:On
先頭行を含む
ラベルを表示しておきたいのでOnにする
Select Rows:by Index
選択形式
インデックスによる選択
End Row Index:-1
終了行のインデックス
-1に設定することで、開始行で選択した行のみを抽出することが出来る
Start Row Index:me.parent().digits
開始行のインデックス
この記述もreplicator COMP を使用する際に頻出です。
親オペレーターのdigits(末尾の数字)を参照します。
replicator COMP で複製されたオペレーターは末尾の数字が連番で複製されるため、このような処理をすることですべてのファイルを個別に抽出することが出来ます。
null DAT を接続し、オペレーター名を movie_info としてください。
様々な箇所に参照するようなオペレーターは名前を付けておくと処理の流れが追いやすくなります。
また、参照先の"op('movie_info')[1, 'name']"のような記述を見るだけで、映像の情報の名前を参照しているんだなと分かります。
("op('null')[0, 1]"では何を参照しているかわからないので、参照元のノードを確認しに行く必要があります。)
1階層上に戻ってボタンのラベルを設定します。
Button
Off Label:op('./movie_info')[1, 'name']
ボタンがOffの時のラベル
op('./movie_info')のように書くと1階層下のオペレータを参照できる
table DAT class のオペレーターは[1, 'name']のように、数字で指定するとインデックス、文字を指定するとラベルで参照してくれる
On Label:me.par.Buttonofflabel
On の時と Off の時でラベルを変える必要がないので自身のOff Labelを参照しておく
サムネイルの作成
次にサムネイルを作成していきます。
映像を選ぶ際に便利なサムネイルですが、いくつか注意すべき点があります。
TouchdesignerのTOPは配置するだけでGPUのメモリを消費するので、無計画に配置しすぎるとメモリを圧迫し、著しくパフォーマンスの低下を引き起こす場合があります。
そこで、出来るだけ低い解像度で読み込む必要があります。
また映像が再生されてしまうのも毎フレームデコードが行われ、パフォーマンスの低下を招くためPlayをオフにしておきます。
以上の点に注意してこのようなサムネイルを作成してみました。
Movie File In TOP:moviefilein1
Play
File:op('movie_info')[1, 'path']
Reload:On
Play:Off
Common
Output Resolution:Fit Resolution
Resolution:me.parent().width, 100
ramp TOP:ramp1
Ramp
右半分が不透明になるように設定
色は白
Output
Operation:Atop
Swap Order:On
constant TOP:constant1
Constant
Alpha:0
Common
Resolution:me.parent().width, me.parent().height
over TOP:over1
Transform
Pre-Fit Overlay:Native Resolution
Justify Horizontal:Right
null TOP:bg
かなりいい感じになってきました!
しかし、よく見てみると2番目や7番目のサムネイルが黒くなってしまっています。
これは動画の開始フレームが黒のためです。
汎用素材ではあまりありませんが、MVやポン出しの素材では黒(等の単色)からフェードインで映像が始まることも少なくありません。
そこで、動画の再生してから20%程度の部分をサムネイルとして読み込みましょう。
Movie File In TOPで、TrimタブのTrimをOnにして、Trim Startを0.2にして複製しなおします。
左が開始フレームで、右が開始後20%部分のサムネイルです。右の方が視認性がかなり向上しているのではないでしょうか?
また、大量のreplicatorを複製する際に、フリーズしてしまうことがあるかもしれませんが、replicator COMPの、Incremental UpdateをOnにし、数を1にすると、1フレームに1個づつ複製され、負荷が分散されるのでフリーズを軽減することが出来ます。
プレビュー画面と操作部
映像選択部分が完成したので、次はプレビュー画面と再生ボタン等の操作部を作っていきましょう。
パネル右側のオレンジ色の部分を作成していきます。
select_buttonsパネルで選択した動画のパスを、in/out DAt を使用してpreviewパネルに入れます。
Movie File In TOP にパスを参照させnull TOP を繋いでおきます。
次にパネルに表示するためにOPviewer COMP を配置し、null TOPを参照します。
ファイル名を表示するためにtext COMPも配置して、ファイル名を参照させておきましょう。
親コンテナのChildrenのAlignをTop to Bottom に設定し、SpacingとMarginをそれぞれ16に設定しましょう。
また、先ほど配置した2つのCOMPのレイアウトを適切に設定しましょう。
この時の、OPviewer COMP のレイアウトですが
Layout
Horizontal Mode:Fill
Fixed Aspect:Use Horizontal
Aspect Ratio:16/9
に設定すると、横幅が親コンテナいっぱいになり、アスペクト比が16:9のビューワーを作成することが出来ます。
info CHOPから情報を反映
動画の再生位置を表示するためのインジケーターを作成しましょう。
info CHOP を使えば、参照したオペレーターの様々な情報を取得することが出来ます。
動画の再生位置は index_fraction にあたるので、Scopeでindex_fractionを指定しましょう。
後段にnull CHOP を接続しておきます。
次に表示部分を作成します。
OPviewer COMP を配置し、レイアウトを設定します。
次に表示用のrectangle TOP を配置しnullTOPに接続しておきます。
rectangle TOP のパラメーターを以下のように設定します。
Rectangle
Size:op('null3')['index_fraction'], 1, Fraction
幅に先ほど取得したindex_fractionを参照させる
Justify Horizontal:Left
fill color:好きな色
Common
Resolution
op('opviewer2').width
op('opviewer2').height
materialDesignIcons
次に再生と頭出しのボタンを作成します。
先ほど同様にmasterButton をPaletteから2つ配置しましょう。
上位のcontainer COMPを作成し接続しておきます。
それぞれのレイアウトを適切に設定します。
上のボタンが頭出し、下のボタンを再生停止のボタンとしましょう。
この時点でこのようなレイアウトになっているかと思います。
頭出しと、再生停止ボタンを「CUE UP」「PLAY/STOP」のように書いても良いですが、今回は materialDesignIcons を使って、アイコンで表現したいと思います。
Palette > Tools > materialDesignIcons を選択し、ネットワークエディタの適当な場所に配置してください。
このようなアイコンがたくさん並んだパネルが表示されると思います。
これらは、materialDesignIcons というもので、アイコンをフォントとして提供しているものになります。TouchDesignerには、デフォルトでmaterialDesignIcons のフォントが入っているので、text TOP や、text COMP等で簡単に利用することが出来ます。
試しに、masterButton のフォントをmaterialDesignIconsに変更し、テキストを chr(0xF0663) に変更してみましょう。
これは、先ほどのmaterialDesignIconsパネルをアクティブにし、使いたいアイコンをクリックするとクリップボードにそのアイコンの文字コードがコピーされます。
このように、簡単にアイコンを設定することが出来ます。
あとは、再生停止ボタンも同様に設定し、出力をMovie File In TOP に割り当てます。
最後にパフォーマンス表示用のフッターを設定したり、プレビュー用で設定していた各container COMP のLookを調整して完成です!
まとめ
今回はTouchDesignerのUI構築について少し実践的な内容を紹介しました。
TouchDesignerのUIに関する記事は基礎的なものが多い印象があるので、こうした実用的なテクニックを整理できてよかったと思います。
今回紹介したテクニックは、どんなプロジェクトにも応用可能です。
ぜひ自身の作品に取り入れて、より快適でかっこいいUIを追求してみてください!
最後まで読んでいただきありがとうございます!
今回の内容には入りきらなかったのですが、シークバーまで実装したものを置いておきます。