目次
- はじめに
- アフターイベントとは
- 注意点
-
WorldAfterEvents
-
プレイヤー関連
- ChatSend
- ItemCompleteUse
- ItemReleaseUse
- ItemStartUse
- ItemStopUse
- ItemUse
- ItemStartUseOn
- ItemStopUseOn x
- PlayerBreakBlock
- PlayerPlaceBlock
- PlayerDimensionChange
- PlayerEmote
- PlayerGameModeChange
- PlayerInputPermissionCategoryChange
- PlayerInteractWithBlock
- PlayerInteractWithEntity
- PlayerJoin
- PlayerLeave
- PlayerSpawn
-
SystemAfterEvents
- 最後に
はじめに
前回に引き続き、ScriptAPIの基本、イベントの操作を扱っていきます。
前回の予告通りどのようなイベントがあるのかを紹介します。
前編で紹介しましたが、ScriptAPIのイベントにはアフターイベントとビフォーイベントの二種類存在し、本編はその内のアフターイベントの内容となっています。
ScriptAPIではバージョンによってイベント名の変更やイベントの追加、削除が行われている為、情報が一致しない可能性のあることに留意した後、本記事を御一読頂けると幸いです。
本編は2025/03/26時点で最新のベータ版2.0.0-beta
の内容になります。(ここで最新の公開されているバージョンを確認することが出来ます。)
以下の前編の構造編を理解することによって、よりスムーズに本記事を読む事が出来ます。文章量も抑えていますので、時間に余裕がある方は是非御一読下さい。
この「ScriptAPI参考書」シリーズではマインクラフト統合版のScriptAPIについて基礎から応用、例文まで詳細に解説し、ScriptAPI開発者や、ScriptAPIの開発を始めようと思っている人の助けになることを目的としています。
また、このシリーズを読むにあたって、ある程度のマインクラフトとJavaScriptの事前知識が必要になってくることがあります。
注意: このシリーズではMinecraft Bedrock Editionを省略してマインクラフトと表記しています。
前回: イベントの操作 構造編
次回: 準備中...
注意点
本記事を読んで頂くにあたって注意点が幾つかあります。
本シリーズでは初心者向けの記事である側面があるため、コードに非効率な部分などが存在する場合があります。主な要素として、型の使用が厳密ではない、コードが冗長、等が挙げられます。
その為、あまりコードの内容については重箱の隅をつつかないようにお願い致します。ただ、根本的に誤っている部分があれば是非コメント欄でお伝え下さい。
アフターイベントとは
前編でも解説しましたが、前編から抜粋して解説いたします。
ScriptAPIにおけるアフターイベントとは、任意のイベントが発生した後に実行されるイベントです。
この仕様から、イベントが発生した前と後で変化があるようなイベント(例えば、ブロックが破壊された時に実行されるようなイベント)の場合、発生する前の情報を取得するのには適していません。
但し、イベントが発生する前の情報をイベントのデータとして持つイベントも存在しています。
基本的に、ビフォーイベントと比べてアフターイベントを使用する頻度が高く、イベントの量も多くなっています。
WorldAfterEvents
ワールド関連
GameRuleChange
説明
ゲームルールが変更された時に実行されるイベント
例文
ランダムティックスピードが100を超えたときに警告メッセージを送信する
import { world, GameRule } from "@minecraft/server";
world.afterEvents.gameRuleChange.subscribe((ev) => {
const { rule, value } = ev;
if (rule === GameRule.RandomTickSpeed && value > 100) {
world.sendMessage(`${GameRule.RandomTickSpeed}が100を超えています。`);
}
});
MessageReceive
説明
クライアントからサーバーにメッセージを渡すために使用される、現在内部にある特定のイベント
様々な記事等から情報を収集、また、実験等を行いましたが、有益な情報を得ることが出来ませんでした。ご存じの方は、コメント等にてお教え頂けると幸いです。
例文
import { world } from "@minecraft/server";
world.afterEvents.messageReceive.subscribe((ev) => {
// 詳細不明
});
WeatherChange
説明
天候が変化した時に実行されるイベント
/toggledownfall
を使用して天候を切り替えた場合、このイベントは実行されません。
例文
天候が変化した時、現在の天候を送信する
import { world } from "@minecraft/server";
world.afterEvents.weatherChange.subscribe((ev) => {
const { newWeather } = ev;
// 例) 現在の天候は Thunder です。
world.sendMessage(`現在の天候は ${newWeather} です。`);
});
WorldLoad
説明
ワールドのスクリプト環境が初期化(起動)した時に実行するイベント
例文
スクリプト環境が初期化された時にメッセージを送信する
import { world } from "@minecraft/server";
world.afterEvents.worldLoad.subscribe(() => {
world.sendMessage("スクリプトが読み込まれました。");
});
ブロック関連
BlockExplode
説明
爆発によりブロックが破壊された時に実行されるイベント
例文
TNTの爆発により破壊されたブロックをコンテンツログに出力する
import { world } from "@minecraft/server";
world.afterEvents.blockExplode.subscribe((ev) => {
const { source, explodedBlockPermutation } = ev;
if (source?.typeId === "minecraft:tnt") {
// 例) minecraft:dirt
console.log(explodedBlockPermutation.type.id);
}
});
ButtonPush
説明
ボタンが押された時に実行されるイベント
例文
(0, 0, 0)
に設置されたボタンを押したエンティティをkillする
import { world } from "@minecraft/server";
world.afterEvents.buttonPush.subscribe((ev) => {
const { source, block } = ev;
if (block.x === 0 && block.y === 0 && block.z === 0) {
source.kill();
}
});
LeverAction
説明
レバーが引かれた時に実行されるイベント
例文
任意のレバーがオンになった時に、レバーの座標を送信する
import { world } from "@minecraft/server";
world.afterEvents.leverAction.subscribe((ev) => {
const { block, isPowered } = ev;
if (isPowered) {
world.sendMessage(`(${block.x}, ${block.y}, ${block.z}) のレバーがオンになりました。`);
}
});
PressurePlatePop
説明
感圧版が上がった時に実行されるイベント
例文
感圧版が上がった時にメッセージを送信する
import { world } from "@minecraft/server";
world.afterEvents.pressurePlatePop.subscribe((ev) => {
const { block } = ev;
world.sendMessage(`(${block.x}, ${block.y}, ${block.z}) の感圧版が上がりました。`);
});
PressurePlatePush
説明
感圧版が下がった時に実行されるイベント
例文
感圧版が下がった時にメッセージを送信する
import { world } from "@minecraft/server";
world.afterEvents.pressurePlatePush.subscribe((ev) => {
const { block } = ev;
world.sendMessage(`(${block.x}, ${block.y}, ${block.z}) の感圧版が下がりました。`);
});
PistonActivate
説明
ピストンの状態が変化した時に実行されるイベント
例文
ピストンが押された時にメッセージを送信する
import { world } from "@minecraft/server";
world.afterEvents.pistonActivate.subscribe((ev) => {
const { block, isExpanding } = ev;
if (isExpanding) {
world.sendMessage(`(${block.x}, ${block.y}, ${block.z}) のピストンが押されました。`);
}
});
TargetBlockHit
説明
ターゲットブロックに投擲物がヒットした時に実行されるイベント
イベントデータ
-
readonly dimension: Dimension
ターゲットブロックにヒットしたディメンション -
readonly block: Block
ヒットしたターゲットブロック -
readonly hitVector: Vector3
ターゲットブロックにヒットしたエンティティの座標 -
readonly source: Entity
ターゲットブロックにヒットしたエンティティ -
readonly previousRedstonePower: number
ヒットする前のターゲットブロックのレッドストーン信号の強度 -
readonly redstonePower: number
ヒットした後のターゲットブロックのレッドストーン信号の強度
例文
ターゲットブロックにエンティティがヒットした時、そのエンティティのtypeIdを送信する
import { world } from "@minecraft/server";
world.afterEvents.targetBlockHit.subscribe((ev) => {
const { block, source } = ev;
// 例) (11, 65, 24) のターゲットブロックに minecraft:arrow がヒットしました。
world.sendMessage(`(${block.x}, ${block.y}, ${block.z}) のターゲットブロックに ${source.typeId} がヒットしました。`);
});
TripWireTrip
説明
エンティティが糸に引っかかった、若しくは離れた時に実行されるイベント
イベントデータ
-
readonly dimension: Dimension
エンティティが糸に引っかかった、若しくは離れたディメンション -
readonly block: Block
エンティティが引っかかった、若しくは離れた糸 -
readonly isPowered: boolean
エンティティが引っかかった、若しくは離れた糸にレッドストーン信号があるか否か
糸がトリップワイヤーフック等に接続されていなくとも、引っかかった時にtrue
、離れた時にfalse
となります。 -
readonly sources: Entity[]
糸に引っかかったエンティティの配列
同時に複数のエンティティが糸に引っかかると配列の要素が複数になります。
但し、エンティティが糸から離れた時は空の配列になります。
例文
トリップワイヤーフックに引っかかったエンティティに対して暗闇を10秒間付与する
import { world, TicksPerSecound } from "@minecraft/server";
world.afterEvents.tripWireTrip.subscribe((ev) => {
const { sources, isPowered } = ev;
if (isPowered) for (const source of Array.from(sources)) {
source.addEffect("minecraft:darkness", TicksPerSecond * 10);
}
});
エンティティ関連
DataDrivenEntityTrigger
説明
エンティティのイベントがトリガーされた時に実行されるイベント
例文
クリーパーが爆発し始めた際にメッセージを送信する
import { world } from "@minecraft/server";
world.afterEvents.dataDrivenEntityTrigger.subscribe((ev) => {
const { entity, eventId } = ev;
const { x, y, z } = entity.location;
if (entity.typeId === "minecraft:creeper" && eventId === "minecraft:start_exploding_forced") {
world.sendMessage(`(${x}, ${y}, ${z}) でクリーパーが爆発します。`);
}
});
上記に登録オプションを使用した例
import { world } from "@minecraft/server";
world.afterEvents.dataDrivenEntityTrigger.subscribe((ev) => {
const { entity } = ev;
const { x, y, z } = entity.location;
world.sendMessage(`(${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}) でクリーパーが爆発します。`);
}, {
entityTypes: ["minecraft:creeper"],
eventTypes: ["minecraft:start_exploding_forced"]
});
EffectAdd
説明
エンティティにエフェクトが付与された時に実行されるイベント
既にエンティティに同一のエフェクトが付与されている場合、このイベントは実行されません。
例文
プレイヤーにエフェクトが付与された時、付与されたエフェクトの内容を送信する
import { world, Player, TicksPerSecound } from "@minecraft/server";
world.afterEvents.effectAdd.subscribe((ev) => {
const { entity, effect } = ev;
if (!(entity instanceof Player)) return;
// 例) Steve に 10秒間 再生能力 III が付与されました。
world.sendMessage(`${entity.name} に ${effect.duration / TicksPerSecond}秒間 ${effect.displayName} が付与されました。`);
});
上記に登録オプションを使用した例
import { world, TicksPerSecound } from "@minecraft/server";
world.afterEvents.effectAdd.subscribe((ev) => {
const { entity, effect } = ev;
world.sendMessage(`${entity.name} に ${effect.duration / TicksPerSecond}秒間 ${effect.displayName} が付与されました。`);
}, {
entityTypes: ["minecraft:player"]
});
EntityDie
説明
エンティティが死亡した時に実行されるイベント
例文
プレイヤーが死亡した時、殺害したエンティティのtypeIdを送信する
import { world, Player } from "@minecraft/server";
world.afterEvents.entityDie.subscribe((ev) => {
const { deadEntity, damageSource } = ev;
const { damagingEntity } = damageSource;
if (!(deadEntity instanceof Player)) return;
if (damagingEntity) {
// 例) Steve は minecraft:wither に殺害されました。
world.sendMessage(`${deadEntity.name} は ${damagingEntity.typeId} に殺害されました。`);
}
});
上記に登録オプションを使用した例
import { world } from "@minecraft/server";
world.afterEvents.entityDie.subscribe((ev) => {
const { deadEntity, damageSource } = ev;
const { damagingEntity } = damageSource;
if (damagingEntity) {
// 例) Steve は minecraft:wither に殺害されました。
world.sendMessage(`${deadEntity.name} は ${damagingEntity.typeId} に殺害されました。`);
}
}, {
entityTypes: ["minecraft:player"]
});
EntityHealthChanged
説明
エンティティの体力が変化した時に実行されるイベント
例文
プレイヤーにプレイヤーの体力の増減を送信する
import { world, Player } from "@minecraft/server";
world.afterEvents.entityHealthChanged.subscribe((ev) => {
const { entity, newValue, oldValue } = ev;
if (!(entity instanceof Player)) return;
const delta = newValue - oldValue;
if (delta > 0) {
entity.sendMessage(`体力が ${delta} 増加しました。`);
}
if (delta < 0) {
entity.sendMessage(`体力が ${Math.abs(delta)} 減少しました。`);
}
});
上記に登録オプションを使用した例
import { world } from "@minecraft/server";
world.afterEvents.entityHealthChanged.subscribe((ev) => {
const { entity, newValue, oldValue } = ev;
const delta = newValue - oldValue;
if (delta > 0) {
entity.sendMessage(`体力が ${delta} 増加しました。`);
}
if (delta < 0) {
entity.sendMessage(`体力が ${Math.abs(delta)} 減少しました。`);
}
}, {
entityTypes: ["minecraft:player"]
});
EntityHitBlock
説明
エンティティがブロックに対して攻撃を行った時に実行されるイベント
矢やトライデント等の投擲による攻撃はProjectileHitBlock
なので注意して下さい。
例文
プレイヤーがブロックを攻撃した時、攻撃されたブロックのtypeIdを送信する
import { world, Player } from "@minecraft/server";
world.afterEvents.entityHitBlock.subscribe((ev) => {
const { damagingEntity, hitBlock } = ev;
if (!(damagingEntity instanceof Player)) return;
// 例) Steve が minecraft:diamond_block を攻撃しました。
world.sendMessage(`${damagingEntity.name} が ${hitBlock.typeId} を攻撃しました。`);
});
上記に登録オプションを使用した例
import { world } from "@minecraft/server";
world.afterEvents.entityHitBlock.subscribe((ev) => {
const { damagingEntity, hitBlock } = ev;
// 例) Steve が minecraft:diamond_block を攻撃しました。
world.sendMessage(`${damagingEntity.name} が ${hitBlock.typeId} を攻撃しました。`);
}, {
entityTypes: ["minecraft:player"]
});
EntityHitEntity
説明
エンティティがエンティティに対して攻撃を行って時に実行されるイベント
例文
プレイヤーがエンティティを攻撃した時、攻撃されたエンティティのtypeIdを送信する
import { world, Player } from "@minecraft/server";
world.afterEvents.entityHitBlock.subscribe((ev) => {
const { damagingEntity, hitEntity } = ev;
if (!(damagingEntity instanceof Player)) return;
// 例) Steve が minecraft:cow を攻撃しました。
world.sendMessage(`${damagingEntity.name} が ${hitEntity.typeId} を攻撃しました。`);
});
上記に登録オプションを使用した例
import { world } from "@minecraft/server";
world.afterEvents.entityHitEntity.subscribe((ev) => {
const { damagingEntity, hitEntity } = ev;
// 例) Steve が minecraft:cow を攻撃しました。
world.sendMessage(`${damagingEntity.name} が ${hitEntity.typeId} を攻撃しました。`);
}, {
entityTypes: ["minecraft:player"]
});
EntityHurt
説明
エンティティがダメージを受けた時に実行されるイベント
例文
エンティティが落下ダメージを受けた時にメッセージを送信する
import { world, EntityDamageCause, Player } from "@minecraft/server";
world.afterEvents.entityHurt.subscribe((ev) => {
const { hurtEntity, damageSource } = ev;
if (!(hurtEntity instanceof Player)) return;
if (damageSource.cause === EntityDamageCause.fall) {
// 例) Steve が落下ダメージを受けました。
world.sendMessage(`${hurtEntity.name} が落下ダメージを受けました。`);
}
});
上記に登録オプションを使用した例
import { world, EntityDamageCause } from "@minecraft/server";
world.afterEvents.entityHurt.subscribe((ev) => {
const { hurtEntity, damageSource } = ev;
if (damageSource.cause === EntityDamageCause.fall) {
// 例) Steve が落下ダメージを受けました。
world.sendMessage(`${hurtEntity.name} が落下ダメージを受けました。`);
}
}, {
entityTypes: ["minecraft:player"]
});
EntityLoad
説明
エンティティがロードされた時に実行されるイベント
ここで言うロードとは、「任意のエンティティが読み込まれていないチャンクにいる時、そのチャンクが読み込まれると同時にエンティティがロードされること」を指す。
その為、例えばプレイヤー参加した直後にプレイヤー周辺のチャンクが読み込まれていないと、そのプレイヤー周辺のチャンクにいるエンティティに対してイベントが発生します。
また、上記より/summon
などで召喚したエンティティはこのイベントに当てはまりません。
例文
エンティティがロードされた時、最も近いプレイヤーにエンティティの距離とtypeIdを送信する
import { world } from "@minecraft/server";
world.afterEvents.entityLoad.subscribe((ev) => {
const { entity } = ev;
const dimension = entity.dimension;
const location = entity.location;
const [player] = dimension.getPlayers({ closest: 1, location });
if (player?.isValid) {
const distance = Math.hypot(...Object.keys(location).map((axis) => player.location[axis] - location[axis]));
// 例) 12.34m 先で minecraft:cow が読み込まれました。
player.sendMessage(`${distance.toFixed(2)}m 先で ${entity.typeId} が読み込まれました。`);
}
});
EntityRemove
説明
エンティティが消滅した時に実行されるイベント
例文
絵画が破壊された時メッセージを送信する
import { world } from "@minecraft/server";
world.afterEvents.entityRemove.subscribe((ev) => {
const { typeId } = ev;
if (typeId === "minecraft:painting") {
world.sendMessage("絵画が破壊されました。");
}
});
上記に登録オプションを使用した例
import { world } from "@minecraft/server";
world.afterEvents.entityRemove.subscribe((ev) => {
world.sendMessage("絵画が破壊されました。");
}, {
entityTypes: ["minecraft:painting"]
});
EntitySpawn
説明
エンティティがスポーンした時に実行されるイベント
例文
牛が繁殖した時にメッセージを送信する
import { world, EntityInitializationCause } from "@minecraft/server";
world.afterEvents.entitySpawn.subscribe((ev) => {
const { entity, cause } = ev;
if (cause === EntityInitializationCause.Born && entity.typeId === "minecraft:cow") {
const { x, y, z } = entity.location;
world.sendMessage(`(${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}) で牛の子が誕生しました!`);
}
});
Explosion
説明
爆発が発生した時に実行されるイベント
イベントデータ
-
getImpactedBlocks(): Block[]
爆発により破壊されたブロックの配列を取得する関数
但し、Block
クラスの配列である為、爆発前のブロック情報を取得することは出来ません。
爆発前のブロックの情報を扱いたい場合はBlockExplode
を使用するか、ビフォーイベントを使用してください。 -
readonly dimension: Dimension
爆発が発生したディメンション -
readonly source?: Entity
爆発したエンティティ
例文
tntが爆発した時に爆発した座標と破壊されたブロックの数を送信する
import { world } from "@minecraft/server";
world.afterEvents.explosion.subscribe((ev) => {
const { source } = ev;
if (source?.typeId === "minecraft:tnt") {
const { x, y, z } = source.location;
const blocks = ev.getImpactedBlocks();
world.sendMessage(`TNTが (${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}) で ${blocks.length}個 のブロックを破壊しました。`);
}
});
ProjectileHitBlock
説明
投擲物がブロックにヒットした時に実行されるイベント
イベントデータ
-
getBlockHit(): BlockHitInformation
投擲物がブロックにヒットした時の情報を取得する関数 -
readonly dimension: Dimension
投擲物がブロックにヒットしたディメンション -
readonly location: Vector3
投擲物がブロックにヒットした座標 -
readonly hitVector: Vector3
投擲物がブロックにヒットした向き -
readonly source?: Entity
ブロックにヒットした投擲物を投擲したエンティティ -
readonly projectile: Entity
ブロックにヒットした投擲物
例文
プレイヤーが投擲した矢が(0, 0, 0)
のブロックにヒットした時、プレイヤーにメッセージを送信する
import { world } from "@minecraft/server";
world.afterEvents.projectileHitBlock.subscribe((ev) => {
const { source, projectile, location } = ev;
if (!(source instanceof Player)) return;
if (projectile.typeId !== "minecraft:arrow") return;
if (location.x === 0 && location.y === 0 && location.z === 0) {
source.sendMessage("矢がヒットしました!");
}
});
ProjectileHitEntity
説明
投擲物がエンティティにヒットした時に実行されるイベント
イベントデータ
-
getBlockHit(): BlockHitInformation
投擲物がエンティティにヒットした時の情報を取得する関数 -
readonly dimension: Dimension
投擲物がエンティティにヒットしたディメンション -
location: Vector3
投擲物がエンティティにヒットした座標 -
readonly hitVector: Vector3
投擲物がエンティティにヒットした向き -
readonly source?: Entity
エンティティにヒットした投擲物を投擲したエンティティ -
readonly projectile: Entity
エンティティにヒットした投擲物
例文
矢がエンティティにヒットした時、ヒットしたエンティティのtypeIdを送信する
import { world } from "@minecraft/server";
world.afterEvents.projectileHitEntity.subscribe((ev) => {
const { projectile } = ev;
const entity = ev.getEntityHit().entity;
if (!entity?.isValid) return;
if (projectile.typeId === "minecraft:arrow") {
// 例) minecraft:cow に矢がヒットしました。
world.sendMessage(`${entity.typeId} に矢がヒットしました。`)
}
});
プレイヤー関連
ChatSend
説明
プレイヤーがチャットを送信した時に実行されるイベント
/say
や/tell
等でのメッセージ送信では実行されません。
例文
チャット内容をコンソールに出力する
import { world } from "@minecraft/server";
world.afterEvents.chatSend.subscribe((ev) => {
const { sender, message } = ev;
console.log(`<${sender.name}> ${message}`);
});
ItemCompleteUse
説明
プレイヤーが溜めが可能なアイテム(弓、トライデント、食料等)を溜め切った時に実行されるイベント
例文
プレイヤーが食べ物を食べ切らなかった時に、そのアイテムのtypeIdを送信する
import { world } from "@minecraft/server";
world.afterEvents.itemCompleteUse.subscribe((ev) => {
const { itemStack, source } = ev;
if (itemStack.hasComponent("food")) {
// 例) Steve が minecraft:apple を食べました。
world.sendMessage(`${source.name} が ${itemStack.typeId} を食べました。`);
}
});
ItemReleaseUse
説明
溜めが可能なアイテム(弓、トライデント、食料等)を、溜めた後に離した時に実行されるイベント
現在何らかの影響で、弓やトライデント、クロスボウ等の投擲物を溜めた後に離しても、このイベントは実行されません。
例文
プレイヤーが食べ物を食べ切らなかった時に、そのアイテムのtypeIdを送信する
import { world } from "@minecraft/server";
world.afterEvents.itemReleaseUse.subscribe((ev) => {
const { itemStack, source, useDuration } = ev;
if (!itemStack.hasComponent("food")) return;
if (useDuration > 0) {
// 例) Steve が minecraft:apple を食べ切りませんでした。
world.sendMessage(`${source.name} が ${itemStack.typeId} を食べ切りませんでした。`);
}
});
ItemStartUse
説明
溜めが可能なアイテム(弓、トライデント、食料等)を、溜め始めた時に実行されるイベント
例文
プレイヤーが弓を溜め始めた時にメッセージを送信する
import { world } from "@minecraft/server";
world.afterEvents.itemStartUse.subscribe((ev) => {
const { itemStack, source } = ev;
if (itemStack.typeId === "minecraft:bow") {
// 例) Steve が矢を溜め始めました。
world.sendMessage(`${source.name} が弓を溜め始めました。`);
}
});
ItemStopUse
説明
溜めが可能なアイテム(弓、トライデント、食料等)を、溜め中に離した、若しくは溜め終えた時に実行されるイベント
例文
プレイヤーが弓で矢を発射した時にメッセージを送信する
import { world } from "@minecraft/server";
world.afterEvents.itemStopUse.subscribe((ev) => {
const { itemStack, source, useDuration } = ev;
if (itemStack?.typeId === "minecraft:bow" && useDuration <= (72000 - 3)) { // 弓は3tick以上溜めると矢を発射する
// 例) Steve が矢を発射しました。
world.sendMessage(`${source.name} が矢を発射しました。`);
}
});
ItemUse
説明
アイテムを使用した時に実行されるイベント
アイテムが溜められるか否かに関わらず実行されます。
アイテムを持った状態で右クリックをすると、基本的にこのイベントが実行されます。
但し、アイテムをブロックに対して使用した時、このイベントは実行されません。
例文
プレイヤーがホットバーからダイヤモンドのヘルメットを着用した時にメッセージを送信する
(インベントリ欄から着用した時は検知されない)
import { world } from "@minecraft/server";
world.afterEvents.itemUse.subscribe((ev) => {
const { itemStack, source } = ev;
if (itemStack.typeId === "minecraft:diamond_helmet") {
// 例) Steve がダイヤモンドのヘルメットを着用しました。
world.sendMessage(`${source.name} がダイヤモンドのヘルメットを着用しました。`);
}
});
ItemStartUseOn
説明
ブロックに対してアイテムを使用し始めた時に実行されるイベント
プレイヤーが素手の場合でも実行されます。
但し、ブロックに対して影響がある場合に限ります。
これには、ブロックを設置した場合も含みます。
例文
オークのボタンを押し始めた時、プレイヤーにメッセージを送信する
import { world } from "@minecraft/server";
world.afterEvents.itemStartUseOn.subscribe((ev) => {
const { source, block } = ev;
if (block.typeId === "minecraft:wooden_button") {
source.sendMessage("オークのボタンを押し始めました。");
}
});
ItemStopUseOn
説明
プレイヤーがブロックに対してアイテムを使用し終えた時に実行されるイベント
プレイヤーが素手の場合でも実行されます。
但し、ブロックに対して影響がある場合に限ります。
また、これにはブロックを設置した場合も含みます。
現在何らかの影響で、プレイヤーがディメンションを移動した時にも実行されます。
例文
オークのボタンを押し終えた時、プレイヤーにメッセージを送信する
import { world } from "@minecraft/server";
world.afterEvents.itemStopUseOn.subscribe((ev) => {
const { source, block } = ev;
if (block.typeId === "minecraft:wooden_button") {
source.sendMessage("オークのボタンを押し終わりました。");
}
});
PlayerBreakBlock
説明
プレイヤーがブロックを破壊した時に実行されるイベント
イベントデータ
-
readonly player: Player
ブロックを破壊したプレイヤー -
readonly block: Block
破壊されたブロックのブロック -
readonly brokenBlockPermutation: BlockPermutation
破壊されたブロックのBlockPermutation
破壊前のブロックの情報を扱いたいのであれば、block
ではなくこちらを使用してください。 -
readonly itemStackAfterBreak?: ItemStack
破壊するために使用した後アイテム
素手で破壊した、若しくはアイテムが壊れた場合undefined
になります -
readonly itemStackBeforeBreak?: ItemStack
破壊するために使用したアイテム
素手で破壊した場合はundefined
になります
例文
プレイヤーが原木を鉄の斧で破壊した時に、周辺3x3の範囲の同じ原木も破壊する
import { world } from "@minecraft/server";
const blockTypes = [
"minecraft:dark_oak_log",
"minecraft:mangrove_log",
"minecraft:jungle_log",
"minecraft:birch_log",
"minecraft:oak_log",
"minecraft:spruce_log",
"minecraft:acacia_log",
"minecraft:cherry_log",
"minecraft:pale_oak_log"
];
world.afterEvents.playerBreakBlock.subscribe((ev) => {
const { player, block, brokenBlockPermutation, itemStackBeforeBreak } = ev;
if (itemStackBeforeBreak?.typeId === "minecraft:iron_axe" && blockTypes.includes(brokenBlockPermutation.type.id)) {
for (let x = -1; x <= 1; x++) for (let y = -1; y <= 1; y++) for (let z = -1; z <= 1; z++) {
const offsetBlock = block.offset({ x, y, z });
if (!offsetBlock?.isValid || !offsetBlock.matches(brokenBlockPermutation.type.id)) continue;
const itemStackEntity = offsetBlock.getItemStack();
offsetBlock.setType("minecraft:air");
player.dimension.spawnItem(itemStackEntity, offsetBlock);
}
}
});
上記に登録オプションを使用した例
import { world } from "@minecraft/server";
world.afterEvents.playerBreakBlock.subscribe((ev) => {
const { player, block, brokenBlockPermutation, itemStackBeforeBreak } = ev;
if (itemStackBeforeBreak?.typeId === "minecraft:iron_axe") {
for (let x = -1; x <= 1; x++) for (let y = -1; y <= 1; y++) for (let z = -1; z <= 1; z++) {
const offsetBlock = block.offset({ x, y, z });
if (!offsetBlock?.isValid || !offsetBlock.matches(brokenBlockPermutation.type.id)) continue;
const itemStackEntity = offsetBlock.getItemStack();
offsetBlock.setType("minecraft:air");
player.dimension.spawnItem(itemStackEntity, offsetBlock);
}
}
}, {
blockTypes: [
"minecraft:dark_oak_log",
"minecraft:mangrove_log",
"minecraft:jungle_log",
"minecraft:birch_log",
"minecraft:oak_log",
"minecraft:spruce_log",
"minecraft:acacia_log",
"minecraft:cherry_log",
"minecraft:pale_oak_log"
]
});
PlayerPlaceBlock
説明
プレイヤーがブロックを設置した時に実行されるイベント
例文
作業台を設置した時、その上に9個作業台を設置する
import { world, BlockVolume } from "@minecraft/server";
world.afterEvents.playerPlaceBlock.subscribe((ev) => {
const { block, dimension } = ev;
if (block.typeId === "minecraft:crafting_table") {
const { x, y, z } = block.location;
dimension.fillBlocks(new BlockVolume({ x, y: y + 1, z }, { x, y: y + 9, z }), block.permutation);
}
});
上記に登録オプションを使用した例
import { world, BlockVolume } from "@minecraft/server";
world.afterEvents.playerPlaceBlock.subscribe((ev) => {
const { block, dimension } = ev;
const { x, y, z } = block.location;
dimension.fillBlocks(new BlockVolume({ x, y: y + 1, z }, { x, y: y + 9, z }), block.permutation);
}, {
blockTypes: ["minecraft:crafting_table"]
});
PlayerButtonInput
説明
特定ボタン(キーボードのキー)を押した時、又は離した時に実行されるイベント
現時点では、ジャンプボタンとスニークボタンの入力の取得をすることが出来ます。
但し、たとえジャンプやスニークが出来ない状態であっても、ボタンの入力があれば実行される点に注意してください。
例文
プレイヤーがスニークし始めた時、又はスニークし終えた時にメッセージを送信する
import { world, InputButton, ButtonState } from "@minecraft/server";
world.afterEvents.playerButtonInput.subscribe((ev) => {
const { player, button, newButtonState } = ev;
if (button !== InputButton.Sneak) return;
if (newButtonState === ButtonState.Pressed) {
// 例) Steve がスニークし始めました。
world.sendMessage(`${player.name} がスニークし始めました。`);
}
if (newButtonState === ButtonState.Released) {
// 例) Steve がスニークし終えました。
world.sendMessage(`${player.name} がスニークし終えました。`);
}
});
上記に登録オプションを使用した例
import { world, InputButton, ButtonState } from "@minecraft/server";
world.afterEvents.playerButtonInput.subscribe((ev) => {
const { player, newButtonState } = ev;
if (newButtonState === ButtonState.Pressed) {
// 例) Steve がスニークし始めました。
world.sendMessage(`${player.name} がスニークし始めました。`);
}
if (newButtonState === ButtonState.Released) {
// 例) Steve がスニークし終えました。
world.sendMessage(`${player.name} がスニークし終えました。`);
}
}, {
buttons: [InputButton.Sneak]
});
PlayerDimensionChange
説明
プレイヤーがディメンション間を移動した時に実行されるイベント
例文
現在のディメンションをプレイヤーに送信する
import { world } from "@minecraft/server";
world.afterEvents.playerDimensionChange.subscribe((ev) => {
const { player, toDimension } = ev;
// 例) 現在のディメンションは minecraft:nether です。
player.sendMessage(`現在のディメンションは ${toDimension.id} です。`);
});
PlayerEmote
説明
プレイヤーがエモートした時に実行されるイベント
例文
プレイヤーがエモートした時にメッセージを送信する
import { world } from "@minecraft/server";
world.afterEvents.playerEmote.subscribe((ev) => {
const { player } = ev;
const { x, y, z } = player.location;
// Steve が (32.05, 62.00, 51.94)
world.sendMessage(`${player.name} が (${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}) でエモートしています!`);
});
PlayerGameModeChange
説明
プレイヤーのゲームモードが変化した時に実行されるイベント
例文
プレイヤーのゲームモードがクリエイティブになった時、OP権限が無ければ元のゲームモードに戻し、プレイヤーにメッセージを送信する
import { world, GameMode } from "@minecraft/server";
world.afterEvents.playerGameModeChange.subscribe((ev) => {
const { player, toGameMode, fromGameMode } = ev;
if (toGameMode === GameMode.creative && !player.isOp()) {
player.setGameMode(fromGameMode);
player.sendMessage("権限が不足している為、クリエイティブになることが出来ませんでした。");
}
});
PlayerInputModeChange
説明
プレイヤーが操作方法を変更した時に実行されるイベント
例文
import { world } from "@minecraft/server";
world.afterEvents.playerInputModeChange.subscribe((ev) => {
const { player, newInputModeUsed, previousInputModeUsed } = ev;
// 例) Steve が操作方法を KeyboardAndMouse から Gamepad に変更しました。
world.sendMessage(`${player.name} が操作方法を ${previousInputModeUsed} から ${newInputModeUsed} に変更しました。`);
});
PlayerInputPermissionCategoryChange
説明
プレイヤーの入力権限が変化した時に実行されるイベント
例文
入力権限が変更された時、プレイヤーにメッセージを送信する
import { world, InputPermissionCategory } from "@minecraft/server";
world.afterEvents.playerInputPermissionCategoryChange.subscribe((ev) => {
const { player, category, enabled } = ev;
const key = Object.keys(InputPermissionCategory).find((key) => InputPermissionCategory[key] === category);
if (enabled) {
// 例) Sneak の操作が解放されました。
player.sendMessage(`${key} の操作が解放されました。`);
}
else {
// 例) Sneak の操作が制限されました。
player.sendMessage(`${key} の操作が制限されました。`);
}
});
PlayerInteractWithBlock
説明
ブロックに対してインタラクトした時に実行されるイベント
イベントデータ
-
readonly player: Player
ブロックにインタラクトしたプレイヤー -
readonly itemStack?: ItemStack
プレイヤーがブロックにインタラクトする為に使用したアイテム
素手でインタラクトした場合はundefined
になります -
readonly beforeItemStack?: ItemStack
プレイヤーがブロックにインタラクトする為に使用した後のアイテム
素手でインタラクトした、若しくはアイテムが壊れた場合undefined
になります -
readonly block: Block
プレイヤーがインタラクトしたブロック -
readonly blockFace: Direction
プレイヤーがインタラクトしたブロックの面の方角 -
readonly faceLocation: Vector3
プレイヤーがインタラクトしたブロックの面の座標 -
readonly isFirstEvent: boolean
このインタラクトが長押しの中で最も始めか否か
例文
プレイヤーがスニークしながら看板にインタラクトした時、看板にコマンドが記述されているなら実行し、メッセージを送信する
また、コマンド実行時にエラーが発生した時、プレイヤーにエラーメッセージを送信する
import { world } from "@minecraft/server";
world.afterEvents.playerInteractWithBlock.subscribe((ev) => {
const { player, block } = ev;
if (!player.isSneaking) return;
const sign = block.getComponent("sign");
const command = sign?.getText();
if (command?.startsWith("/")) {
try {
player.runCommand(command.slice(1));
player.sendMessage(`§a正常に実行されました。: ${command}`);
}
catch (error) {
player.sendMessage(`§c${error.message}`);
}
}
});
PlayerInteractWithEntity
説明
エンティティに対してインタラクトした時に実行されるイベント
例文
プレイヤーがウシに小麦を上げた時、プレイヤーにリアクションメッセージを送信する
import { world } from "@minecraft/server";
world.afterEvents.playerInteractWithEntity.subscribe((ev) => {
const { player, target, beforeItemStack } = ev;
if (target.typeId === "minecraft:cow" && beforeItemStack?.typeId === "minecraft:wheat") {
player.sendMessage("<ウシ> ムシャムシャ..");
}
});
PlayerJoin
説明
プレイヤーがワールドに参加した時に実行されるイベント
扱えるプレイヤーのデータが名前とidと限られている為、プレイヤーの情報を扱いたい場合、PlayerSpawn
と、イベントデータのinitialSpawn
を併用して下さい。
例文
プレイヤーの参加を通知する
import { world } from "@minecraft/server";
world.afterEvents.playerJoin.subscribe((ev) => {
const { playerName } = ev;
// 例) Steve が間もなく参加します。
world.sendMessage(`${playerName} が間もなく参加します。`);
});
PlayerLeave
説明
プレイヤーがワールドを抜けた時に実行されるイベント
扱えるプレイヤーのデータが名前とidと限られている為、プレイヤーの情報を扱いたい場合、ビフォーイベントを使用して下さい。
例文
プレイヤーの退出を通知する
import { world } from "@minecraft/server";
world.afterEvents.playerLeave.subscribe((ev) => {
const { playerName } = ev;
// 例) Steve が退出しました。
world.sendMessage(`${playerName} が退出しました。`)
});
PlayerSpawn
説明
プレイヤーがリスポーンした時に実行されるイベント
これには、プレイヤーが参加した時も含みます
例文
プレイヤーの参加を通知する
import { world } from "@minecraft/server";
world.afterEvents.playerSpawn.subscribe((ev) => {
const { player, initialSpawn } = ev;
if (initialSpawn) {
// 例) Steve が参加しました。
world.sendMessage(`${player.name} が参加しました。`);
}
});
プレイヤーがリスポーンした時、5秒間プレイヤーに耐性を付与する
import { world, TicksPerSecond } from "@minecraft/server";
world.afterEvents.playerSpawn.subscribe((ev) => {
const { player, initialSpawn } = ev;
if (!initialSpawn) {
player.addEffect("minecraft:resistance", TicksPerSecond * 5, { showParticles: false, amplifier: 255 });
}
});
SystemAfterEvents
システム関連
ScriptEventReceive
説明
/scriptevent
を実行した時に実行されるイベント
コマンドの説明になりますが、構文は
/scriptevent <messageId: string> <message: string>
となっています。
messageId
はminecraft
以外の名前空間識別子を付ける必要があります。(例えば、id:test
やcmd:test
等としなければいけません。)
イベントデータ
-
readonly id: string
/scriptevent <messageId> message
の部分の文字列 -
readonly message: string
/scriptevent messageId <message>
の部分の文字列 -
readonly sourceType: ScriptEventSource
/scriptevent
を実行した媒体 -
readonly sourceEntity?: Entity
/scriptevent
を実行したエンティティ -
readonly initiator?: Player
/scriptevent
をNPCを介して実行したプレイヤー -
readonly sourceBlock?: Block
/scriptevent
を実行したブロック(主にコマンドブロック)
例文
/scriptevent cmd:give <itemType> <amount>
の構文でプレイヤーが実行した時、実行したプレイヤーにアイテムを渡す
import { system, Player, ItemTypes, ItemStack } from "@minecraft/server";
system.afterEvents.scriptEventReceive.subscribe((ev) => {
const { id, message, sourceEntity } = ev;
if (!(sourceEntity instanceof Player)) return;
const args = message.split(/ +/);
if (id === "cmd:give") {
const itemType = ItemTypes.get(args[0]);
if (!itemType) {
sourceEntity.sendMessage("§cアイテム名が無効です。");
return;
}
const amount = Number(args[1]);
if (Number.isNaN(amount) || amount < 1 || amount > 64) {
sourceEntity.sendMessage("§cアイテムの個数が無効です。");
return;
}
const itemStack = new ItemStack(itemType, amount);
const container = sourceEntity.getComponent("inventory")?.container;
container.addItem(itemStack);
sourceEntity.sendMessage(`${itemType.id}を${amount}個受け取りました。`);
}
});
最後に
ここまで読んで頂き有難うございました。
ScriptAPIにおいて、イベントはとても重要な役割を担っており、同時に初心者が躓きやすい部分でもあります。
この記事を通してイベントとは何かを理解出来、また、どのような使い方なのかということが分かって頂ければとても幸いです。
また、誤字脱字、その他誤っている箇所があれば、コメント等にて教えて頂けると幸いです。
次回は引き続きビフォーイベントについて解説していくつもりですので、今後ともよろしくお願い致します。