ルッキーのコマンドメモ

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

(マイクラ コマンド・データパック) セレクタ引数dx,dy,dzの使い方

セレクタ引数のdx,dy,dzの使い方

今回はセレクタ引数のdx,dy,dzの使い方や、似たような引数であるdistance引数との違い、応用例などについて紹介していきます。

目次

dx,dy,dz引数とは

dx,dy,dzといった引数は基準点からの立方体型の範囲を指定してその範囲内に当たり判定があるエンティティを対象とするというセレクタです。

特徴的な点として、エンティティの座標ではなく、当たり判定があるかどうかで対象を取るかを決めるという点があります。

そのため、魔法や銃のようなアイテムを作る場合のhit判定を取るためにこのセレクタが使われることが多いです。

distance引数との違い

以上で挙げたように、dx,dy,dzでは当たり判定を基準とするという点でエンティティの座標を基準とするdistance引数とは大きく異なります。

また、dx,dy,dzは立方体型の範囲を選択するのに対して、distance引数は球形の範囲を選択するという特徴もあります。

dx,dy,dzのつまずきやすい仕様

このdx,dy,dzという引数は上記に挙げたような特徴から、それなりに使う場面がある引数です。

しかし、この引数は少し面倒な仕様を持っていて何も考えずに使ってしまうと思い通りに動いてくれないことがよくあります。

実際にコマンドを実行しながら解説していきます。

1辺が1より小さい範囲を指定できない

特につまずきやすい仕様が、1辺が1より小さい範囲が指定できないという点です。

このセレクタ引数の使おうと思ったとき、よく以下のようなコマンドを使うことが思い浮かびます

# bulletというタグがついたエンティティに触れているエンティティを発光させる
execute as @e[tag=bullet] at @s run effect give @e[tag=!bullet,dx=0.01,dy=0.01,dz=0.01] glowing 1 1

これは銃を作る場合を想定して、銃の玉として扱うエンティティにbulletというタグをつけ、これに触れたエンティティを発光させるというコマンドの失敗例となります。

一見、bulletというタグがついたエンティティがいる座標から一辺が0.01の立方体の中にいるエンティティを対象ととるというコマンドになっているように見えます。

しかし、実行してみるとこのような結果になります。

実行結果。なぜか一部の防具立てが反応する

真ん中の白いエフェクトがbulletというタグのついたエンティティがいる場所になります。

本来ならどの防具立ても中心の白いエフェクトには触れていないので、どの防具立ても発行しないはずです。

しかし、一部の防具立ては発光してしまいます。

これは、dx,dy,dzという引数を指定した場合、最小でも必ず1辺が1の立方体を指定してしまうという使用によるものです。

これを覚えていないと、なぜか思った通りの挙動をしてくれず、原因もわからないため混乱することになります。

必ず正の方向に0から1の範囲は対象になる

上記のように、dx,dy,dzという引数は1辺が1より小さい範囲を指定できないという面倒な仕様があります。

では、次にこのようなコマンドを実行することを考えてみます。

# bulletというタグがついたエンティティからz方向に0から5,x方向に0から-2の範囲に触れているエンティティを発光させる
execute as @e[tag=bullet] at @s run effect give @e[tag=!bullet,dx=-2,dz=5] glowing 1 1

コマンド上ではz軸方向に0から5,x方向に-2から0の範囲に当たり判定があるエンティティが発光するはずです。

しかし、実行結果は以下のようになります。(左がx軸正方向、上がz軸正方向です。)

実行結果。 なぜかx方向で1の座標にある防具立ても反応する

x軸の正方向は指定していないはずですが、x座標が1のところにある防具立ても反応しています。

このように、たとえ負の値を引数に入れたとしても、必ず正方向に0から1の範囲が指定されてしまうという仕様があります。

当たり判定のないエンティティを指定できない

これは、仕様というよりは当たり前のことなのですが、たまにつまずくので一応紹介します。

dx,dy,dzは当たり判定があるかで検知を行うため、そもそも当たり判定がないエンティティは検知することができません。

全ての防具立てに対してMarkerというnbtを1にして、必ず正の方向に0から1の範囲は対象になるで使用したコマンドをもう一度実行してみます。

結果は以下のようになります。

実行結果。範囲内に存在するはずの防具立ても反応しない

先ほどは反応していたはずの防具立ても反応しません。

これは防具立てのMarkerというnbtを1にすると、当たり判定がなくなるため、dx,dy,dzでは検知できなくなるからです。

使用例

このdx,dy,dzといった引数の使用例を紹介します。

実行者の視線先にいるエンティティを発光させる

視線の先にいるモブやエンティティを調べるで紹介したコマンドと全く同じものです。

再帰呼び出しを利用して、プレイヤの視線の方向にmarkerを飛ばし、markerに当たり判定が触れたエンティティを対象に発光させています。

check.mcfunction

# 検知用にタグのついたmarkerを召喚する
execute at @s anchored eyes run summon marker ~ ~ ~ {Tags:["marker"]}

# マーカーの向きを実行者の視線の方向にする
execute at @s anchored eyes run data modify entity @e[tag=marker,sort=nearest,limit=1] Rotation set from entity @s Rotation

# ループ用のカウントを設定する
scoreboard players set count test 0
scoreboard players set loop test 50

#実行者を検知してしまわないようにtagをつけておく
tag @s add executer

# 再帰呼び出しにより視線先のエンティティを探す
execute at @s anchored eyes positioned ^ ^ ^ as @e[tag=marker,sort=nearest,limit=1] if score count test < loop test run function <名前空間>:check_loop

# 検知用のmarkerをkill
kill @e[type=marker,tag=marker]

# つけたtagを消す
tag @e[tag=executer] remove executer

# 検知したエンティティに発光エフェクトをつける
effect give @e[tag=detected] glowing 1 1

# 検知したエンティティからタグを消去する
tag @e[tag=detected] remove detected

# スコアをリセットする
scoreboard players reset count test
scoreboard players reset loop test

check_loop.mcfunction

# 検知用エンティティを視線先に0.1ブロックtpさせる
tp @s ^ ^ ^0.1

# 検知用エンティティを中心とした0.01×0.01×0.01の立方体の中に当たり判定があるエンティティにdetectedタグをつける
execute at @s positioned ~0 ~0 ~0 as @e[tag=!marker,tag=!executer,dx=0] positioned ~-0.99 ~-0.99 ~-0.99 if entity @s[dx=0] run tag @s add detected

# ループ処理。 detectedタグがついたエンティティがいなければ継続する
scoreboard players add count test 1
execute unless entity @e[tag=detected] at @s if score count test < loop test run function <名前空間>:check_loop

特に重要なのがこのコマンドです。

execute at @s positioned ~0 ~0 ~0 as @e[tag=!marker,tag=!executer,dx=0] positioned ~-0.99 ~-0.99 ~-0.99 if entity @s[dx=0] run tag @s add detected

このコマンドはdx,dy,dzの使用を利用して、markerにエンティティが触れたかを検知している部分になります。

1辺が1より小さい範囲を指定できないという仕様からdx=0という指定は、正方向に1辺1の立方体の範囲を指定することになります。

これで検知されたエンティティのうち、さらに各方向に-0.99ずつした座標から正方向に1辺1の立方体の範囲でも検知できるエンティティを指定することにより、実質的に1辺が0.01の立方体に触れているエンティティを対象としています。

今回は見つけたエンティティを発光させるだけですが、これをdamageコマンドにしたり、ループ時にmarkerにパーティクルを出したりすることで、魔法や銃の球を作ることができます。

まとめ

dx,dy,dzという引数は指定した範囲内に当たり判定があるエンティティを対象としてコマンドを実行することができます。

この当たり判定があるかを対象とするという使用から、視線の先にいるエンティティの検知や、銃や魔法のhit判定を調べるのにこの引数を応用することができます。