概要
Godotでは、一つのベースシーンから複数のバリエーションを作成する方法として、Editable ChildrenとScene継承の2つのアプロー チがあります。それぞれの特徴を理解して使い分けることが重要です。
最初は「どちらを使えばいいのか」でとても迷いました。似たような機能に見えて、実際は適用場面が全く異なるんです。結果的に「軽い変更は、Editable Children」「機能追加は、Scene継承」というシンプルなルールに落ち着きました。

2つのアプローチの比較
Editable Children(子ノードを編集可能にする)
- 用途: 見た目やパラメータだけが異なるインスタンス
- 例: 村人A、村人B(セリフが違うだけ)
- 特徴: その場限りのカスタマイズ
Scene継承(シーンの継承)
- 用途: 機能的に異なる派生種
- 例: 商人NPC(売買機能付き)、クエストNPC(特殊イベント付き)
- 特徴: 再利用可能な独立したシーン
Editable Childrenの使い方
基本手順
- ベースシーンをインスタンス化
- インスタンスを右クリック → "Editable Children"
- 子ノードが黄色表示になり編集可能に
実装例:モブNPCの配置
# BaseNPC.gd (ベースシーン)
extends CharacterBody2D
@export var npc_name: String = "村人"
@export var dialog_text: String = "こんにちは!"
@export var sprite_texture: Texture2D
func _ready():
$Sprite2D.texture = sprite_texture
$NameLabel.text = npc_name
func interact():
show_dialog(dialog_text)
メインシーンでの使用:
- BaseNPC.tscnをインスタンス化
- Editable Childrenを有効化
- インスペクターで個別に設定:
- 村人A: dialog_text = "今日はいい天気ですね"
- 村人B: dialog_text = "市場は向こうですよ"
Scene継承の使い方
基本手順
- ベースシーン作成(BaseNPC.tscn)
- 新規シーン作成時に「継承」を選択
- BaseNPC.tscnを選んで継承シーンを作成
実装例:商人NPCの作成
ベースクラス:
# BaseNPC.gd
extends CharacterBody2D
class_name BaseNPC
@export var npc_name: String = "NPC"
signal interaction_finished
func interact():
# 継承先でオーバーライド
pass
func show_dialog(text: String):
# ダイアログ表示処理
$DialogBox.show_text(text)
継承シーン:
# MerchantNPC.gd (Inherits: BaseNPC.tscn)
extends BaseNPC
@export var shop_items: Array[Resource] = []
@export var greeting_text: String = "いらっしゃい!何か買っていくかい?"
func interact():
show_dialog(greeting_text)
await $DialogBox.dialog_finished
open_shop()
func open_shop():
var shop_ui = preload("res://UI/ShopUI.tscn").instantiate()
shop_ui.set_items(shop_items)
get_tree().root.add_child(shop_ui)
使い分けの指針
Editable Childrenが適している場合
# 同じ機能、違うパラメータ
# 例:宝箱(中身が違うだけ)
ChestA: item = "ポーション"
ChestB: item = "100ゴールド"
ChestC: item = "鉄の剣"
Scene継承が適している場合
# 基本 機能を拡張
BaseEnemy → SlimeEnemy(分裂機能追加)
→ GoblinEnemy(武器使用追加)
→ BossEnemy(特殊攻撃パターン追加)
実践的な組み合わせ例
町のNPC配置
町のシーン
├── 一般村人 (Editable Children)
│ ├── 村人A(男性スプライト、セリフ1)
│ ├── 村人B(女性スプライト、セリフ2)
│ └── 村人C(子供スプライト、セリフ3)
├── 機能NPC (Scene継承)
│ ├── 商人(ShopNPC.tscn)
│ ├── 宿屋主人(InnkeeperNPC.tscn)
│ └── クエスト発行者(QuestGiverNPC.tscn)
メリット・デメリット
Editable Children
メリット:
- 素早く個別調整可能
- ベースシーンの更新が即座に反映
- シンプルな変更に最適
デメリット:
- 変更がそのシーンに限定
- 大規模な機能追加は困難
- バージョン管理で差分が見づらい
Scene継承
メリット:
- 独自の機能を追加可能
- 再利用性が高い
- 体系的な管理が可能
デメリット:
- ファイル数が増える
- 継承関係の管理が必要
- 小さな変更には過剰
ベストプラクティス
命名規則
BaseNPC.tscn # ベースシーン
├── MerchantNPC.tscn # 継承:商人
├── GuardNPC.tscn # 継承:衛兵
└── QuestNPC.tscn # 継承:クエスト
プロパティの設計
# ベースクラスで共通プロパティを定義
extends CharacterBody2D
# 全NPCで使用
@export_group("基本設定")
@export var npc_name: String
@export var health: int = 100
# 継承先でカスタマイズを想定
@export_group("カスタマイズ")
@export var custom_behavior: bool = false
トラブルシューティング
継承シーンの変更が反映されない
- ベースシーンを保存し忘れていないか確認
- 継承シーンで明示的にオーバーライドしていないか確認
Editable Childrenが黄色くならない
- 既に編集可能になっている可能性
- インスタンスが正しく作成されているか確認
実装して学んだこと
この2つの手法を使い分けられるようになってから、ゲームの作業効率が大幅に向上しました。特にRPGでは、「同じようなNPCだけど、セリフだけ違う」というケースが非常に多く、Editable Childrenの使用頻度が高いです。
一方で、特殊な機能を持つNPC(商人、クエスト発行者など)はScene継承で作成し、再利用しやすい形にしています。この使い分けを意識することで、プロジェクトの保守性と拡張性が大幅に向上しました。
最初は「なぜ2つも方法があるのか?」と思いましたが、実際に使ってみると、それぞれに明確な適用場面があることが理解できました。Godotの設計思想の素晴らしさを実感しています。