Skip to content

create object

Ella Coat edited this page May 18, 2026 · 14 revisions

オブジェクトは、矢・弾・演出のマーカーみたいに 一瞬だけ場に出して消えるエンティティ をまとめて作るための仕組みだよ。ギミックにも使える。

神器・モブと違って、オブジェクトは「召喚 → 毎 tick 動く → 命中や時間切れで消える」 という流れで使い捨てるのが基本。既に作ったオブジェクトを土台にして派生 (例: 「矢」 から「炎付き矢」) を作れる仕組みもあるから、似た挙動のオブジェクトをまとめて書けるよ。

1. 事前に済ませてね

2. テンプレートを作成する

MCDatapackUtilityを利用してオブジェクトアセットのテンプレートを作成するよ。
Datapack: Create Datapack templateを実行してね。デフォルトだとShift + Alt + D -> Shift + Alt + Tを押すと動作するよ。

下記のメニューが出てくるからデータパックにテンプレートを追加するを選択してね。

image

データパックはAssetフォルダを指定。命名規則は他と同じ。

オブジェクト名の命名規則

  • <四桁のID>.<オブジェクト名(snake_case)>で名前を記述してね
  • オブジェクト名は基本的に英語に翻訳したものを使うよ
  • 各単語を_区切ってね
  • 英語に翻訳できないような物はローマ字 (ヘボン式) にしてね

テンプレートの種別では「オブジェクト/テンプレート」を選んでね。必要な処理 (summon/init/tick 等) のチェックも入れる。

これでテンプレートが Asset/data/asset/functions/object/<オブジェクト名>/~Asset/data/asset/functions/object/alias/<ID>/~ に生成されてるはずだよ。

asset/functions/object/<オブジェクト名>/
    register.mcfunction          # ID/Field/Extends 等を定義
    summon/.mcfunction           # 召喚時の処理
    init/.mcfunction             # 初期化処理 (オプション)
    tick/.mcfunction             # 毎tick処理 (オプション)
    (任意のメソッド)/.mcfunction    # 自分で追加するカスタムメソッド

asset/functions/object/alias/<ID>/
    register.mcfunction          # 実装パスへのエイリアス
    summon.mcfunction
    tick.mcfunction
    init.mcfunction
    (任意のメソッド).mcfunction

alias/ID → 実装パスの間接参照層 だよ。オブジェクトは ID で呼ばれるから、 alias がないと実体のパスが見つけられないって仕組み。中身はだいたい function asset:object/<実装パス>/<メソッド> を呼ぶだけ。

note: alias は MCDatapackUtility のテンプレート生成時に自動で作られるので、基本的に手動で作る必要はないよ。カスタムメソッドを後から追加する時だけ、自分で alias を書き足す必要がある (詳細は4.5節)。

3. オブジェクトの基本情報の設定

注: ここから先基本的に function 名は下記のような省略した形で記載するよ

Asset/data/asset/functions/object/<オブジェクト名>/register.mcfunction -> ~/register.mcf

生成されたテンプレートの~/register.mcfを編集していくよ。

register.mcfunction で設定する項目

設定名 必須 設定する型 説明 デフォルト
Extends × int[] 継承する親オブジェクトの ID (append で追加)
使うときは function asset:object/extends も併用
[] … append value 1001
ExtendsSafe × boolean 他のオブジェクトから継承されることを許可するか false … value true
IsAbstract × boolean 抽象オブジェクトとして扱う (直接召喚不可、継承用) false … value true
IsTicking × boolean tick を実行するか false … value true
ID o int オブジェクト ID - … value 1009
Field × compound カスタムフィールド (tick 等で asset:context this.<キー> で参照可能) {} … value {Speed:4,Damage:1.0d}

Field について

オブジェクト個体ごとに持つカスタムデータ。召喚時に値が割り当てられて、 tick 等から asset:context this.<キー> で参照できる。

実例: 1009.arrow の Field

data modify storage asset:object Field.Speed set value 4
data modify storage asset:object Field.Range set value 40
data modify storage asset:object Field.Color set value 16777215
data modify storage asset:object Field.ShowCritParticle set value true
data modify storage asset:object Field.Damage set value 1
data modify storage asset:object Field.AttackType set value "Physical"
data modify storage asset:object Field.ElementType set value "None"

召喚 API 側でArgument.FieldOverrideを指定すれば、個別の召喚時に Field を上書きできる。例: 「速度 2 倍の矢」「魔法の矢」 みたいな個別調整。

IsAbstract / IsTicking について

  • IsAbstract:true = 「抽象オブジェクト」 として扱う。直接召喚しようとするとエラー。継承用の親クラス (例: 1001.abstract_projectile) で使う
  • IsTicking:true = 毎 tick の処理を実行する。 tick 処理が必要なオブジェクト (= ほぼ全てのオブジェクト) で true にする。静的な装飾オブジェクトなら false

4. オブジェクトの処理を記述する

4.1. 処理一覧

イベント 呼ばれるタイミング 実装ファイル
register load 時に 1 回 (クラス定義として) register.mcfunction
summon api:object/summon で召喚された時 summon/.mcfunction
init 召喚直後の初期化処理 (ObjectInitタグが付与された状態) init/.mcfunction
tick 毎 tick (IsTicking:true の時のみ) tick/.mcfunction
カスタム asset_manager:object/call_method/run_method.m で呼び出した時 自由なファイル名

実行コンテキストでは以下が参照可能:

  • @s = オブジェクトエンティティ
  • storage asset:context this = Field の中身
  • storage asset:context id = このオブジェクトの ID
  • storage asset:context originID = 召喚時の元 ID (継承呼び出し中も最初の ID を保持)
  • tag @s this = 自分自身であることを示すタグ

4.2. summon (召喚時)

新規エンティティを実際に生成する処理。 TSB が常駐させているマーカーエンティティ (UUID 0-0-0-0-0、別名 commonMarker) をテンプレートに使うと、座標・向きの引き継ぎが楽。

注意: 0-0-0-0-0 は overworld の 0 0 0 に常駐する前提のマーカーだよ。 tp する時は 必ず in minecraft:overworld を挟んで overworld 内で動かすこと。 overworld 以外で素朴に tp 0-0-0-0-0 ~ ~ ~ してしまうと、 0-0-0-0-0 自身が実行 dimension 側に飛ばされて、以降のシステム参照 (core:tick 内の存在チェック等) が壊れる。後述のコード例の in minecraft:overworld はこのためのもの。

例: 矢の召喚 (1009.arrow)

#> asset:object/1009.arrow/summon/

# 元となるEntityを召喚する (0-0-0-0-0をベースに座標 / 向きを揃える)
# in minecraft:overworld で dimension を overworld に固定してから tp する (鉄則)
    execute as 0-0-0-0-0 in minecraft:overworld positioned as @s run tp @s ~ ~ ~ ~ ~

# 召喚に必要なFieldを取り出す
    data modify storage asset:temp Args.Color set from storage asset:context this.Color
    data modify storage asset:temp Args.Rotation set from entity 0-0-0-0-0 Rotation

# マクロでitem_displayを召喚
    function asset:object/1009.arrow/summon/m with storage asset:temp Args
    data remove storage asset:temp Args

summon/m.mcfunction (マクロ部) :

#> asset:object/1009.arrow/summon/m
#
# @input args
#   Rotation: [float] @ 2
#   Color: int

$summon item_display ~ ~ ~ {Rotation:$(Rotation),Tags:["ObjectInit"],item:{id:"minecraft:leather_horse_armor",Count:1b,tag:{CustomModelData:20451,display:{color:$(Color)}}},teleport_duration:1}

ポイント :

  • 召喚するエンティティに必ず Tags:["ObjectInit"] を付与。これで init フェーズが呼ばれる
  • item_displayarea_effect_cloud など、軽量なエンティティを使うのが基本

4.3. init (初期化)

召喚されたエンティティの初期化処理。 ObjectInit タグが付いている間に呼ばれる。 ObjectID スコアの設定や OhMyDat スロットの確保はシステム側で自動でやってくれるので、自分で書くのは個別の初期化だけで OK 。

#> asset:object/<name>/init/

# 個別の初期化処理 (例: 寿命カウンタを設定)
scoreboard players set @s LifeTime 200

# 自身に Asset.Object.<ID> 等のタグを付与 (asset_manager 側で自動付与されるので普通は不要)

4.4. tick (毎 tick)

オブジェクトの本体処理。移動・衝突判定・寿命管理など。 asset:context this にオブジェクト毎のストレージが用意されているので、活用するといい感じの設計ができるよ。

例: 矢の tick (move → 衝突判定 → 寿命チェック)

#> asset:object/<name>/tick/

# 前進 (this.Speed の値だけ進む)
    execute store result score $Move Lib run data get storage asset:context this.Speed 10000
    function lib:score_to_move/

# 命中判定 (Mob にぶつかったら hit_entity を呼ぶ)
    execute if entity @e[type=#lib:living_without_player,tag=Enemy,distance=..1.5] run function asset:object/<name>/hit_entity/

# 寿命カウントダウン
    scoreboard players remove @s LifeTime 1
    execute if score @s LifeTime matches ..0 run function asset:object/<name>/remove/

# tick 終了時、変更した Field を保存
# (システムが自動で this を ObjectField に書き戻すので、ここでは何もしなくてOK)

tick の中で Field を書き換える

asset:context this.<キー>data modify で書き換えると、 tick 終了時に自動で OhMyDat に保存される。だから tick 中は普通の storage 操作として扱える。

# 残り射程を減らす
scoreboard players remove @s LifeTime 1

# Field の値を直接更新したい場合
execute store result storage asset:context this.RemainingRange int 1 run scoreboard players get @s LifeTime

4.5. カスタムメソッド

任意のメソッドを定義して、他のところから呼び出せる。ボス戦の演出オブジェクトに「攻撃メソッド」 「リセットメソッド」 を持たせる、みたいな使い方。

メソッド定義

#> asset:object/<name>/attack/

# 自分の周囲の敵にダメージを与える
    data modify storage api: Argument.Damage set value 5.0f
    data modify storage api: Argument.AttackType set value "Magic"
    execute as @e[type=#lib:living_without_player,tag=Enemy,distance=..3] run function api:damage/
    function api:damage/reset

alias を追加

カスタムメソッドの場合、 alias は自動生成されないので手動で追加する必要がある。

asset/functions/object/alias/<ID>/attack.mcfunction :

#> asset:object/alias/<ID>/attack
function asset:object/<name>/attack/

呼び出し側

オブジェクト自身、または別の場所からメソッドを呼ぶときは asset:object/call.m をマクロ呼び出しする。 as <対象 entity> で対象を指定すれば、そのオブジェクトの ID が自動で取得されて該当の alias 経由でメソッドが実行される。

# 自分自身のメソッドを呼ぶ (オブジェクト内部から)
function asset:object/call.m {method:attack}

# 別のオブジェクトのメソッドを呼ぶ (外部から、例: ボスの本体が分身に attack させる)
execute as @e[tag=Asset.Object.<ID>] at @s run function asset:object/call.m {method:attack}

5. オブジェクトの召喚 (API から呼ぶ側)

詳細は API を参照。基本的な使い方:

# 引数: ID
    data modify storage api: Argument.ID set value 1009

# (オプション) Field の値を上書き
    data modify storage api: Argument.FieldOverride set value {Speed:8,Damage:5.0d,Color:16711680}

# 召喚位置・向きは実行者のものが使われる
    execute at @s anchored eyes positioned ^ ^ ^ rotated ~ ~ run function api:object/summon

Argument.FieldOverride を渡せば、 register で定義したデフォルト値の一部を上書きできる。「弱い矢」「強い矢」「色違いの矢」 みたいなバリエーションを register を増やさず作るのに便利だよ。

6. 継承 (extends) の仕組み

オブジェクトは疑似 OOP で継承が使える。共通処理を親に集約して、個別の挙動だけ子で書く設計ができる。射撃体や弾系の「共通の移動・衝突判定」 を作る時にはほぼ必須。

親オブジェクトの作り方

継承される親は IsAbstract:true (直接召喚させない) と ExtendsSafe:true (継承を許可) を明示する。

#> asset:object/1001.abstract_projectile/register

# 抽象オブジェクトとして
    data modify storage asset:object IsAbstract set value true
    data modify storage asset:object ExtendsSafe set value true
    data modify storage asset:object IsTicking set value true

# ID
    data modify storage asset:object ID set value 1001

# 共通の Field (子で上書き可能)
    data modify storage asset:object Field.Speed set value 1
    data modify storage asset:object Field.Range set value 10
    data modify storage asset:object Field.Damage set value 0

親側の tick は共通処理 (移動とか) を書く:

#> asset:object/1001.abstract_projectile/tick/

# 前進
    execute store result score $Move Lib run data get storage asset:context this.Speed 10000
    function lib:score_to_move/

# 射程切れたら削除
    execute if data storage asset:context this.RemainingRange{..0} run kill @s

子オブジェクトでの継承宣言

子の register で Extends に親 ID を追加して function asset:object/extends を呼ぶ。

#> asset:object/1009.arrow/register

# 継承
    data modify storage asset:object Extends append value 1001    # 1001.abstract_projectile を継承
    function asset:object/extends

# 自分の情報を上書き
    data modify storage asset:object IsAbstract set value false
    data modify storage asset:object ID set value 1009
    data modify storage asset:object Field.Speed set value 4
    data modify storage asset:object Field.Range set value 40
    data modify storage asset:object Field.Damage set value 1

これで Field は親の値で初期化されて、子側で書いた行で上書きされる。 ID と IsAbstract は子の値が優先される。

super.* で親メソッドを呼ぶ

tick 等の実装ファイルで親のメソッドも実行したい時は、 function asset:object/super.<method> を呼ぶ。

#> asset:object/1009.arrow/tick/

# 子独自の処理 (矢特有の演出など)
particle crit ~ ~ ~ 0 0 0 0.05 1

# 親 (abstract_projectile) の tick も実行 (= 共通の移動・寿命チェック)
function asset:object/super.tick

super.tick を呼ぶと、親側の tick/.mcfunctionasset:context id を親 ID に切り替えた状態で実行される。自動で context が戻されるから後片付けは不要。

super.method は任意のメソッド名版で、 asset:context method にメソッド名をセットしてから呼ぶ。

7. オブジェクトの削除

オブジェクトを削除したい時は、 ObjectID スコアをリセットすれば OK 。システムが次 tick で自動的にエンティティを片付ける。

# オブジェクトを削除
scoreboard players reset @s ObjectID

または kill @s で即座に削除してもいい。ただし OhMyDat スロットの解放が遅れるので、通常は ObjectID リセット推奨。

8. ハマりポイント

  • alias/ を作り忘れる → 召喚しても何も起きない。 alias は ID → 実装パスの間接参照で、必ず register / summon / tick / その他カスタムメソッドの分を alias/<ID>/ に置く必要があるよ
  • 召喚時に Tags:["ObjectInit"] を付け忘れる → init/.mcfunction が呼ばれない。さらに後続の自動初期化 (ObjectID 割り当て等) もスキップされる
  • IsAbstract:true を直接召喚しようとする → エラーになる。派生クラス (IsAbstract:false) を作って召喚する
  • IsTicking を false のまま tick を書く → tick 関数があっても呼ばれない。動かしたいなら必ず true にする
  • super.tick の呼び出し位置を間違える → 子の tick の中で呼ぶと「子の処理 → 親の処理」 の順で実行される。親 → 子 にしたいなら子 tick の先頭で super を呼ぶ
  • 重い処理を tick で書く → 同時に数百個のオブジェクトが存在することもあるから、 1 個あたりの tick コストには気を配ること。寿命カウンタで早めに削除するのも大事

Clone this wiki locally