「Control」もかなり重要な基本ノードなので早めに触ってみたら、見えているものだけがゲームではないことを理解できた

Node解説

今回はControlを触ってみました。これまで扱ったLabelやButtonは、どちらもControlを継承したノードです。いわばUI用ノードの共通の土台にあたるので、単体で置いたらどうなるのか一度確かめておきたいと思っていました。

先に感想を書いておくと、Control単体は本当に何も表示されません。そのかわり、見えないままマウスの操作だけはしっかり受け止めていて、置き方によってはボタンが押せなくなることが分かりました。

まずはControlを1つだけ置いて、サイズを広げてみた状態です。

Controlを1つだけ置いて選択した状態のエディタ画面。オレンジ色の枠と赤いハンドルだけが表示されている
Controlを選択した状態のエディタ。オレンジの枠とサイズ変更用のハンドルが表示されます。

エディタでは選択しているあいだだけオレンジの枠が出ますが、枠の中には何もありません。Labelなら文字、Buttonならグレーのボックスがありましたが、Controlはインスペクターを見ても、文字や背景色を設定する項目がありませんでした。この状態で実行してみます。

Controlだけを置いて実行した画面。灰色の背景だけで何も表示されていない
実行した画面。Controlを置いた場所にも何も映っていません。

あたりまえですが、実行すると何もない灰色の画面でした。デフォルトの背景色がそのまま見えているだけで、どこにControlがあるのかはまったく分かりません。見た目に関与するノードではないことはよくわかったので、次はButtonと組み合わせて試してみました。

Buttonを置き、その上に同じくらいの大きさのControlを重ねます。Godotではシーンツリーで下に並んでいるノードほど手前に描かれるので、ButtonのあとにControlを並べました。

シーンツリーでButtonの下にControlを並べ、Buttonの上にControlを重ねた状態のエディタ画面。Buttonだけが見えている
シーンツリーではButtonの下にControlを置いています。エディタ上で見えるのはButtonだけです。

エディタで見ても、見えているのはButtonだけです。Controlを選択していないと枠も出ないので、ここにControlが重なっていることは、シーンツリーを見ないと気づけません。

この状態で実行して、ボタンにマウスを乗せてみました。すると、ボタンの見た目が何も変わりません。普通はマウスを乗せるとボタンの背景が少し明るくなるのですが、その反応がありませんでした。マウスを乗せた反応すら届いていないので、クリックも届いていないはずです。見えないUIが手前にあって、奥のボタンにマウスの反応が届かない、という方がイメージしやすいでしょうか。

ControlのMouse Filterという設定で、マウスを反応させることは出来ました。インスペクターのMouseの項目にあり、デフォルトは「Stop」になっています。Stopは、マウスの入力を自分で受け止めて、後ろのノードには渡さない設定です。見た目は透明でも、マウスから見るとボタンの前に一枚の板が立っているような状態だったわけです。

そこでMouse Filterを「Ignore」に変えて、同じようにマウスを乗せてみました。

Mouse FilterがStopとIgnoreのときにボタンへマウスを乗せた状態の比較。Ignoreの方はボタンの背景が明るくなっている
どちらもボタンにマウスを乗せた状態です。左のStopは反応がなく、右のIgnoreはボタンが明るくなっています。

Ignoreにすると、今度はボタンの背景が明るくなりました。Controlがマウスを素通りさせるようになり、後ろのButtonまで入力が届いたということですね。実際はUI画面の向こう側のゲーム画面を触らせたくはないと思うので、Stop設定がデフォルトなんでしょうね。

ちなみに、シーンツリーの順番を逆にしてControlをButtonより上に並べた場合は、Mouse FilterがStopのままでもボタンは普通に反応しました。この場合はButtonのほうが手前にあるので、Controlまでマウスの入力が回ってこないのだと思います。見た目の重なりだけでなく、マウスの入力をどちらが先に受け取るかも、ツリーの順番で変わるのは覚えておきたいポイントです。

Mouse Filterにはもう一つ「Pass」という選択肢もありますが、今回は試していません。

実際のゲーム作りで考えると、これはかなりハマりそうな仕様です。たとえばUIをまとめるために、画面全体の大きさのControlを親として置いておくのはよくある形だと思います。そのままだと、後ろにあるボタンやゲーム画面へのクリックを受け止めてしまいそうです。テストプレイで「なぜかボタンが押せない」となったとき、原因が目に見えないノードだと探すのに時間がかかりそうですね。ボタンが反応しないときは、手前に透明なControlが重なっていないか、Mouse Filterが何になっているかを確認する、というのを覚えておこうと思います。

逆に考えると、この性質には使い道もありそうです。会話ウインドウやポーズメニューを開いているあいだ、後ろのボタンを押されたくない場面では、画面全体に透明なControlを1枚置いておくだけでクリックを止める壁になってくれます。見た目を持たないノードなので、デザインに影響しないのもちょうどいいですね。

Controlには、位置やサイズを「アンカー」で決める仕組みもあります。こちらはゲームUIを作ってみた記事で試しているので、今回は触れていません。LabelやButtonで使っていた機能の多くは、このControlから受け継いだものなので、地味ですが重要なノードだと感じました。

単体では何も映らないので最初は拍子抜けしましたが、「見えないのにクリックは受け止める」という性質は、知らないと原因が分からずに悩みそうなポイントでした。UIを重ねて作るときは、Mouse Filterの設定を意識しておこうと思います。

関連記事

コメント