0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

データパック開発報告:egg ver.1.2 / 01「3D関連編」

0
Last updated at Posted at 2025-11-17

データパック for データパック

egg ver. 1.2 公開中です!

今回はこの自作「データパック for データパック」である egg について解説していきます。
リファレンスなどは Notion にて公開していますが、ここではもっと具体的に説明できればと思います。

気軽に雑多に欲しい機能を

データパック開発に初挑戦する初学者にとって熟練者ができているけどハードルの高いことというのは山のようにあります。

険しいながら、それが熟練者への道のりなのかもしれません…が、それにしたってちょっと険しすぎかなと思います。

egg はそのハードルを少し下げるためのデータパックです。

欲しい機能をピンポイントに、最小の記述で実現することを目標にして現在も機能追加中です。
もし、欲しい機能が egg に実装されていればぜひとも試しに使ってみてください!

MIT ライセンス

egg は MIT ライセンスで提供されます。

ライセンスの解釈は人によります。
そのため、ライセンスを読んで不明点があれば、作者に聞くのが無難です。

以下は、私の解釈であり egg を使う上で私がOKだと言える使い方で、皆様が egg を利用する上での指標になればと思います。

egg に同梱されている LICENSE テキストファイルをあなたのデータパックにも同梱して「egg の技術は私のものだ!」と主張しなければ利用・改変どちらも可能な、緩めのライセンスです。
あなたのデータパックに気軽に組み込めるかと思います。

ここからは、あくまで私がOKとしているケースです。他の MIT ライセンスデータパックは別の話になるので、不明点については個別に作者にお問い合わせください。

egg 本体を同梱するのはOK

LICENSE テキストも同梱されるので問題ありません。

egg 名前空間を自分のデータパック内に組み込むのもOK

LICENSE テキストを同梱していれば問題ありません。
前提MODのように小分けにされたデータパックを別途導入するのは手間と思う人は少なくありません。
一つのデータパックに一括で機能が入っているのはスマートです。ただ、egg 内の minecraft 名前空間も一緒に組み込まないと動いてくれないので気をつけてください。

egg の一部を自分のデータパックに組み込むのもOK

LICENSE テキストを同梱していれば問題ありません。
例えば egg:math 機能だけ欲しい場合はその部分だけ切り出して組み込んでも問題ありません。データパックで処理速度が致命的になる可能性がある以上、無駄な機能を一緒に組み込むデメリットがあるのは事実です。
ただ、ディレクトリごとの依存関係が存在するので、うまく切り出す必要があります。

egg を改良するのもOK

LICENSE テキストを同梱していれば問題ありません。
MIT ライセンスは改変も可能です。

機能紹介

3D 関連

3次元空間での処理で便利なものをまとめてあります。

egg:motion_from_rotation

NBTデータタグの Rotation からその方向への Motion を取得します。
移動量は 1 [m/tick] で固定なので、移動量を調整したい場合は function egg:scale_motion で scale 倍してください。
この機能を使うことで、プレイヤーやモブの向いている方向にエンティティを投擲できるようになります。
入力関連の機能と組み合わせることで、火の玉を狙った方向に発射させるカスタムアイテムを作ることも可能です。

使い方は以下のとおりです

throw_snowball.mcfunction
# コマンド実行者 @s の Rotation を <<rotation に設定
data modify storage egg:3d/motion_from_rotation <<rotation set from entity @s Rotation

# <<rotation から >>motion に変換
function egg:3d/motion_from_rotation

# 雪玉の Motion に >>motion を設定
execute at @s summon minecraft:snowball \
  run data modify entity @s Motion set from storage egg:3d/motion_from_rotation >>motion

egg:scale_motion

NBTデータタグの Motion を scale 倍します。
function egg:motion_from_rotation で取得できる Motion 移動量は 1 [m/tick] で固定です。移動量を変更したい場合はこの関数で調整してください。

使い方は以下のとおりです

throw_snowball.mcfunction
# コマンド実行者 @s の Rotation を <<rotation に設定
data modify storage egg:3d/motion_from_rotation <<rotation set from entity @s Rotation

# <<rotation から >>motion に変換
function egg:3d/motion_from_rotation

# <<motion に対象の Motion 相当のデータタグを設定
data modify storage egg:3d/scale_motion <<motion set from storage egg:3d/motion_from_rotation >>motion

# <<scale に 1.5 の倍率を設定
data modify storage egg:3d/scale_motion <<scale set value 1.5

# Motion の移動量を 1.5 m/tick に増幅
function egg:3d/scale_motion

# 雪玉の Motion に >>motion を設定
execute at @s summon minecraft:snowball \
  run data modify entity @s Motion set from storage egg:3d/scale_motion >>motion

egg:rotation_from_motion

NBTデータタグの Motion からその進行方向への Rotation を取得します。
主に投げナイフのような、剣の外観をした飛翔体の切っ先の向きを表現することに利用できます。
throwing_knife.png
こういうのが作りやすくなりますよ。

使い方は以下の通りです。
上記全ての関数を組み合わせた投げナイフのサンプルになります。

data/xxx/knife/throw.mcfunction
# Rotation から Motion を取得
data modify storage egg:3d/motion_from_rotation <<rotation set from entity @s Rotation
function egg:3d/motion_from_rotation

# Motion の移動量を 1.5 m/tick に増幅
data modify storage egg:3d/scale_motion <<motion set from storage egg:3d/motion_from_rotation >>motion
data modify storage egg:3d/scale_motion <<scale set value 1.5
function egg:3d/scale_motion

# ナイフ召喚(ただの雪玉)
# 雪玉以外のエンティティにする場合は
#   summon         の ~-0.125
#   transformation の -0.125f
# をエンティティサイズの半分の値に変更してください
# 着弾時バーティクルがバグりますが簡単のためこれでご容赦ください
# リソースパックで透明画像に差し替えるときれいになります
summon minecraft:snowball ~ ~-0.125 ~ {\
  Item:{id:"minecraft:snowball",count:1,components:{item_model:"minecraft:air"}},\
  Passengers:[\
    {\
      id:"minecraft:item_display",\
      Tags:["xxx.knife","xxx.uninitialized"],\
      item:{id:"minecraft:iron_sword",count:1},\
      transformation:[0f,0f,-1f,0f,-0.7071067812f,-0.7071067812f,0f,-0.125f,-0.7071067812f,0.7071067812f,0f,0f,0f,0f,0f,1f],\
    }\
  ]\
}

# tick スコアを初期化
scoreboard players set @e[tag=xxx.uninitialized] xxx.knife.tick 0
# ナイフに Motion を設定
execute as @e[tag=xxx.uninitialized] on vehicle run data modify entity @s Motion set from storage egg:3d/scale_motion >>motion

# 初期化完了
tag @e[tag=xxx.uninitialized] remove xxx.knife.uninitialized
data/xxx/knife/has_vehicle.mcfunction
# 乗り物である雪玉が存在するかどうか
execute on vehicle run return 1
return 0
data/xxx/knife/update_rotation.mcfunction
# 雪玉の Motion から Rotation を取得
execute on vehicle run data modify storage egg:3d/rotation_from_motion <<motion set from entity @s Motion
function egg:3d/rotation_from_motion
data modify entity @s Rotation set from storage egg:3d/rotation_from_motion >>rotation
data/xxx/knife/delete.mcfunction
# 雪玉と表示エンティティを破壊
execute on vehicle run kill @s
kill @s
data/xxx/knife/update.mcfunction
# 着弾時にパーティクルやダメージを発生させたい場合は以下のようにしてください
# 着弾点は雪玉の中心なので positioned ~ ~-0.125 ~ とする必要があります
# 雪玉以外のエンティティを使う場合はそれの半分の高さを設定してください
# execute unless function xxx:knife/has_vehicle at @s positioned ~ ~-0.125 ~ run function ...

# 乗り物の雪玉が着弾していたら処理終了
execute unless function xxx:knife/has_vehicle run return 0

# Rotation 更新
execute if score @s xxx.knife.tick matches 0 run function xxx:knife/update_rotation

# tick 更新
scoreboard players add @s xxx.knife.tick 1
scoreboard players operation @s xxx.knife.tick %= #4 --

# 処理継続
return 1
data/xxx/load.mcfunction
# 汎用 スコア定義
scoreboard objectives add -- dummy

# tick スコア定義
scoreboard objectives add xxx.knife.tick dummy

# 定数定義
scoreboard players set #4 -- 4
data/xxx/tick.mcfunction
# 投げナイフ更新
# function xxx:knife/update が 0 を返せば function xxx:knife/delete が実行されます
execute as @e[type=item_display,tag=xxx.knife] unless function xxx:knife/update run function xxx:knife/delete

「当たり判定の雪玉」に「本体のアイテム表示ディスプレイ」が乗った状態で召喚され、様々に処理されます。
雪玉を本体にしないのは着弾時にコマンドを挟む余地なく消滅してしまうからです。

着弾時に本体の表示ディスプレイだけが残った状態になり、雪玉が消滅して乗っていない状態であることを感知したら着弾用の関数を実行し本体を破壊します。

投げナイフの Rotation 更新は 4tick に1回ペースで行われます。
3D関連の関数は内部コマンドの実行数がかなり多く、頻繁に実行すると高負荷とコマンド数限界の問題に直面します。
ある程度それっぽく表現できれば十分な要素なので、常に呼び出す必要はありません。

あとは function xxx:load と function xxx:tick を #minecraft:load と #minecraft:tick に登録します。

data/minecraft/tags/function/load.json
{
  "replace": false,
  "values": [
    "xxx:load"
  ]
}
data/minecraft/tags/function/tick.json
{
  "replace": false,
  "values": [
    "xxx:tick"
  ]
}

これで実装は完了です。
試しに

/execute positioned ~ ~1.62 ~ run function xxx:knife/summon

を実行すると、目線の方向に投げナイフ(雪玉)を投擲します。

プレイヤーの位置 at @s はプレイヤーの足元になるため、目線に位置を調整する必要があります。
直立時の目線はおおよそ ~ ~1.62 ~ のようです。
スニーク時は更に 0.3 下がって ~ ~1.32 ~ になるようです。
厳格に「この高さ!」という定義を見つけられなかったので、情報募集中です。

まとめ

Rotation から Motion を得られると「視線方向に投擲」が可能になります。
Motion から Rotation を得られると「進行方向を向くエンティティ表現」が可能になります。

本当に始めたての頃、私は物を投擲することすらまともにできず苦労した思い出があります。

様々な投擲方法はネット上に存在しますが、特殊な操作に依存したり、何らかの条件があったり…とにかく難しいのです!
初学者にとって「無条件でコマンド一発の単体で起動させることができる独立した実装」に到達することは大きなハードルだと…私は今でも思います。

だからそれらを実現する力を3つの関数に集約しました。

使う側は極限までシンプルに!面倒事は egg がやるよ!

データパックは面倒事が多いのです。
本当にやりたいことをするまで辿り着くのも大変な時があると思います。
egg は今後もそういう面倒事の手助けのため更新していく所存です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?