【Godot】Editable ChildrenとScene継承によるNPCの量産

作成: 2025-06-20最終更新: 2026-07-09

Godotで敵やNPCのバリエーションを効率よく量産する方法を解説。シーン継承で差分だけ管理し親の変更を全体に伝播させるやり方、Editable Childrenの一点調整、Resourceによるデータ駆動との使い分けまで図解します。

RPGやアクションを作っていると、必ずぶつかるのが キャラクターの量産 です。「スライム」の基本形はできた。でもレベルを作り込むうちに、「HPが多いスライム」「攻撃力2倍のレッドスライム」「レアドロップのメタルスライム」……と、無数のバリエーションが欲しくなります。

最初はつい Slime.tscn をコピペして1体ずつ数値をいじりがちですが、これはすぐ破綻します。あとで「全スライムの移動速度を上げたい」と思ったら、コピーした全シーンを開いて直す羽目になるからです。この記事では、これをエレガントに解決する シーン継承Editable Children 、そして大規模化に効く Resourceによるデータ駆動 を、使い分けまで含めて解説します。

キャラクター量産のイメージ。1つのベーステンプレートから、色や大きさの違う複数の派生キャラクターが生み出される様子

この記事でわかること

  • シーン継承 ——テンプレートから差分だけ変えて派生させる王道
  • 親の変更が 全ての子に自動で伝播 する仕組みと、super での拡張
  • Editable Children ——「この一体だけ」を即席で変える例外処理
  • Resource によるデータ駆動との使い分け

Sponsored

シーン継承:テンプレートから派生させる

シーン継承は、オブジェクト指向の「クラス継承」の考え方を、Godotのシーンに持ち込んだものです。既存のシーンを 「親」 とし、その構造と機能をすべて受け継いだ 「子」 シーンを作れます。再利用性と保守性を重視するなら、これが第一候補です。

シーン継承の伝播の図。親のBaseEnemyから、StrongEnemy・RedSlime・MetalSlimeの3つの子シーンが派生し、それぞれ差分(HPや攻撃力の上書き)を持つ。親のBaseEnemyを修正すると、その変更が3つの子すべてに自動で伝わる

継承の強みは2つです。

  • 差分だけ管理する :子シーンでは、親から受け継いだプロパティ(位置や @export 変数)を自由に上書きできます。変えた項目はインスペクタに「元に戻す」アイコンが付き、 親との差分がひと目で分かります
  • 親の変更が子に自動で伝わる :これが最大の利点です。親シーンにバグ修正や新機能を加えると、その変更は すべての子シーンへ自動で伝播 します。「全キャラ共通の修正」と「特定キャラの個別調整」が同時に成り立ちます。

これは、コピペとは決定的に違います。コピペした複製は親との縁が切れているので、あとから共通の修正をしたくても全部を手直しするしかありません。

継承とコピペの違いの図。左のコピペは独立した複製で、元を直しても複製には反映されない(バラバラ)。右のシーン継承は親とつながっており、親の変更が全ての子に反映される

実践:BaseEnemyから敵バリエーションを量産する

RPGのスライム色違い、アクションの強化版ザコ、シューティングの弾種違いの敵——「共通の土台+種類ごとの違い」は、シーン継承の得意分野そのものです。実際に組んでみましょう。

まず、すべての敵の土台になる BaseEnemy.tscn を作り、共通のスクリプトをアタッチします。数値は @export にして、 子やインスペクタから調整できる ようにするのがコツです。

# base_enemy.gd
extends CharacterBody2D

@export var health: int = 100     # @exportにすると継承先で個別に上書きできる
@export var attack_power: int = 10
@export var speed: float = 50.0

func take_damage(amount: int) -> void:
    health -= amount
    if health <= 0:
        die()

func die() -> void:
    queue_free()                  # 共通の死亡処理(全敵で使い回す)

次に、FileSystemドックで BaseEnemy.tscn を右クリック →「新しい継承シーン」で StrongEnemy.tscn を作ります。この時点では見た目も機能も親と同じ。あとはインスペクタで health を250、attack_power を25に 上書きするだけ で、強化版が完成します。コードは1行も書いていません。

さらに、独自のスクリプトで 親の機能を拡張 することもできます。親のメソッドを上書き(オーバーライド)しつつ、super で親の処理も呼べます。

# strong_enemy.gd
extends "res://base_enemy.gd"

func die() -> void:
    print("強敵が断末魔の咆哮をあげた!")   # この敵だけの追加演出
    super.die()                            # 親のdie()(queue_free等)も実行する

ポイントは2つです。

  • 共通はBaseEnemy、違いだけ子で上書き :移動や被ダメージの共通ロジックは BaseEnemy に一本化。子は「どこが違うか」だけを持ちます。だから後日「全敵の移動を直す」ときも、BaseEnemy を1回直せば全バリエーションに伝わります。
  • super で親を活かすdie() を丸ごと書き直すのではなく、追加演出だけ足して super.die() で親の後始末を再利用します。親の処理を壊さずに拡張できます。

注意: queue_free() はノードを 次のフレームで 削除します。削除後のノードを参照し続けると null参照エラー の原因になります。他ノードから参照される場合は、is_instance_valid() で有効性を確認するか、NOTIFICATION_PREDELETE で後始末する習慣をつけましょう。

継承の考え方そのものは GDScriptで使うOOPデザインパターン の記事も参考になります。

Sponsored

Editable Children:この一体だけ即席で変える

シーン継承が「再利用するテンプレートを作る」機能なら、 Editable Children は「配置した特定の1体だけを、その場でいじる」機能です。新しいシーンファイルを作らずに、インスタンス化した子シーンの 内部ノードを直接編集 できます。

こんな「一度きり」の調整で輝きます。

  • ボス部屋のゴーレム1体だけ、腕の CollisionShape2D を大きくして攻撃範囲を広げる
  • チュートリアル最初の敵1体だけ、speed を0にして動かなくする

やり方は簡単です。メインシーンに配置したインスタンスを右クリックし、「編集可能な子(Editable Children)」にチェックを入れると、内部のノードがツリーに展開され、直接選択・編集できるようになります。

Editable Childrenを有効にしたシーンツリーのスクリーンショット。NPCは折りたたまれた通常のインスタンスだが、NPC2はEditable Childrenが有効で、内部のSprite2D・CollisionShape2D・CanvasLayerなどのノードが展開されて直接編集できる状態になっている

上の画像では、NPC は折りたたまれた普通のインスタンスですが、NPC2 は Editable Children が有効になっていて、内部の Sprite2DCollisionShape2D まで展開・編集できる状態です。

ただし、この変更は そのインスタンス限り で、再利用はできません。「後でも使いそう」と思ったら、右クリック →「ブランチをシーンとして保存」で継承シーンに昇格させるのが定石です。

使い分けと、Resourceによるデータ駆動

3つのアプローチは、目的で使い分けます。

使い分けガイドの図。シーン継承は種類ごとに構成や見た目が変わる場合、Editable Childrenは配置した1体だけの例外調整、Resourceデータ駆動は構成は同じで数値だけ変わる大量バリエーション、と3つの適用場面を並べる
  • シーン継承 :種類ごとに ノード構成や見た目が変わる バリエーション。基本戦略。
  • Editable Children :配置した 1体だけの例外調整 。使い捨ての微調整。
  • Resourceデータ駆動 :構成は同じで 数値だけが違う大量のバリエーション

特に、数百種類のモンスターが出るRPGのような規模では、シーン継承だけだとシーンファイルが増えすぎて煩雑になります。そこで、キャラのパラメータを Resource(データ)として分離 する「データ駆動設計」が効きます。

Resourceデータ駆動の図。1つのBaseEnemy.tscnに、slime_data.tres・goblin_data.tres・dragon_data.tresといった複数のデータリソースのいずれかを差し込むと、同じシーンが別々の敵として振る舞う

BaseEnemy.tscn@export var data: CharacterData を1つ持たせ、slime_data.tresdragon_data.tres を差し替えるだけで、 シーンは1つのまま 何百種類もの敵を表現できます。パラメータ調整は .tres ファイル側で完結します。詳しくは カスタムリソースの作成と活用 を参照してください。

「見た目・構成が違う=継承」「数値だけ違う=データ駆動」、そして両者を組み合わせる(継承したシーンにデータリソースを差す)のが、実戦的な落としどころです。

よくある間違いとベストプラクティス

よくある間違いベストプラクティス
何でもEditable Childrenで済ませる再利用の可能性があるなら シーン継承 を選ぶ。「後で使うかも」と思ったら継承シーンにする
継承階層を深くしすぎる継承は 2〜3階層まで を基本に。それ以上は継承よりコンポジションやデータ駆動を検討する
親シーンが子の状態を仮定する親は 自己完結 させ、汎用機能を提供。具体的な振る舞いは子が決める
数値変更のためにスクリプトを増やすHP・攻撃力・速度は @export にして、デザイナーがインスペクタで安全に調整できるようにする
Sponsored

おまけ:先に知っておくと良いこと

  • 継承よりコンポジション :オブジェクト指向の定石です。深い継承より、機能を子ノードとして足していく「合成」の方が、Godotでは柔軟に働く場面が多いです。「攻撃コンポーネント」「HPコンポーネント」を組み合わせる発想は、継承の限界を感じたときの次の一手になります。
  • 実行時のパフォーマンスは気にしなくてよい :シーン継承もEditable Childrenも、最終的には1つのシーンツリーとして解釈されるため、実行時の負荷に大きな差はありません。 選ぶ基準は「保守性」 です。
  • 継承シーンでノードは消せない :親由来のノードは子から削除できません。不要なら可視化オフや queue_free() で対応します。

まとめ

  • シーン継承 は、テンプレートから 差分だけ変えて派生 させる王道。親の変更が全ての子に自動伝播する
  • 子スクリプトで super を使えば、 親の処理を活かしつつ拡張 できる
  • Editable Children は、配置した 1体だけを即席で調整 する例外処理。再利用はできない
  • 大量バリエーションは Resourceによるデータ駆動 (1シーン+種類ぶんの .tres)が管理しやすい
  • 「構成が違う=継承」「数値だけ違う=データ駆動」「1体だけ=Editable Children」で使い分ける

まずは BaseEnemy を1つ作り、継承シーンで health を書き換えるところから試してみてください。「親を直すと全部に効く」感覚が掴めれば、量産の設計はぐっと楽になります。

さらに学ぶために