【Godot】これからGodotを学ぶUnity開発者のための対応表とオススメ教材

2025/06/132026/03/28 更新📖 約17分 | 9,618文字ゲーム開発Godot学習記録

※Godot公式が配布しているデモプロジェクト (最初の2Dゲーム)

Godot Engineは、2014年にオープンソース化されたMITライセンスのゲーム開発エンジンです。2023年のUnity Runtime Fee騒動をきっかけに移行先として注目が集まり、知名度が一気に上がりました。

※学習中のUdemyコース「Godot4: Build a 2D Action-Adventure Game

この記事では、Unity開発者がGodotを学ぶ際に役立つ情報をまとめています。Udemyコースの受講感想、Godotに触れて感じたこと、UnityとGodotの概念対応表、コードの書き方の違いなどを紹介します。

Godot Engine 公式サイト

Godot Engineに対するQ&A

Godotを学び始める前、私にはいくつもの疑問がありました。「そもそもGodotって何がすごいの?」「ノードベースって難しくない?」「GDScriptって覚える価値あるの?」――同じ疑問を持つ方も多いはず。ここでは、学習前の疑問に対して実際に触れた今の自分が答えます。

Q. Godot Engineって? 2014年にオープンソース化されたゲーム開発エンジン。MITライセンスで完全無料、ロイヤリティもなし。エンジン本体はC++製。

Q. UnityやUnreal Engineと比べた第一印象は? とにかく軽い。v4.4.1時点でエンジン全体が約149MB。Unityのインストーラーを起動する間にGodotは開発を始められる。ただし日本語情報の少なさは覚悟が必要。

Q. Godotで作られた有名ゲームって? 「Backpack Battles」「Backshot Roulette」「Unrailed 2: Back on Track」など。意外と知られたタイトルが並んでいる。公式サイトのShowcaseで一覧を確認でき、各年度のまとめ動画もおすすめ。

Q. ノードベースってなに? 機能をノードの階層構造で構築する仕組み。たとえば物理判定のあるキャラクターなら、CharacterBody2Dノードの下にAnimatedSprite2D(アニメーション)とCollisionShape2D(衝突判定)を配置する。Unityでいうコンポーネントのアタッチに近い感覚なので、Unity経験者なら難しくない。

Q. ノードベースって自由度低くない? ノードを継承して独自クラスを作れるので、コーディングの自由度はUnityやUnreal Engineと変わらない。

Q. GDScriptって何? PythonベースのGodot独自言語。C#もサポートされているが、基礎学習ではGDScriptから始めるのが圧倒的に効率がいい。構文がシンプルで、エンジンとの統合も深い。

Udemy講座を受講した感想

新しいエンジンを学ぶとき、私は公式ドキュメントに加えて動画チュートリアルを複数こなすようにしています。今回はUdemyの「Godot Engineで気軽に2Dゲームを作ろう」を受講し、6.5時間ほどで修了しました。

コースは基礎(プロジェクト設定、ノード・シーン理解、Windows/Web向けビルド)から始まり、後半ではオリジナル2Dゲームの開発に入ります。1動画1〜5分で要点を押さえてくれるため、テンポよく進められました。

※コースの手順で作成できるゲームの完成形

特に面白かったのは、穴掘り法アルゴリズムによる迷路のプロシージャル生成です。UI作成、データ保存、射撃システム、敵AIまで一通り実装し、タイトル→エリア選択→迷路→タイトルというゲームサイクルを完成させます。

※穴掘り法アルゴリズムの実行ログ

Godotの日本語コースはまだ少なく、ここまで整備されたカリキュラムは貴重です。まずこのコースで全体像をつかんでから、英語圏のより高度なコースに進むのがおすすめです。Udemyは頻繁にセールがあるので、お気に入りに登録しておくとよいでしょう。

学習中のTipsとして、Godotの独自仕様はChatGPTやClaudeに「Unity/Unreal Engineで例えると何に相当するか?」と聞きながら進めると理解が格段に早くなります。@exportSerializeFieldget_tree().change_scene_to_file()SceneManager.LoadScene のように既存の知識と紐づけるだけで、学習効率がまるで変わります。

Godot Engineで気軽に2Dゲームを作ろう (Udemy)

Godotに触れて感動したこと

コースを通じてGodotの設計思想に触れ、率直に感動しました。Unity/Unreal Engineとは明確に異なるアプローチで、特に2D開発では「こういうのが欲しかった」と思う場面が何度もありました。

  • ノードとシグナルの直感性: Godotの核となる2つの概念。ノードで構造を作り、シグナルで通信する。この組み合わせに慣れると、UnityのGetComponent + UnityEventよりも流れるように実装できる感覚がある。
  • 軽量さが生む快適さ: Unityはプロジェクトを開くだけで数十秒〜数分かかることがあるが、Godotは.exeをクリックして数秒で開発再開。コンパイルもほぼ一瞬なので、「ちょっと試す」のハードルが劇的に低い。
  • シーンの再利用性: 最初は「シーン = Prefab + Scene」という概念に戸惑ったが、慣れるとUnityと同じ感覚で使える。GameManager的なものはMarker2Dにスクリプトをアタッチしてシーン化し、AutoLoadでシングルトン化すればOK。
  • 2D専用機能の充実: TileMapやAnimatedSprite2Dなど、2D開発に特化したノードが最初から揃っている。Unityの2Dが「3Dエンジンの上に載せた2D」なのに対し、Godotの2Dはネイティブ。
  • スプライトシート制作: Unityではスプライトのスライス→個別設定が必要だったが、Godotはグリッドアイコンから画像を選ぶだけでタイムラインに並ぶ。この手軽さは2Dゲーム開発者にとって大きい。
  • タイルセット管理: 衝突判定を視覚的に設定でき、Physics Layerでタイルごとの当たり判定を効率的に管理できる。Unityのタイルマップ設定と比べて手順が少ない。

Unity開発者向け: Godotとの対応表

Unity開発者がGodotを学ぶとき、まず知りたいのは「Unityのあれは、Godotでは何にあたるのか?」でしょう。以下の対応表をざっと眺めてから学習を始めると、理解がスムーズになります。

GodotUnity(近い概念)
シーン (.tscn)Prefab + Scene
get_tree().change_scene_to_file()SceneManager.LoadScene()
$記法 / get_node()GameObject.Find() / FindObjectOfType()
get_parent()transform.parent
_ready()Start()
_process(delta)Update()
_physics_process(delta)FixedUpdate()
CanvasLayerCanvas (Sorting Order)
ControlUI GameObject
LabelText / TextMeshPro
シグナルUnityEvent / C# Event
@export[SerializeField]
@onreadyAwake()での初期化
AutoLoadDontDestroyOnLoad
load() / preload()Resources.Load()

あくまで「おおよその対応」です。細かい挙動は異なるので、実際に手を動かしながら違いを体感してみてください。

Unity開発者向け: コードで見る違い

対応表で概念を押さえたら、次はコードの書き方を見比べてみましょう。GDScriptはPythonに似たインデントベースの構文で、C#と比べてコード量が少ないのが特徴です。Unity開発者が最初に戸惑いやすいのは、型宣言のスタイル、$記法によるノードアクセス、そしてシグナルの仕組みあたりでしょう。

例1:変数の公開と初期化 (@export vs [SerializeField])

ゲーム開発では「インスペクターで値を調整したい」場面が頻繁にあります。移動速度やジャンプ力をコード内にハードコーディングするのではなく、エディタ上でいつでも変更できるようにしたい――Unityでは[SerializeField]を使いますが、Godotでは@exportアノテーションが同じ役割を果たします。

また、UnityでStart()に書いていた初期化処理は、Godotでは_ready()に記述します。

Godot (GDScript)

# Player.gd
extends Node2D

@export var player_name: String = "Hero"
@export var speed: int = 100

# UnityのStart()に相当
func _ready():
    print("Player Name: ", player_name)
    print("Initial Speed: ", speed)

Unity (C#)

// Player.cs
using UnityEngine;

public class Player : MonoBehaviour
{
    [SerializeField] private string playerName = "Hero";
    [SerializeField] private int speed = 100;

    // Godotの_ready()に相当
    void Start()
    {
        Debug.Log("Player Name: " + playerName);
        Debug.Log("Initial Speed: " + speed);
    }
}

なお、毎フレーム処理は_process(delta)(UnityのUpdate()に相当)で記述します。引数のdeltaはUnityのTime.deltaTimeと同じくフレーム間の経過秒数で、フレームレートに依存しない動作を実現するために使います。

例2:物理演算の処理 (_physics_process vs FixedUpdate)

キャラクターを左右キーで移動させる、ゲーム開発の基本中の基本です。UnityではRigidbody2Dをアタッチし、Start()GetComponentして変数に保持し、FixedUpdate()velocityを設定する――という3ステップが必要でした。

GodotのCharacterBody2Dvelocityプロパティとmove_and_slide()を内蔵しているため、コンポーネント取得のボイラープレートが不要です。コードを見比べると、Godot側のシンプルさが際立ちます。

Godot (GDScript)

# Character.gd
extends CharacterBody2D

const SPEED = 300.0

# UnityのFixedUpdate()に相当
func _physics_process(delta):
    var direction = Input.get_axis("ui_left", "ui_right")
    velocity.x = direction * SPEED
    move_and_slide()  # Godotの便利な組み込み関数

Unity (C#)

// Character.cs
using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]
public class Character : MonoBehaviour
{
    [SerializeField] private float speed = 300.0f;
    private Rigidbody2D rb;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    // Godotの_physics_process()に相当
    void FixedUpdate()
    {
        float moveInput = Input.GetAxis("Horizontal");
        rb.velocity = new Vector2(moveInput * speed, rb.velocity.y);
    }
}

例3:ノードの取得 ($ vs GetComponent)

「子オブジェクトのアニメーションを再生したい」「コリジョンを無効化したい」――こうした操作はゲーム開発で頻出します。UnityではGetComponentInChildren<T>()transform.Find()で参照を取得し、nullチェックを挟んでからアクセスするのが定番パターンです。

Godotの$記法(get_node()のシンタックスシュガー)はノードパスを直接書けるため、驚くほど簡潔です。ツリー構造が見えているぶん、どのノードにアクセスしているかも一目瞭然です。

Godot (GDScript)

# Player.gd
extends Node2D

func _ready():
    # $記法で子ノードに直接アクセス
    $AnimatedSprite2D.play("run")

    # get_node() を使う方法もある
    var collision_shape = get_node("CollisionShape2D")
    collision_shape.disabled = true

Unity (C#)

// Player.cs
using UnityEngine;

public class Player : MonoBehaviour
{
    void Start()
    {
        // 子オブジェクトからコンポーネントを取得
        Animator animator = GetComponentInChildren<Animator>();
        if (animator != null)
        {
            animator.Play("run");
        }

        // 名前で子オブジェクトを探す場合
        Transform collisionShape = transform.Find("CollisionShape");
        if (collisionShape != null)
        {
            collisionShape.gameObject.SetActive(false);
        }
    }
}

例4:シグナル (signal vs UnityEvent)

「プレイヤーがダメージを受けたらUIのHP表示を更新したい」――オブジェクト間の通知はゲームのあらゆる場面で必要になります。UnityではUnityEventやC#のeventで実装しますが、発信側と受信側の参照管理がやや煩雑になりがちです。

Godotのシグナルはこの問題をエレガントに解決しています。大きな特徴は2つ。エディタ上でノード同士の接続をGUIで設定できることと、発信側が受信側の存在を一切知らなくてよい疎結合な設計です。コードで接続する場合も.connect()一行で済みます。

Godot (GDScript)

# Player.gd
extends Node2D

signal health_changed(new_health)

var health: int = 100

func take_damage(damage: int):
    health -= damage
    health_changed.emit(health)  # シグナル発信
# UI.gd
extends Control

func _ready():
    var player = get_node("../Player")
    player.health_changed.connect(_on_health_changed)

func _on_health_changed(new_health: int):
    print("体力が ", new_health, " になりました")

Unity (C#)

// Player.cs
using UnityEngine;
using UnityEngine.Events;

public class Player : MonoBehaviour
{
    [SerializeField] private UnityEvent<int> onHealthChanged;

    private int health = 100;

    public void TakeDamage(int damage)
    {
        health -= damage;
        onHealthChanged?.Invoke(health);  // イベント発信
    }
}
// UI.cs
using UnityEngine;

public class UI : MonoBehaviour
{
    [SerializeField] private Player player;

    void Start()
    {
        player.onHealthChanged.AddListener(OnHealthChanged);
    }

    private void OnHealthChanged(int newHealth)
    {
        Debug.Log("体力が " + newHealth + " になりました");
    }
}

例5:シーン切り替え (change_scene_to_file vs SceneManager.LoadScene)

レベルクリア時に次のステージへ遷移する処理です。UnityではSceneManager.LoadScene()にシーン名を渡しますが、Build Settingsへのシーン登録が事前に必要でした。

Godotでは.tscnファイルへのパスを直接指定するだけでシーンを切り替えられます。Build Settingsのような登録ステップがないぶん、プロトタイピング時の取り回しが軽快です。

Godot (GDScript)

# GameManager.gd
extends Node

func level_complete():
    print("レベルクリア!")
    get_tree().change_scene_to_file("res://scenes/Level2.tscn")

Unity (C#)

// GameManager.cs
using UnityEngine;
using UnityEngine.SceneManagement;

public class GameManager : MonoBehaviour
{
    public void LevelComplete()
    {
        Debug.Log("レベルクリア!");
        SceneManager.LoadScene("Level2");
    }
}

まとめ

Godotは、特に2D開発者におすすめできるゲームエンジンです。スプライトやタイルセット管理ではUnity/Unreal Engineに対して明確な優位性があり、純粋な2DゲームはGodot、ライティング演出にこだわるならUnityという使い分けが良いと感じました。

エンジンとしての成熟度では、情報量・ストア環境・商業実績いずれもUnityやUnreal Engineが圧倒的です。しかし「Backpack Battles」や「Backshot Roulette」などGodot製タイトルは着実に増えており、Runtime Fee騒動で移行した開発者の作品が出揃えばシェアは伸びるでしょう。

オープンソースという点もユニークです。MayaとBlenderの関係を見ると、Godotにも化ける可能性はあります。UnityやUnreal Engineが無料で使える以上、Blenderほどの急速な浸透は難しいかもしれませんが、業界の受け皿として成長する余地は十分です。

私自身はUnityやUnreal Engineにも引き続き触れますが、Godotが第三の選択肢になり得ることを確認できたのは収穫でした。興味がある方はぜひ触れてみてください。

この記事をシェアする