【統合版アドオン】ScriptAPIサンプルコード集

スポンサーリンク

初めに

どうも餅わらびすとです。この記事では究極の機能、ScriptAPI(gametestとも言う)のサンプルコード集を置いていきます。
良いなと思ったものがあればたまに更新するかも?
よく使うであろうコードを選んだので役に立てれば嬉しいです。

「まずScriptAPIについて知らない」、という方はこちらの、「【統合版アドオン】part-1│究極の機能、ScriptAPIを徹底解説!」で基本的な使い方を解説しているので、見ていない方は見てください。ここでは、リンクの記事の内容を理解していることを前提にしているので、記事を見た後に来るのを推奨します。

モジュールから全ての要素をインポート

%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-05-11-194848.png

@minecraft/serverにある、クラスや変数などの要素がmcに入ります。これによりいちいち必要な要素をインポートする手間がなくなるでしょう。(今回のコード集ではこれを使います)

import * as mc from "@minecraft/server";
import * as ui from "@minecraft/server-ui";

使用例: 棒を使ったら使用者にメッセージを送信する

%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-05-11-195443.png
import * as mc from "@minecraft/server";

mc.world.afterEvents.itemUse.subscribe(ev => {
if (ev.itemStack.typeId === "minecraft:stick") ev.source.sendMessage("棒を使った!");
});

全プレイヤーの取得

%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-05-11-195923.png

for () {}の、{}の中ではgetPlayers()で取得した配列の要素1つ1つにplayerという名前を付けて処理を出来ます。
playerという部分の命名に制限はありません。

for (const player of mc.world.getPlayers()) {
//処理
}

使用例: 20ティック(1秒)毎に全プレイヤーへメッセージを送る

%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-05-11-200523.png
mc.system.runInterval(() => {
for (const player of mc.world.getPlayers()) {
player.sendMessage("あなたは全プレイヤーの内の1人です");
}
}, 20);

全エンティティの取得

%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-05-11-201033-1.png

同じく、for () {}の、{}の中ではgetEntities()で取得した配列の要素1つ1つにentityという名前を付けて処理を出来ます。
entityという部分の命名に制限はありません。
また、mc.world.getDimension(“overworld”)の部分はディメンションオーバーワールドを取得しているということなのでこの部分を事前に所得していたディメンションに置き換えても問題ありません。

for (const entity of mc.world.getDimension("overworld").getEntities()) {
//処理
}

使用例: 20ティック(1秒)毎にプレイヤーを除外した全エンティティを消す

%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-05-11-214632.png
mc.system.runInterval(() => {
for (const entity of mc.world.getDimension("overworld").getEntities({ excludeTypes: ["minecraft:player"] })) {
entity.remove();
}
}, 20);

スコアボードオブジェクトの追加や取得

%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-05-11-203931.png

取得したスコアボードは操作出来ます。

mc.world.scoreboard.getObjective(/* 取得したいオブジェクトの名前 */);
mc.world.scoreboard.addObjective(/* 追加したいオブジェクトの名前 */);

使用例: チャットによりスコアを操作

%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-05-11-205302.png
mc.world.afterEvents.chatSend.subscribe(ev => {
//testスコアボードを取得してundefinedだったらtestスコアボードを追加。結果をscoreへ代入
const score = mc.world.scoreboard.getObjective("test") ?? mc.world.scoreboard.addObjective("test");

//チャットへ.addと送信されたら送信者のtestスコアを1追加
if (ev.message === ".add") score.addScore(ev.sender, 1);
//チャットへ.getと送信されたら送信者のtestスコアを送信
if (ev.message === ".get") ev.sender.sendMessage(String(score.getScore(ev.sender)));
});

DynamicProperyへオブジェクトを保存

%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-05-11-211252.png

現状DPには文字列,数値,真偽値,Vetor3の4つしか入れられなく、Vector3以外のオブジェクトは入れられないため、オブジェクトをJSON化(文字列化)してセットする必要があります。そのため、取得する際もJSON化されたオブジェクトをオブジェクトに戻す必要があります。
オブジェクトを直接入れているわけではないのでItemStackを保存、のようなことは出来ません。

//セットするとき
mc.world.setDynamicProperty("DPのID", JSON.stringify(/* 保存したいオブジェクト */));
//取得するとき
JSON.parse(mc.world.getDynamicProperty("DPのID"));

使用例: プレイヤー参加時にDPjoinedPlayersに参加したプレイヤーの名前を追加された配列をセットする

%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-05-11-214114.png
mc.world.afterEvents.playerJoin.subscribe(ev => {
//DP、joinedPlayersを取得
let joinedPlayers = mc.world.getDynamicProperty("joinedPlayers");
//変数joinedPlayersがundefinedだったら変数joinedPlayersへ[](JSONで表す空の配列)をセット
joinedPlayers ??= "[]";
//オブジェクトへ変換され、配列となった変数joinedPlayersへ参加したプレイヤーの名前を追加された配列を定数newJoinedPlayersへ代入
const newJoinedPlayers = JSON.parse(joinedPlayers).concat(ev.playerName);
//JSON化された定数newJoinedPlayersをDP、joinedPlayersへセット
mc.world.setDynamicProperty("joinedPlayers", JSON.stringify(newJoinedPlayers));
});

コンポーネントの取得

%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-05-16-211854.png

取得したコンポーネントはその要素をいじくれたりします。コンポーネントを追加ことは出来ません。

entity.getComponent("コンポーネント名");

使用例: 常にインベントリ番号0の位置へ棒をセットする

%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-05-16-212410.png
mc.system.runInterval(() => {
for (const player of mc.world.getPlayers()) {
const stick = new mc.ItemStack("minecraft:stick", 1);
player.getComponent("minecraft:inventory").container.setItem(0, stick);
}
});

ウォッチドックによるクラッシュのキャンセル

%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-05-16-214749.png

一定の大きさの負荷が掛かるとscriptapi側がワールドを閉じてしまうので、それをキャンセルします。

mc.system.beforeEvents.watchdogTerminate.subscribe(ev => {
ev.cancel = true;
});

スクリーンの操作

onScreenDisplayの中に操作出来る要素があります。

player.onScreenDisplay;

使用例: エフェクトが追加されたらタイトルを表示

%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-05-16-221023.png
mc.world.afterEvents.effectAdd.subscribe(ev => {
const { entity, effect } = ev;
entity.onScreenDisplay.setTitle(effect.displayName, {
fadeInDuration: 0,
stayDuration: 60,
fadeOutDuration: 20,
subtitle: "エフェクトが追加されました"
});
});

ブロックステートがセットされたブロックの設置

%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-05-16-221925.png

ブロックステートは調べれば出てきます。設置音はしません。
Vector3は、x,y,zという三つのプロパティを持ったオブジェクトです。

const permutation = mc.BlockPermutation.resolve("ブロック名", ブロックステート);
dimension.setBlockPermutation(Vector3, permutation);

使用例: アイテムを使用したらブロックステートを設定されたブロックを設置する

%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-05-16-222234.png
mc.world.afterEvents.itemUse.subscribe(ev => {
const { source, itemStack } = ev;
const { dimension } = source;
if (itemStack.nameTag === "肥料") {
const permutation = mc.BlockPermutation.resolve("minecraft:tallgrass", { tall_grass_type: "fern" });
dimension.setBlockPermutation(source.location, permutation);
}
});

処理されたItemStackをセット

%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-05-16-223938.png

ItemStackは処理後にインベントリにセットしてあげないと名前を変えたりしても変化しないのでこのようにセットする必要があります。

//ItemStackへの処理
player.getComponent("equippable").setEquipment("Mainhand", 処理されたItemStack);

使用例: アイテムを使用したらアイテムの説明欄に説明をセットする

%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-05-16-224320.png
mc.world.afterEvents.itemUse.subscribe(ev => {
const { source, itemStack } = ev;
if (itemStack.typeId === "minecraft:dragon_breath") {
itemStack.setLore(["試してみたが飲めたものじゃない。"]);
source.getComponent("equippable").setEquipment("Mainhand", itemStack);
}
});

全ItemTypeの取得

ItemTypeはItemStackの生成なんかに使えるものです。ブロックもアイテムに入ります。ワールドにあるものを取得するのでアドオンでの追加アイテムなども取得できます。

mc.ItemTypes.getAll();

使用例: チャットをしたらIDにgoldと入ったアイテムをスポーンさせる

%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-05-16-231204.png
mc.world.afterEvents.chatSend.subscribe(ev => {
if (ev.message === "getGoldItems") {
for (const itemType of mc.ItemTypes.getAll().filter(it => it.id.includes("gold"))) {
const item = new mc.ItemStack(itemType, 1);
ev.sender.dimension.spawnItem(item, ev.sender.location);
}
}
});

最後に

ここまで読んでくださりありがとうございました!役に立ったと思ってもらえたら嬉しいです。

なにか質問があるときはこちらのディスコードサーバーから受け付けています。どんな人も大歓迎!一応ここでも受け付けますが内容が複雑になると判断した質問はサーバーでしか受け付けません。

それでは良いアドオンライフを!

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

コメント

  1. ありがとうございます!
    役に立ちました!

    • よかったです!
      励みになります

コメント通報