Godotのリストに戻る

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

作成: 2025-06-20更新: 2025-06-20ノード・シーンブログ記事を読む

概要

Godotでは、一つのベースシーンから複数のバリエーションを作成する方法として、Editable ChildrenとScene継承の2つのアプローチがあります。それぞれの特徴を理解して使い分けることが重要です。

最初は「どちらを使えばいいのか」でとても迷いました。似たような機能に見えて、実際は適用場面が全く異なるんです。結果的に「軽い変更は、Editable Children」「機能追加は、Scene継承」というシンプルなルールに落ち着きました。

Editable Childrenの設定方法

2つのアプローチの比較

Editable Children(子ノードを編集可能にする)

  • 用途: 見た目やパラメータだけが異なるインスタンス
  • : 村人A、村人B(セリフが違うだけ)
  • 特徴: その場限りのカスタマイズ

Scene継承(シーンの継承)

  • 用途: 機能的に異なる派生種
  • : 商人NPC(売買機能付き)、クエストNPC(特殊イベント付き)
  • 特徴: 再利用可能な独立したシーン

Editable Childrenの使い方

基本手順

  1. ベースシーンをインスタンス化
  2. インスタンスを右クリック → "Editable Children"
  3. 子ノードが黄色表示になり編集可能に

実装例:モブ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)

メインシーンでの使用:

  1. BaseNPC.tscnをインスタンス化
  2. Editable Childrenを有効化
  3. インスペクターで個別に設定:
    • 村人A: dialog_text = "今日はいい天気ですね"
    • 村人B: dialog_text = "市場は向こうですよ"

Scene継承の使い方

基本手順

  1. ベースシーン作成(BaseNPC.tscn)
  2. 新規シーン作成時に「継承」を選択
  3. 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の設計思想の素晴らしさを実感しています。