コンテキストメニューからテクスチャの切り替えをする!【Resonite】
はじめに
この記事は基本的なResoniteの操作、Devtoolやインスペクターの操作がわかっている前提で書いていくので、もしまだDevtoolの使い方がよくわからん!という方は下記の記事を見たり、現地民に教えてもらうなどしてください。
また、かのんさんがコンテキストメニューについての記事をいくつか書いてくれているので、こちらも合わせて参考にしてください!
この記事でやりたいこと
先日くりねこちゃんのルームウェアを作成し、色違いのテクスチャをいくつか作ったので、コンテキストメニューから服の色を変えられたらおもしろいと思い作ってみることにしました。
簡単に説明すると、メニューの操作でマテリアルのテクスチャを差し変える、のような動作になるので、例えば看板の文字だったり、テクスチャで表現されるアバターの表情だったりも同じ方法で実装できます。
是非応用してみてください!

今回の記事で説明にお借りするアバター
今回使う服とカラバリ

では早速作っていきたいと思います!
設計図を作る
私はまだ頭の中でメニューの構想を考えながらコンポーネントを配置して設定して…みたいなことが出来ないので一旦図解にします。
今回はコンテキストメニューの中に「アバターメニュー」という大きな括りでメインメニューを作成し、その中に服のテクスチャを差し替えるサブメニューを作ることにしました。
将来的に表情変えたいな~とか、服の着せ替えしたいな~ってなった時に、後から増えるであろうサブメニューを「アバターメニュー」の下の階層に増やしていけるようにと思い、このような形に。

今回は記事のためにちゃんと書いたけど、自分用なら手書きのらくがきでもOK。わかればよい!
切り替えたいテクスチャに番号を振り分ける
というわけで設計図が出来たら早速メニュー作りの準備をしていきます!
順番はどっちでもいいですが、今回は一旦切り替えたいテクスチャを全部出して、番号を振り分けるところからやってみます。
テクスチャを変えたいマテリアルのスロットを見つける
アバターのインスペクターを開いて、rootスロットの一個下にあるCenteredRootというスロットを探します。
CenteredRootの階層を開いたら、さらに下のAssetsを開きます。

Assetsの下にある、Material:○○といったスロットがこのアバターのマテリアルです。

私の場合はさらにあとから着せた服のスロットを別途わけているのですが、このあたりの整理の仕方は好みなので今回はあまり気にせず、テクスチャの差し替えをしたいマテリアルのスロットが見つかればOKです。

目的のマテリアルのスロットを見つけたら開いておきます。
AssetMultiplexer<ITexture2D>をアタッチする
見つけたマテリアルのスロットに、AssetMultiplexer<ITexture2D>コンポーネントをアタッチします。
場所は Assets/Utility/AssetMultiplexer 内にあります。

コンポーネントをアタッチしたら、AssetMultiplexer<ITexture2D>のTargetにテクスチャを切り替えたいマテリアルを設定します。
マテリアルのコンポーネント内にあるMainTextureを掴んで、Targetのnullにレーザーを当てて手を離すと入ります。



⇑この操作はこの後も出てくるので覚えておきましょう。
テクスチャの画像を設定していく
続いて、3種類のテクスチャを一つのマテリアルに充てていきます。
コンポーネント下部にあるAddを押すと、なにやらテクスチャが入りそうな枠が増えます。
今回使うテクスチャは3種類なので、Addを3回押して、3つの枠を用意します。

入れたいテクスチャをResoniteにインポートします。
まとめてドラッグ&ドロップでOK。


先ほど作った枠にテクスチャを入れます。
この操作がちょっと癖つよなのですが、
テクスチャの画像をレーザーでグラブして、入れたい枠の向こうに画像を持ってきて、レーザーが枠を貫通する形でプライマリ。
デスクトップは常にカーソルにレーザーが出ているので、画像をグラブしたまま画像をインスペクターの奥に持ってきて、枠にカーソルを合わせてクリックでOK。

という感じで3種類のテクスチャをそれぞれの枠に入れました。
順番は好きな順でよいです。

このAssetMultiplexer<ITexture2D>が何をしているかというと、各テクスチャに番号を振って、同コンポーネント内Indexに入力された数値と同じ番号のテクスチャをマテリアルに割り当ててくれています。
なので、このIndexに入る数値を指定してあげればマテリアル内のテクスチャを切り替えることができるようになります。
ではどうやってこのIndexの数字を指定するのかというと、
今回はButtonValueSetというコンポーネントをコンテキストメニューに仕込んで、メニューをぽちぽち選択するとIndexに数値が入るようにします。
この辺の詳細は後ほど!
というわけでひとまずマテリアル側の設定は以上です!
お疲れさまでした。慣れない作業はMPを消費するので、ぼちぼち休憩しつつやりましょう。
このあたりで一旦バックアップに保存しておくのもいいですね。
次はコンテキストメニューの設定に移ります。
コンテキストメニューを作る
設計図通りに空のメニュー作りをしていきます。
一番上の階層を作る
まずコンテキストメニューを作るための子スロットを作成します。
アバターのルートの直下に空のスロットを作成してください。



ここのスロットに、メニューを作るコンポーネントを入れていきます!
今回入れるのはRootContextMenuItemとContextMenuItemSourceです。

両方とも、RadiantUI/ContextMenuの中に入っています。

次にContextMenuItemSourceを、RootContextMenuItem内Item:に入れます。
さっきのグラブしてレーザーあてて離すやつと同じやり方です。


ここまでやったら、一度アバターを着てコンテキストメニューを出してみましょう。
My Itemというメニューが増えているはず。

RootContextMenuItemはコンテキストメニューの一番上の階層に空のメニューを増やすコンポーネントで、ContextMenuItemSourceは増やしたメニューの名前や色なんかを設定してあげるコンポーネントです。
現在はContextMenuItemSourceのLabel:が「My Item」なので、同名のメニューが生えています。
今回は、この設計図通りにメニューを作りたいので、このLabelの欄を「アバターメニュー」にしておきます。


メニューの名前を変更できたら、一番上の階層は完成です!
下の階層を作っていく
続いて、さらに下に続くメニューを作っていきます。
サブメニューの作り方は簡単!
まずはRootContextMenuItemを入れたスロットにContextMenuSubmenuをアタッチ。
こちらのコンポーネントも RadiantUI/ContextMenu に入っています。

ContextMenuSubmenu内のItemsRootに上になる階層のスロットをつかんで入れます。


続いてコンテキストメニューの子スロットを作成。

作成した子スロットに先ほども使用したContextMenuItemSourceをアタッチ。

こうすることで、「アバターメニュー」を選択すると、さらに下に階層が出てくるようになりました!
Labelを変えてないので、今はまだ「My Item」としか出ないと思います。
このLabelも設計図通りに「服カラー」としておきましょう。
さらに下に階層を作りますが、これは先ほどやった手順と全く同じです。
上になるスロットにContextMenuSubmenuをアタッチし、ItemRootに上になるスロットを入れ、子のスロットを作成してContextMenuItemSourceをアタッチ。

服カラーの下の階層は3種類分のみっつ必要なので、子スロットも3つ作ります。


ついでにスロット名がややこしくなってきたので、メニューの名前に揃えておきます。
ここまで出来たら、一旦アバターを着てメニューの様子を見てみます。



もしここまででうまくメニューが動いてなければ、ContextMenuSubmenuのItemRootに直上のスロットが指定されているか、コンポーネントをアタッチするスロットが合っているか等を確認してみてください。
下記に、作ったスロットのコンポーネントの写真を載せていきます。
慣れないととてもややこしい作業なので、確認しながらゆっくり進めてください。






動作が問題なければ、ここらでバックアップに一旦保存するのもいいかもしれません。
適度に休憩もはさみながら進めてください。
作ったメニューをボタンにする
さて、ここまで作ったメニューですが、選択したときにマテリアルのテクスチャを差し替えてくれないと意味がありません。
そこで、ちょっとだけ先述したButtonValueSetを使います。
Common UI/Button Interactions/ButtonValueSet<T>の中に入っているButtonValueSet<int>を見つけてください。
仲間がいっぱいいますが、今回は末尾が<int>のコンポーネントを使います。
これは押すと値を書き込むボタンにしてくれるコンポーネントで、今回切り替えボタンになってほしいスロット、つまり一番下の階層のスロットすべてにアタッチします。

最下層のすべてのスロットにコンポーネントがアタッチできました。

続いて、各スロットのボタンと、最初に設定したテクスチャの番号を紐づけていきます。
ButtonValueSetのSetValue:に書き込む値、TargetValue:に値を書き込みたい欄を設定します。
今回の場合だと、
紺×白のテクスチャは2番なので、紺×白のスロットのSetValue:には2を入力、TargetValue:にはAssetMultiplexer<ITexture2D>のIndexを入れます。

こうすることで、
メニューの紺×白を押す
⇓
ButtonValueSetによってAssetMultiplexer<ITexture2D>のIndexの値が2になる
⇓
マテリアルのテクスチャが2番(紺×白)のテクスチャに差し変わる
⇓
アバターの服の色が紺×白になる
というわけです。
他の色も同じようにやってみます。


すべてのスロットのButtonValueSetを設定できたら、アバターを着てメニューをぽちぽちしてみます。



メニューの色を押すと、その色に服の色が変わるようになりました!!!
やったー!!!
変更したいマテリアルが一つだけなら、ここで完成になります!
ですが、この服はトップスとボトムスでマテリアルが分かれている(なんで?)ので、ボトムスの方も連動して変わるように設定します。
といっても、トップスとほぼ同じ作業をするだけです。
ドルフィンパンツのマテリアルのスロットにAssetMultiplexer<ITexture2D>をアタッチして、Targetとテクスチャ3種を設定。

コンテキストメニュー最下層のスロットにButtonValueSet<int>を増やし、TargetValueにマテリアル側のIndexを入れ、SetValueに対応するテクスチャの番号を入力。

これで、メニューを押すとトップスの色変えボタンと、ボトムスの色変えボタンを同時押ししているような形になりました。
実はさっきの写真ではドルフィンパンツの色が変わっていませんでしたが、これでトップスとボトムスの色をそろえて変更することができるようになりました。



改変後のアバターを忘れずにインベントリに保存したら完成です!
おわり
思ったよりもかなり長い記事になってしまいましたが、ここまでお付き合いいただきありがとうございました!
もし変わらないところやつまづいたりしたときは、れぞ民か私までお気軽に質問しに来てください!
それではまたResoniteでお会いしましょう!

