clusterのTextViewのあれこれ
こんばんわ きえらです。
最近ベータ版だったいくつかの機能が正式版になりましたが、その中で「テキスト入出力」について少し書いていこうと思います。
基本的な使い方
テキスト出力
テキスト出力(表示)は、unityで空のGameObjectをつくりTextViewコンポーネントを追加すればよいです。後は文字サイズとか位置とか色の調整をすれば大丈夫だと思います。
テキスト入力
テキスト入力のフォームを出すには、ClusterScriptのrequestTextInputを使います。例えば、インタラクトして入力フォームを出すならこんな感じのスクリプトを書きます。
///<reference types = "@clustervr/cluster-script-types"/>
const meta = "ask_name";
const output = "あなたのお名前は?";
$.onInteract(player => {
try {
player.requestTextInput(meta, output);
} catch (e) {
// 例外処理
// $.log(e);
}
})
try〜catchで囲ってるのは、制限でrequestTextInputがエラーになる場合があるので一応入れています。エラーが出たときとか(フォーム表示されないとき)に、何かしたいときはcatch{}の中に書いたりします。しないなら書かなくても…。詳しくはドキュメントを見てください。
※ 特に30m離れるとエラーでフォーム表示されないっぽいので、アイテムによっては注意した方がよいです。
テキスト入出力
入力フォームに書いた内容を受け取るのは$.onTextInput、出力用TextViewのテキストを変更するにはsetTextを使います。
「インタラクトで入力フォームが出て、入力したテキストが表示される」みたいなのを作るならこんな感じでできます。
<ヒエラルキー>
TextViewSampleObj : Item、 Scriptable Item コンポーネント追加
-- TextView : TextViewコンポーネント追加
-- Cube : Boxコライダー追加(インタラクト用)
///<reference types = "@clustervr/cluster-script-types"/>
const view = $.subNode("TextView"); // TextViewコンポーネントがついたオブジェクトの名前
const requestMeta = "ask_name"; // 文字列いれておく (requestTextInputを識別するために使う)
const output = "あなたのお名前は?";
$.onTextInput((text, meta, status) => {
switch (status) {
case TextInputStatus.Success:
if (meta == requestMeta) {
view.setText(text); // 入力したテキストを表示
}
break;
case TextInputStatus.Busy:
// プレイヤーが文字列の入力ができない場合
break;
case TextInputStatus.Refused:
// 拒否された場合
break;
}
});
$.onInteract(player => {
try {
player.requestTextInput(requestMeta, output);
} catch (e) {
// $.log(e);
}
})
こんな感じで、テキスト入出力はできます。
いろんな使い方
入力した文字が◯◯ならXXする
入力文字によって何かしたいなら、onTextInputの中で判別すれば良さそうです。
*) 入力が指定した複数の単語と、完全に一致しているかどうか
const defArr = ["red", "blue", "green"]; // 指定したい単語の配列
・・・(省略)・・・
case TextInputStatus.Success:
if (meta == requestMeta) )
if (defArr.includes(text)) {
// 入力文字がdefArrの中に入っているときの処理を書く
}
}
break;
・・・(省略)・・・
何かの単語の選択式とかで、入力してほしいときに使えるかもです。
*) 入力が1のときは☓☓、2のときは□□する
const defArr = [1, 2];
・・・(省略)・・・
case TextInputStatus.Success:
if (meta == requestMeta) )
switch (Number(text)) {
case defArr[0]:
// 入力文字が1のときの処理を書く;
break;
case defArr[1]:
// 入力文字が2のときの処理を書く;
break;
}
}
break;
・・・(省略)・・・
数字の選択式で、入力してほしいときに使えるかもです。
このあたりはjavascriptのif・switch文などの分岐処理と文字列の比較とかで調べればいろいろできそうです。
文字のサイズを変える
setTextXXXでサイズやフォーマットは変えられます。例えば「インタラクトでサイズとフォーマットが変わる」のは、こんな感じで書けます。
const view = $.subNode("TextView");
$.onInteract((player) => {
view.setTextSize(0.1);
view.setTextAlignment(TextAlignment.Left);
view.setTextAnchor(TextAnchor.UpperLeft);
})
文字の色を変える
setTextColorで文字の色も変えられます。例えば「インタラクトで文字が赤に変わる」のはこんな感じで書けると思います。
const view = $.subNode("TextView");
$.onInteract((player) => {
view.setTextColor(1, 0, 0, 1); // 赤色
})
0〜1の値をいろいろ変更すれば、文字色/透明・不透明も変えたりもできそうです。
直接色を指定したい場合、RGBA値(0〜1の範囲)だと設定しにくいので、6〜8桁のカラーコード(#FF00FF etc)で指定できるようにするなら、こんな感じでできそうです。
const view = $.subNode("TextView");
$.onInteract((player) => {
let hex = "FF0000"; // 赤色のカラーコード
// 10進数のRGBA値(0〜255)に変換して、decArrに配列でいれる
let decArr = hex.match(new RegExp(/.{1,2}/g)).map(v => parseInt(v, 16));
// RGBA値(0〜1)の範囲でマッピング
let rgbArr = decArr.map(v => parseFloat(v / 255));
view.setTextColor(rgbArr[0], rgbArr[1], rgbArr[2], !rgbArr[3] ? 1 : rgbArr[3]);
})
※ カラーコードは16進数(0〜F)が並んでできているので、それを2桁ずつ区切って10進数に変換してRGBA値(0〜255)で表すようにして、setTextColorの0〜1の範囲にしてsetTextColorに入れています。
ちなみにこんな感じのを組み合わせて作ったのが、ストアに上げている説明ボードです。
さいごに
テキスト入出力で今までよりできることが増えたと思うので、良ければ参考にしてみてください。
※ コードなどは自由に使ってもらって良いですが、不備などがあっても一切の責任は取りません。
※ リトライの処理とかは少しコードが長くなるため、この記事内では記述していないです。