ルッキーのコマンドメモ

主にマイクラのコマンドやデータパックに関することを書いていきます。

(マイクラ コマンド・データパック)セレクタの使い分け @aと@e

セレクタの使い分け

データパックを作る際に度々使用することになるセレクタ。今回はその中でも@aと@eの違いについて説明していきます。

目次

@aセレクタ

@aセレクタはワールド内の全てのプレイヤを対象とするセレクタです。 プレイヤのみに対してコマンドを実行したい場合には大抵こちらのセレクタを使うと思います。

@eセレクタ

@eセレクタはワールド内のすべてのエンティティを対象とするセレクタです。 プレイヤ以外のモブを対象としたい場合やプレイヤとモブを同じように扱いたい場合に利用することになると思います。
また、セレクタの引数でエンティティのタイプを指定することにより特定のエンティティのみを指定でき、 @e[type=player]とすれば@aと同様にワールド内のすべてのプレイヤを指定することができます。

@aと@e[type=player]

前述したようにプレイヤのみを指定してコマンドを実行したい場合には@aセレクタか@e[type=player]によって対象を指定することができます。
では、この二つのセレクタには違いはないのでしょうか。

@aと@eの大きな違い

実は上記の二つのセレクタには大きな違いがあります。
それは死亡中のプレイヤを対象とできるかという点です。
@aセレクタでは、死亡中のプレイヤも含んだワールド内の全プレイヤを指定します。
一方、@eセレクタでは、死亡中のエンティティを含まないワールド内の全エンティティを指定します。
この二つの違いをしっかり意識しておかないと、たまにとんでもないバグを引き起こします。

セレクタの違いによって引き起こされるバグ

2つのセレクタの違いによってバグが起きる例を紹介します。
testというスコアが1になったプレイヤをkillして、そのスコアを0にするという操作を毎tick実行することを考えます。 それぞれのfunctionファイルはこんな感じ。

@aの場合

execute as @a if score @s test matches 1 run kill @s
execute as @a if score @s test matches 1 run scoreboard players set @s test 0

@eの場合

execute as @e[type=player] if score @s test matches 1 run kill @s
execute as @e[type=player] if score @s test matches 1 run scoreboard players set @s test 0

さて、この2つを毎tick実行するとどのような挙動をするでしょうか。
一見、どちらもtestスコアが1になると1回killされるだけに見えます。
しかし、@eセレクタを使用した方は、無限にkillされ続けてしまいます。

なぜバグが起きるか

@eセレクタ死亡したプレイヤを対象として取りません。そのため、1行目でプレイヤがkillされてしまうと、2行目のtestスコアを0にするというコマンドが働かず、killされ続けてしまうのです。

@eセレクタが有用になる場面

このようなバグが発生することを考えると、毎回@aセレクタを使えば問題ないように感じます。
しかし、@eセレクタを使用した方が都合がいい場面も確かに存在します。 例えば、PVPマップを作るときなどに死亡したプレイヤはリスポーン後に5秒間無敵にしたいという場合。 functionファイルはこのようになります。

@aの場合

execute as @a if score @s deathcount matches 1 run effect give @s minecraft:resistance 5 4 
execute as @a if score @s deathcount matches 1 run scoreboard players set @s deathcount 0

@eの場合

execute as @e[type=player] if score @s deathcount matches 1 run effect give @s minecraft:resistance 5 4 
execute as @e[type=player] if score @s deathcount matches 1 run scoreboard players set @s deathcount 0

あらかじめ死亡数をカウントするスコアdeathcountを作成しているものとします。

今度は@aセレクタを使用した方はリスポーン後にエフェクトがかかりません。
@aセレクタが死亡中のプレイヤを対象にしてしまうため、死亡中のプレイヤに対してエフェクトをかけてしまうからです。
このようにリスポーン後のプレイヤを対象にコマンドを実行したい場合には@eセレクタが有効です

他のセレクタについて

ちなみに、他の@sや、@rといったセレクタは死亡中のプレイヤを対象とすることができます。 そのためexecute as @e run functionで呼び出したfunctionファイル内でプレイヤをkillした場合にも、そのfunctionファイル内で@sによって指定すれば対象を取ることができます。

まとめ

@aセレクタ死亡中のプレイヤを対象にできる一方で、@eセレクタ死亡中のプレイヤを対象にできません。
死亡してすぐにコマンドを実行したい場合には@aコマンドが、死亡してリスポーンしたときにコマンドを実行したい場合には@eコマンドが有効に働きます。
これらの違いに注意することで、思わぬバグを防ぐことができます。