【統合版】ScriptAPI #4 アクションフォーム

スポンサーリンク

事前説明

こんにちは、さば2号です。

今回はScriptAPIのUIについて解説していきます。

事前準備、アドオンフォルダの作成、manifestの書き方は前回の解説をご覧ください。
【統合版】ScriptAPIでアドオンを作ってみよう #1 ダメージメッセージ

注意事項

・この記事は2024/03/26時点のものです。
・投稿者は素人です。間違えることがあります。

解説

ScriptAPIでは3つのフォームのUIを作成できます。
今回はボタンの選択肢を設定できる、ActionFormの解説をしていきます。

公式リファレンス ActionFormData Class

%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2024-03-27-180910-3.png

次のようなフォームを作ってみましょう。
「フォームを開く」という名前の棒を使ったときに開くようにします。

%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2024-03-27-183624.png
import { world } from "@minecraft/server";
// フォームのインポート
import { ActionFormData, MessageFormData, ModalFormData } from "@minecraft/server-ui";

// アイテムを使用すると起動
world.afterEvents.itemUse.subscribe(ev => {
const player = ev.source;
const itemStack = ev.itemStack;

// アイテムの種類が棒(minecraft:stick) かつ アイテムの名前が「フォームを開く」の場合
if (itemStack.typeId === "minecraft:stick" && itemStack.nameTag === "フォームを開く") {

// アクションフォームのインスタンスを生成
const form = new ActionFormData();
form.title("タイトル");
form.body("ボディ");
// ボタンの追加
form.button("0番目のボタン");
form.button("1番目のボタン");
form.button("2番目のボタン", "textures/items/apple");
form.button("3番目のボタン", "textures/blocks/stone");

// フォームの表示
form.show(player).then(response => {
// response.canceled - フォームをキャンセルしたかどうか
// response.selection - 押したボタンの番号 (0から始まる)

if (response.canceled) { // フォームをキャンセルした場合
player.runCommand("say キャンセルしました");

} else { // そうでない場合
player.runCommand(`say ${response.selection}番目のボタンを押しました`);
}
});
}
});

サンプルコード:コマンドフォーム

%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2024-03-27-204101.png
import { world } from "@minecraft/server";
import { ActionFormData, MessageFormData, ModalFormData } from "@minecraft/server-ui";

world.afterEvents.itemUse.subscribe(ev => {
const player = ev.source;
const itemStack = ev.itemStack;

// アイテムの種類が棒(minecraft:stick) かつ アイテムの名前が「コマンドフォーム」の場合
if (itemStack.typeId === "minecraft:stick" && itemStack.nameTag === "コマンドフォーム") {
// プレイヤーがopタグを持っていたら
if (player.hasTag("op")) {

const form = new ActionFormData();
form.title("コマンドフォーム");
form.button("アドベンチャーに変更");
form.button("クリエイティブに変更");
form.button("ロビーにTP (0,0,0)");
form.button("アイテムクリア");

// フォームの表示
form.show(player).then(response => {
if (response.canceled === false) {
// 選んだボタンによってコマンドを実行する
if (response.selection === 0) {
player.runCommand("gamemode a @s");
} else if (response.selection === 1) {
player.runCommand("gamemode c @s");
} else if (response.selection === 2) {
player.runCommand("tp @s 0 0 0");
} else {
player.runCommand("clear @s");
}
}
});
} else {
player.sendMessage("opタグを持っていません。");
}
}
});

サンプルコード:コマンドフォーム(async/await,メソッドチェーン,switchを使用する場合)

import { world, system } from "@minecraft/server";
import { ActionFormData, MessageFormData, ModalFormData } from "@minecraft/server-ui";

world.afterEvents.itemUse.subscribe(ev => {
const player = ev.source; const itemStack = ev.itemStack;
if (itemStack.typeId === "minecraft:stick" && itemStack.nameTag === "コマンドフォーム") {
if (!player.hasTag("op")) {
player.sendMessage("opタグを持っていません");
return;
}
showCommandForm(player);
}
});

// コマンドフォームを開く関数
async function showCommandForm(player) {
// メソッドチェーンでまとめて定義
const form = new ActionFormData()
.title("コマンドフォーム")
.button("アドベンチャーに変更")
.button("クリエイティブに変更")
.button("ロビーにTP (0,0,0)")
.button("アイテムをクリア");

const res = await form.show(player);
if (res.canceled) return;
switch (res.selection) {
case 0:
player.runCommand("gamemode a @s");
break;
case 1:
player.runCommand("gamemode c @s");
break;
case 2:
player.runCommand("tp @s 0 0 0");
break;
case 3:
player.runCommand("clear @s");
break;
}
}

参考URL

公式リファレンス
minecraft/server Module | Microsoft Learn

ディスコードサーバー
Script API 開発初心者コミュニティ

参考にしたサイト
マイクラの泉

備忘録ブログ
さば2号のgametest(scriptAPI)備忘録

※投稿記事に含まれるファイルやリンクにより発生した被害についてクラフターズコロニーは責任を取りません
投稿通報

コメント

  1. 質問失礼します。こちらの記事を参考に、作ってみたのですが、フォームが表示されなくて、原因分かりますか?

    import { world } from “@minecraft/server”;
    import { ActionFormData, MessageFormData, ModalFormData } from “@minecraft/server-ui”;

    world.afterEvents.itemUse.subscribe(ev => {
    const player = ev.source;
    const itemStack = ev.itemStack;

    // アイテムの種類がコンパス(minecraft:compass) の場合
    if (itemStack.typeId === “minecraft:compass”) {

    const form = new ActionFormData();
    form.title(“§l§bServer menu”);
    form.button(“§l§aback to lobby”);

    // フォームの表示
    form.show(player).then(response => {
    if (response.canceled === false) {
    // 選んだボタンによってコマンドを実行する
    if (response.selection === 0) {
    player.runCommand(“tp @s 0 1 0 0 0”);
    }
    }
    });

    コンテンツ ログに[main.js] run with error: [SyntaxError: unexpected token in expression: “ at main.js:23 とエラーが出ています。
    返信お願いします。

    • 返信してください。お願いします。

    • 次の括弧がないためエラーとなっているようです。

      4行目のsubscribe(ev => { の終わりの括弧 });
      9行目のif (itemStack.typeId === … の終わりの括弧 }

コメント通報