解説
今回は三つのフォームのうち、ModalFormの解説をしていきます。

早速次のようなフォームを作ってみましょう。

import { world } from "@minecraft/server";
import { ModalFormData } from "@minecraft/server-ui";
world.afterEvents.itemUse.subscribe(ev => {
const player = ev.source;
const itemStack = ev.itemStack;
// アイテムの種類がダイヤモンドの場合
if (itemStack.typeId === "minecraft:diamond") {
// モーダルフォームを定義
const form = new ModalFormData();
// タイトル
form.title("タイトル");
// トグル (ラベル,初期値)
form.toggle("トグル", false);
// スライダー (ラベル,最小値,最大値,刻み,初期値)
form.slider("スライダー", 0, 100, 1, 0);
// ドロップダウン (ラベル,配列,初期値)
form.dropdown("ドロップダウン", ["選択肢0", "選択肢1", "選択肢2"], 0);
// テキストフィールド (ラベル,プレースホルダ,初期値);
form.textField("テキストフィールド", "プレースホルダ", "");
// フォームの表示
form.show(player).then(res => {
// ここから下はフォームが送信される または フォームが閉じられると処理が始まる
// res.canceled - フォームをキャンセルしたかどうか
// res.formValues[] - フォームの入力の配列 (0から始まる)
if (res.canceled) { // フォームをキャンセルした場合
player.runCommand("say キャンセルしました");
} else { // キャンセルされなかった場合
// フォームの結果をsayする
player.runCommand("say トグル: " + res.formValues[0]);
player.runCommand("say スライダー: " + res.formValues[1]);
player.runCommand("say ドロップダウン: " + res.formValues[2]);
player.runCommand("say テキストフィールド: " + res.formValues[3]);
}
});
}
});
サンプルコード:メッセージフォーム

import { world } from "@minecraft/server";
import { ModalFormData } from "@minecraft/server-ui";
world.afterEvents.itemUse.subscribe(ev => {
const player = ev.source;
const itemStack = ev.itemStack;
if (itemStack.typeId === "minecraft:iron_ingot" && itemStack.nameTag === "メッセージを送る") {
// 全てのプレイヤーの配列
const players = world.getPlayers();
// 名前の配列
const names = players.map(player => player.name);
// フォームの定義
const form = new ModalFormData()
.title("メッセージフォーム")
.dropdown("どのプレイヤーに送りますか?", names)
.textField("メッセージ", "", "")
.toggle("匿名にする", false);
// フォームの表示
form.show(player).then(res => {
if (res.canceled) return;
const toPlayer = players[res.formValues[0]]; // 送信先のプレイヤー
const message = res.formValues[1]; // メッセージ
const isAnonymous = res.formValues[2]; // 匿名かどうか
let fromName = player.name; // 送信元のプレイヤー名
// 匿名の場合、送信元を"匿名"にする
if (isAnonymous) {
fromName = '匿名';
}
// メッセージがない場合、エラーメッセージを送る
if (message === "") {
player.sendMessage("§cメッセージがありません");
return; // 処理を終わる
}
// 送信先プレイヤーにメッセージを送る
toPlayer.sendMessage(`§e${fromName}§f => ${message}`);
});
}
});
参考URL
公式リファレンス
minecraft/server Module | Microsoft Learn
ディスコードサーバー
Script API 開発初心者コミュニティ
参考にしたサイト
マイクラの泉
コメント
トグルがONの時にplayer.runCommandAsyncを使う方法ってありますか?
トグルのフォームの結果がtrueなら、player.runCommandAsync()を実行する、というプログラムを書けばできます。
server.system.runIntervalを使ってコマンドを使いたい(トグルがONした場合実行)
コマンドに ${} を使うとエラーになる
player.runCommandで使用
例えば
execute as ${player.name} at @s run fill ${A} ${B} ${A} ${A} ${B} ${A} ${C} []
Aはsliderで指定した座標 X&Z
BはtextFieldで指定した 座標 Y
CはtextFieldで指定したブロック名
${}でtarget data でやってみたんだけどエラーになる
${}は「`」(バッククォート)で囲まれた文字列でのみ使えます。
もし、「”」(ダブルクォート)や「’」(シングルクォート)で囲んでいる場合は、ただの文字列になります。
例)
const message = “hello”;
const command = `say ${message}`;
メッセージフォームに送信者==>受信者 チャットの内容
のようにできますでしょうか?
コードが間違っていたため、修正しました。
「送信者の名前 => チャットの内容」のように表示するよう修正しました。
質問ありがとうございます。
「送信者の名前 => 受信者 チャットの内容」のように表示したい場合は、
最後の「送信先プレイヤーにメッセージを送る」のコードを次のように変更してください。
// 送信先プレイヤーにメッセージを送る
toPlayer.sendMessage(`§e${fromName}§f => ${player.name} ${message}`);
こんにちは。formValuesの部分で
player.runCommand(‘tellraw ‘ + player.name + ‘ {“rawtext”:[{“text”:”‘ + form.formValues[0] + ‘”}]}’)というコードでformValuesが効きません。
他の単語とかならいけるのですが…
(コードは一部改変しています。内容はほとんど一緒です)
クォート(’,`,”)が、半角ではなく全角で入力されていませんか?
すべて半角であれば構文的には問題ありません。
プレイヤーにメッセージを送るのであれば
player.sendMessage(form.formValues[0]);
でも同じ結果なので、試してみてください。
本当にありがとうございます!このコメントの返信を見ようとしたのですが、迷ってしまいしばらく時間がかかりました。やってみます!
トグルボタンのところで質問があります。
1回目にプレイヤー自らがフォームを開いてトグルを「true」に設定して,2回目同じフォームを開いたときにトグルボタンが「true」,要するに前回の状態を保持する方法がありましたら,ご教授お願い致します
「トグルをtrueにした」ということを何かしらに記録しておけば可能です。
例えば、タグで記録するなら
フォームの結果から
トグルがtrueのとき、タグ「toggle_true」をプレイヤーに追加。
トグルをfalseのとき、タグ「toggle_true」をプレイヤーから削除。
という処理を行い。
フォームを表示する際に、
form.toggle(“トグル”,player.hasTag(“toggle_true”));
とすればできます。
他にもダイナミックプロパティを使う手もあります。
迅速な返信ありがとうございます。
加えて質問があります。
まずシチュエーションですが,マルチプレイでの利用を考えており,「OP」というタグを持った人がスニークしながら時計を使うとフォームが面が開き,トグルで朝夜を切り替えるようにしたいです。
OPは2人いて,どっちも時計を使っての操作するため,「もしAが朝にした」のちに,「Bが夜にする」ということをしたいです。この場合,フォームのトグルの結果は,個人に依存するのか,もしくは全体で変わりますでしょうか?変わる場合は,どのようにすればいいでしょうか?
時計をスニークして使えば切り替わるという動作の方が早いとは思いますが,もし上記の内容ができたらほかにも応用が利くと思い,質問させていただきました。
それであれば、
world.getTimeOfDay(); // ワールドの時刻を取得するメソッド
の値から、朝か夜かを判定し、それをトグルの初期値にしたほうが良いと思います。
world.getTimeOfDay()のリファレンス
https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/world?view=minecraft-bedrock-stable#gettimeofday
朝だったら数値○○,夜だったら数値○○みたいな感じですかね?!
スパムメッセージと判断されたのか構文が送信できませんでした。
SendMessageは正常に動作したのですがやはりform.formValuesがうまく動作しませんでした。
// フォームの表示
form.show(player).then(res => {
ここはどうなっていますか?
同じであれば、
form.formValues
ではなく
res.formValues
です
コードをよくよーく見て修正したら、できました!すみません!