【Godot】Godot Engine の Tips (逆引き)

Godot Engine Advent Celendar 2022 2日目

この記事はGodot Engine Advent Celendar 2022 2日目の記事となります。

目次

グラフィックス

矩形 (四角形) を描画したい

画像リソースを用意せずに、ひとまず四角形を表示したい場合、ColorRect ノードを追加すると四角形を表示できます。

ColorRect ノードを作成します。

白い四角が表示されます。

インスペクタの ColorRect > Color から色を変更できます。

GDScriptから color プロパティを設定すると色が変えられます。

# 緑色に変更する
$ColorRect.color = Color.green

Sprite関連

Spriteの色を変更したい

Spriteノードの色は modulate となります

## スプライトの頂点カラーを緑色にする
$Sprite.modulate = Color.green

Spriteでパターンアニメーションしたい

Spriteの Animation > Vframes とAnimation > Hframes を設定すると Sprite.frame の値を書き換えることでアニメーションを実装できます。または AnimatedSprite ノードを使用します。詳細は以下のページに書きました。

【Godot】2Dスプライトアニメーションの基本的な使い方

アニメーションそのものを制御する場合、 AnimationPlayerノードを使うこともできます。これについては以下の記事に書いています。

【Godot】AnimationPlayerでのアニメーションを実装する基本

加算ブレンドモードでSpriteを描画したい

CanvasItem > Material > 新規CanvasItemMaterial でMaterialを作成し、Blend Mode に Add を指定すると加算ブレンドモードで Sprite を描画できるようになります。

Tween関連 (緩急のある動きを作りたい)

Tweenの使い方を知りたい

Tweenノード を使うと緩急のある (イージング) アニメーションを作れます。詳細は以下のページに書きました。

【Godot】Tweenの使い方

ただ 3.5 以降はもう少し便利な書き方ができたり、4.x以降になると lambda式が使えるので簡潔にコードを書けるようです。以下は 3.5 と 4.0 での Tween を解説されている方の記事となります。

イージング関数 ease() の使い方

ease() という関数が用意されていて単純な曲線であればこれで実装できます。
ただ、パラメータの指定が独特なのでこのグラフを見てどの値を指定するのかを検討する必要があります。

# cube in
var d = ease(t, 0.4)
# cube out
var d = ease(t, 4.6)
# expo in
var d = ease(t, 0.2)
# expo out
var d = ease(t, 4.8)

Tweenノードを使わずにイージングのアニメーションを作りたい

個人的に Tweenノード を使うよりもスクリプトで書いた方がお手軽に使える気がしたので、イージングアニメーションを自作するサンプルコードを以下の記事に書きました。

【Godot】イージング関数のサンプルコード

描画順の制御をしたい

z_indexを使った描画順の制御

z_index の値で描画順を制御できます。この値を大きくするほど手前に描画されます。

    # ピラミッドに追加
    for i in range(6):
        var card = deck.pop_back()
        card.set_next_position(get_pyramid_position(i))
        card.z_index = i # 下にあるカードが手前に描画する
        card.place = Card.ePlace.Pyramid
        card.pos_index = i

CanvasLayerを使った描画順の制御

CanvasLayerノード を使うことで描画順を階層化して制御ができます。詳細は以下の記事に書いています。

【Godot】2Dゲームの描画順の制御方法

Y座標を基準に描画ソートしたい

YSortノードを使うと、簡単に描画順を制御できます。詳細は以下の記事に書いています。

【Godot】YSortを使った描画順の制御
YSortノードはGodot4.xでは削除されました

Godot4.xで YSort を行いたい場合、CanvasItem にある “y_sort_enabled” を true にすることでYSortが有効となります。

bool y_sort_enabled =false

trueの場合、最も低いY位置を持つ子ノードは、より高いY位置を持つ子ノードの前に描画されます。falseの場合、Yソートは無効になります。Yソートは、CanvasItemを継承する子にのみ影響します。

Yソートでノードをネストできます。子Yソートノードは、親Yソートと同じスペースでソートされます。この機能を使用すると、シーンツリーを変更することなく、シーンをより適切に整理したり、複数のシーンに分割したりできます。

GODOT DOCS > CanvasItem

クォータービューのゲームを作りたい

Godot Engineでは、クォータービューの仕組みがすでに用意されているので、これを使うことで簡単に実現できます。実装方法は以下の記事に書きました。

【Godot】クォータービューの基本的な作り方

スクロール

スクロールしたい

スクロールしたい場合は Camera2D ノードをシーンに配置して、Current を オンにして、position の値を動かすとスクロールできます。

カメラのスクロールに追従するオブジェクトにしたい

カメラを有効にしてスクロールをすると基本的にすべてのオブジェクトがスクロール対象となります。ですが、例えばスコア表示などのUIは、通常であれば位置を固定化したいです。

そういった場合に描画位置をスクリーン座標で固定するには CanvasLayer ノードの下に配置します。

CanvasLayerに登録したオブジェクトをスクロールに追従しないようにする方法

CanvasLayerはデフォルトでカメラに追従する(正確には Viewport に追従しない) 設定となっています。これを無効にする (Viewport に追従する) には Follow Viewport” を Enable にします。

背景を多重スクロールしたい

ParallaxBackground / ParallaxLayer ノードを使用することで多重スクロールが実現できます。

【Godot】多重スクロールの実装方法

ポストエフェクト

CanvasLayer単位でポストエフェクトを行いたい

ViewportContainer / Viewport ノードを使用すると CanvasLayer単位でポストエフェクトを適用することができます。

ポストエフェクトを行いたい CanvasLayer ノードの下に、「ViewportContainer」「Viewport」をぶら下げます。

そして ViewportContainerのインスペクタから Stretchにチェックを入れます。

Viewport のインスペクタから Size をスクリーン(ウィンドウ)のサイズに合わせます(以下は 1024×720)。

この設定をすることで、あとは WorldEnvironmentノードなどでポストエフェクトがかけ放題となります。

WorldEnvironmentノードの簡単な使い方については以下の記事に書きました。

【Godot】ブルームを適用する方法

CanvasLayerにWorldEnvironmentの効果が適用されない

WorldEnvironmentの Background の Mode を Canvas とする場合、”Canvas Max Layer” というパラメータがあります。

これはどの CanvasLayer までポストエフェクトを適用するかという値で、これを適用したいレイヤーの描画順の最大値に設定する必要があります。

なお、CanvasLayer のインスペクタには Layer という値があり、これが描画順となります。

画像リソースの動的読み込み

load() で画像リソースのパスを指定することで、画像を動的に読み込むことができます(※ただし同期ロードです)。

var id = 12

# 画像リソースへのパス "res://assets/cards/012.png" を作成する
var path = "res://assets/cards/c%03d.png"%id

# 子ノードに "Sprite" が存在する前提
$Sprite.texture = load(path)    

画像を拡大するとぼやけてしまう

Godot Engine はデフォルトでBilinear補間の描画が有効になっています。なので、これを無効にすると拡大してもピクセル比が固定(ドットバイドット、ピクセルパーフェクト)で描画できます。

手順は以下のとおりです。

  1. 対象の画像を選ぶ
  2. インポート」タブを選ぶ
  3. プリセットから「2D Pixel」を選ぶ
  4. 再インポート」をクリックする

Godot 4.x以降の場合

Godot 4.x 以降の場合はプロジェクト設定から変更するのが便利です。

一般 > レンダリング > テクスチャ」から「Canvas Textures > Default Texture Filter」の値を「Nearest」にするとピクセルパーフェクトとなります。

ノードを使わずに直接描画したい

_draw() をオーバーライドすると、draw_*() 系の関数を使って直接描画できます。以下、三角形の描画例です。

func _draw():
    var points = PoolVector2Array()
    var colors = PoolColorArray([Color(0, 1, 0, 0.5)])
    points.push_back(Vector2(50, 0))
    points.push_back(Vector2(0, 200))
    points.push_back(Vector2(200, 200))
    draw_polygon(points, colors)

ただ、この描画コマンドはキャッシュされる(開始時に1度しか呼び出されない)ため、位置やサイズなどを変更したい場合は、描画情報が変更されたタイミングでupdate() (Godot4.xの場合はqueue_redraw()) を呼び出して _draw() を再び呼び出すようにします。

Spineを使いたい

高度な2Dアニメーションを実装する場合、Spineでデータ作成してそれをGodotでインポートします。spine-godotの簡単な使い方については以下の記事にまとめています。

【Godot】spine-godotの使い方メモ

デフォルトのクリアカラー (背景色) を変更したい

Godot はデフォルトのクリアカラーが灰色 (#777777) ですが、「プロジェクト設定 > レンダリング > 環境」の “Default Clear Color” から変更できます。

UI (Controlノード)

ゲージUI

ゲージUIを作りたい

Godot Engine には ProgressBar / TextureProgress ノードという便利な機能が用意されているので、それを使うことで簡単に実装できます。詳細は以下の記事に書きました。

【Godot】ゲージUIの作り方

円状のゲージを作りたい

TextureProgressノードは円状のゲージにすることも可能です。実装方法は以下の記事に書いています。

【Godot】TextureProgressを使用したクールダウンアイコンの実装方法

9Slice(拡大・縮小できるUI)を作りたい

Godotには、NinePatchRectというUIノードがあり、それを使うと9Sliceを実現できます。

【Godot】NinePatchRectでスケーラブルなUIを作る方法

Label ノードを使わずにフォントを描画したい

draw_string() を使用すると動的に文字を描画できます。以下、サンプルとなります。

extends Node2D

var font:BitmapFont

func _ready():
    # デフォルトフォントを取得
    font = Control.new().get_font("font")

func _process(delta):
    # 描画情報に変更がある場合は update() を呼び出して更新する必要がある
    # 更新しない場合は update() の呼び出しは不要
    update()

func _draw():
    # デフォルトフォントを使って文字を描画
    draw_string(font, Vector2(32, 32), "Hello world.")

より詳しくは以下の記事に書いています。

【Godot】スクリプトだけで文字を描画する方法

フォント

日本語を表示したい

日本語フォントを使用するにはテーマファイルの作成が必要となります。詳細は以下の記事に記載しています。

【Godot】日本語フォントの設定方法 (Godot3.4〜3.5)

Godot4.xからはデフォルトフォントで日本語を表示できるようになったので、“Label”ノードを使用することで日本語を表示できます。

フォントを差し替えるには、まずフォントファイル(*.ttfなど)をファイルシステムに追加します。

次に “Label” ノードのインスペクタから Label Settings の <空> のところをクリックします。

<空> をクリックするとポップアップが表示されるので「新規LabelSettings」を選びます。

そして作成された「LabelSettings」をクリックするとフォントの設定項目が表示されます。

次に「Font > Font」の <空> をクリックして クイックロード を選びます。

ダイアログから設定したいフォントを選びます。

あとはフォントサイズやアウトライン(縁取り)などを自由に選びます。

なおこの LabelSettings はリソースとして保存しておくと他の Label でも使いまわすことができます。

ビットマップフォントを使用したい

例えばダメージ数値など、専用の画像で数字を表示したい場合にはビットマップフォントを使う方法があります。詳細は以下の記事に書きました。

ShoeBoxを使用したビットマップフォントの作成方法とGodot Engineでの設定方法

入力制御

入力の定義を追加する

インプットマップを使うことで入力判定を追加できます。

以下、マウスのクリック判定を追加する手順となります。

  1. メニューから プロジェクト > プロジェクト設定 を選ぶ。
  2. インプットマップ タブを選んで、アクションに “ui_click” と入力して、「追加」ボタンをクリック
  3. 追加された “ui_click” の行の右側にある「+」をクリックして マウスボタン を選択
  4. 「左ボタン」を選んで「追加」ボタンをクリック

この設定をすることで、以下のコードでクリック判定ができるようになります。

func _process(delta: float) -> void:
    if Input.is_action_just_pressed("ui_click"):
        print("クリックしました")

マウスカーソルの座標を取得したい

get_viewport() を使用することでマウス座標が取得できます。

# マウスのX座標
var mx = get_viewport().get_mouse_position().x
# マウスのY座標
var my = get_viewport().get_mouse_position().y

Area2Dのマウスクリックイベントがうまく動かない場合

*Rect 系ノード (TextureRect や ColorRect)を使っていると、そちらにマウスイベントを取られてしまうことがあるので、もし *Rect 系ノードを使っている場合は Mouse > Filter を Ignore にします。

物理システム関連

物理システムノードの分類

Godot Engineで使用できる物理システムに関するノードと分類は以下のとおりです。

ノード名概要使用例
Area2D・衝突の「検知」「影響」
・シグナルの衝突検知
・領域内の重力や速度減衰
・衝突検知のみのオブジェクト
 (2Dシューティングなど)
・重力を変化させる装置
StaticBody2D衝突しても動かない
静的オブジェクト
・動かない壁や床
・動かないベルトコンベア
・動かない障害物
RigidBody2D物理エンジンで動く
物理オブジェクト
・投擲オブジェクト
・物理パーティクル
CharacterBody2Dスクリプトで細かく動きを
制御できるRigidBody2D
・プレイヤー
・動く床

ゲームジャンルごとに向いている物理システムノードの分類は以下のとおりです。

(※あくまで向いている、というだけなのでどのように使うのかは自由です)

RigidBody2D関連

RigidBody2Dの基本的な使い方を知りたい

Godotでの物理エンジンの基本となる RigidBody2D ノード の使い方は以下の記事にまとめました。

【Godot】RigidBody2Dの基本的な使い方

より複雑な物理システムを使いたい

Joint2Dを使うと複数の物理オブジェクトを組み合わせることができます。詳細は以下の記事に書きました。

【Godot】2D Jointの使い方

RigidBody2Dの衝突関連のシグナルが発生しない

RigidBody2D の “body_entered” といったシグナルはデフォルトで無効となっています(処理負荷軽減のため…?)。なのでインスペクタから有効にする必要があります。

Contacts Monitor を「オン」にして、Contacts Reported を「10」あたりにします。

  • Contacts Monitor: 衝突検知を有効にするかどうか
  • Contacts Reported: 衝突検知のログを残す件数

ちなみに Contacts Reported の数は衝突検知の最大数なので、衝突が多くなる場合はもう少し数を増やしておきます。

コリジョン関連

コリジョンの領域をデバッグ表示したい

「エディタのメニュー > デバッグ」 から コリジョンの形状の表示」にチェックを入れると実行時にもコリジョンの形状が表示されるようになります。

【Godot】コリジョンの形状を実行時にデバッグ表示する方法

一方通行床が作りたい

上からのみ衝突する床を作る場合には、コリジョンの設定から「One Way Collision」の項目にチェックを入れます

KinematicBody2Dでキャラクターを実装し、一方通行床を作る方法は以下の記事に書きました。

【Godot】KinematicBody2Dの is_on_floor() と One wayコリジョンの使い方

一方通行床の設定に変更はないですが、Godot4.xの場合は CharacterBody2Dを使用しますので、Godot4.x用の記事を書きました。

【Godot4.x】CharacterBody2Dの is_on_floor() と One wayコリジョンの使い方

特定のオブジェクトとのみ衝突するようにしたい

オブジェクトには “name” というプロパティがあるので、それを使って判定する方法があります。

func _on_Shot_area_entered(area):
  # オブジェクト名に "Enemy" または "Boss" が含まれていたら
  if "Enemy" in area.name or "Boss" in area.name:
    area.hit(1) # 敵に1ダメージ
    queue_free() # 自分も消える

もしくは Godot Engine にはコリジョンレイヤーの仕組みがあるので、それを使用して衝突対象を限定することもできます。

詳細は以下の記事に書いています。

【Godot】コリジョンレイヤーとマスクについて

衝突した対象を判定したい

例えば KinematicBody2D.move_and_collide() (Godot4.xの場合はCharacterBody2D) で移動した場合には、戻り値は KinematicCollision2D を返します。そして KinematicCollision2D.collider には CollisionObject2D が含まれるので、そこから collider.collision_layer をビット演算することで判定できます

# 移動と衝突処理を行う
var collision:KinematicCollision2D = move_and_collide(velocity * delta)
if collision:
  # 衝突した
  var collider:CollisionObject2D = collision.collider # コライダーを取り出す
  if collider.collision_layer & (1 << 1) # layer '2' と衝突した.
    collider.do_something() # 衝突した対象との任意の処理を行うことができる

(※ name プロパティで判定する方がお手軽かもしれません )

こちらも詳しくは以下の記事に書いています。

【Godot】コリジョンレイヤーとマスクについて

衝突対象を判定するその他の方法は以下のとおりです。

# 名前を使う
func _on_Wall_body_enter(body):
    if body.name == "Player": # 対象のオブジェクトが複数存在する場合は "in" で比較する.
        print("Collision with player")

# グループを使用する
func _on_Wall_body_enter(body):
    if body.is_in_group("Player"):
        print("Collision with player")

# クラス名を使用する (これには "class_name" を Playerオブジェクトに追加する必要がある)
func _on_Wall_body_enter(body):
    if body is Player:
        print("Collision with player")

# methodが存在するかどうかを確認する
func _on_Wall_body_enter(body):
    if body.has_method("death"):
        print("Collision with player")

Area2Dの衝突の有効無効を切り替えたい

Area2D には monitoringmonitorable の2つの衝突フラグを使って有効無効を切り替えられます。

  • Area2D.monitoring: 自身が衝突を検出するかどうかを判定するフラグ
  • Area2D.monitorable: 他者が衝突を検出できるかどうかを判定するフラグ

レイ(光線)を使った交差判定をしたい

RayCast2Dノードを使用した交差判定の方法は以下のページに書きました。

【Godot】RayCast2Dの基本的な使い方

スクリプトのみでレイキャストする方法については以下の記事に書いています。

【Godot】スクリプトでレイキャストする方法

コリジョンを一時的に無効にしたい

CollisionShape2D / CollisionPolygon2D には disabled というフラグがあるので、これを true にすることでコリジョンを一時的に無効にできます。

コリジョンをすべて無効にしたい (Godot 4.x〜)

1つの CharacterBody2D などに複数のコリジョンを設定している場合は以下の記述ですべて有効・無効を切り替えられます。(※ただし_process() / _physics_process() も無効となります)


## コリジョンの有効・無効を切り替える.
func _set_collision_enabled(b:bool) -> void:
	if b:
		# 有効にする
		unlock_target.disable_mode = CollisionObject2D.DISABLE_MODE_KEEP_ACTIVE
		unlock_target.process_mode = Node.PROCESS_MODE_INHERIT

	else:
		# 無効にする.
		unlock_target.disable_mode = CollisionObject2D.DISABLE_MODE_REMOVE
		unlock_target.process_mode = Node.PROCESS_MODE_DISABLED

サウンド制御

サウンドを再生したい

プロジェクトにサウンドファイル (.wav / .mp3 / .ogg) を追加して、再生したいシーンまたはノードに AudioStreamPlayer2D を追加します。

ノード名を 「AudioDrawCard」とした場合、スクリプトで以下のように記述します。

# 再生
$AudioDrawCard.play()

1つの AudioStreamPlayer2D に対し、1つの再生のみとなります(再生中に play() を呼び出すと再生中のサウンドは停止する)。

再生中には再生したくない場合には playing で判定できます。

if $AudioDrawCard.playing == false:
  # 再生していないときのみ再生する
  $AudioDrawCard.play()

サウンドを動的に読み込みたい

AudioStreamPlayer2D.stream にサウンドリソースを指定すると、動的な読み込みができます。

詳細は以下のページにまとめました。

【Godot】サウンドを動的にロードして再生する方法

BGMを区間リピート再生したい

たとえば「イントロ→A→B」の曲を「A→B」でリピート再生したい場合には「Loop Offset」を設定します。詳細は以下の記事に書きました

【Godot】サウンドの区間リピート再生をする方法

スクロールすると音が小さくなる

AudioStreamPlayer2D はカメラの位置に合わせて、音量が距離減衰します(小さくなる)。音源がカメラの位置に依存しないものにしたい場合は AudioStreamPlayer を使用すると距離減衰が行われなくなります。

ファイル操作

ファイルが存在するかどうかをチェックしたい

var f = File.new()
if f.file_exists("user://savedata.txt"):
  # ファイルが存在するときの処理
else:
  # ファイルが存在しない
  push_error("user://savedata.txt は存在しません")

セーブ周り

セーブデータを保存したい

Fileオブジェクトを使うことでセーブ・ロードすることができます。詳細は以下の記事に書きました。

【Godot】セーブデータの保存方法

Godot4.x用に書き直したセーブデータの保存方法は以下の記事となります。

【Godot4.x】セーブデータの保存方法

可読性の高い ConfigFile に保存する方法は以下の記事に書いています。

【Godot】ConfigFileの使い方

エディタ周り

ショートカットキーを変更したい

「エディター > エディター設定」の「ショートカット」タブから変更できます。

個人的にクイックオープン」はとても便利なショートカットなので、「Ctrl+T (Cmd+T)」など押しやすいキーに設定しておくことをおすすめします。

より詳しくは以下の記事に書いています。

【Godot】よく使いそうなショートカットキーの紹介

出力ウィンドウの制御

ログやエラーが出力される「出力ウィンドウ」はひとまずここをクリックすれば表示・非表示は切り替えられますが、初期設定ではデバッグ実行時に常に表示されてしまいます。

このウィンドウの表示設定をするには、メニューから エディタ > エディタ設定 を選択します。

一般 > Run > Output から出力ウィンドウの設定をします。

  • Always Open Output On Play: デバッグ起動時に出力ウィンドウを自動で表示する
  • Always Close Output On Stop: デバッグ停止時に出力ウィンドウを自動で非表示にする

個人的には出力ウィンドウが常に必要ではなく、必要なときだけ表示したいので、Always Open Output On Play のチェックは外しています。

エディタ拡張をしてみたい

CSVエディタをエディタ拡張で作る例を以下の記事に書きました。

【Godot】エディタ拡張で簡易CSVエディタを実装する方法

その他

リソースのパスを文字列以外の指定にしたい

preload()で読み込むシーンやリソースのパスを文字列以外で指定する方法は以下の記事に書きました。

【Godot4.x】シーン・リソースの指定を文字列以外にする方法

スロー再生をしたい

Engine.time_scale に 1.0 以下の値を指定するとゲーム全体がスローになります。詳しくは以下の記事に書いています。

【Godot】スロー再生する方法

ヒットストップを実装したい

Nodeには set_process() / set_physics_process() といったオブジェクトの更新の有効・無効を切り替える関数が用意されているので、これを使うとヒットストップが実現できます。詳しくは以下の記事に書きました。

【Godot】オブジェクトを一時停止する方法

なお、RigidBody2D はこの方法では停止できないため、apply_impulse() で速度を直接書き換えるしかなさそうなようです。

RigidBody2Dには現在の速度を表すプロパティの “linear_velocity” があります。このベクトルの向きを逆にした値を力に加えることで一時停止できます。

# 一時停止用の保存用速度
var _linear_velocity_tmp = Vector2.ZERO

...

		# 現在の移動量を保存しておく.
		_linear_velocity_tmp = linear_velocity
		# 逆方向に力を加えることで動きを止める.
		apply_central_impulse(-linear_velocity)

そして、更新が再開したタイミングで保存した速度で力を加えることで、動きを再開できます。

func _process(delta: float) -> void:
	if _linear_velocity_tmp.length() != 0:
		# 保存した速度を反映.
		apply_central_impulse(_linear_velocity_tmp)
		_linear_velocity_tmp = Vector2.ZERO # ゼロにする.

ウィンドウをリサイズしたい

スクリプトから画面サイズを変更するには OS.set_window_size() を使用します

# ウィンドウを 480x320 に変更する
OS.set_window_size(Vector2(480, 320))

なおウィンドウをリサイズしても表示物はそのままのサイズなので、プロジェクト設定の「表示 > ウィンドウ」から「ストレッチ」の設定を以下のように変更すると、リサイズに合わせて表示物のサイズもストレッチされるようになります。

  • モード:2d または viewport
  • アスペクト:keep

プロジェクト設定を取得したい

プロジェクト設定の情報は ProjectSettings.get() で取得できます。

以下は 2Dコリジョンのレイヤー名を取得する例です。

var collision_layer:int # コリジョンレイヤー番号
var layer: String = ProjectSettings.get(str("layer_names/2d_physics/layer_", collision_layer + 1))

他の設定を取り出すには公式ドキュメントを参照します。

GDScript

オブジェクト・インスタンス

対象のインスタンスが破棄されたかどうか

is_instance_valid() でそのインスタンスが有効化どうかを判定できます (※null かどうかでは有効なインスタンスであるかどうかは必ずしも判定できません)

var obj; # 何らかのインスタンス.
if is_instance_valid(obj) == false:
  # objは無効なインスタンス.
  print("objは破棄済みです")

なお queue_free() による破棄リクエストが行われたかどうかは is_queued_for_deletion() で判定できます。(※例えば、衝突系のシグナルでお互いを破棄するときに、複数回破棄処理が行われないようにする…といったチェックができます)

## 他の剛体と衝突した.
func _on_body_entered(body: Node) -> void:
	if self.is_queued_for_deletion():
		return # すでに破棄要求されている.
	if body.is_queued_for_deletion():
		return # すでに破棄要求されている.
		
	# フルーツとヒットした.
	var other = body as Fruit
  ...

自身のインスタンスIDを知りたい

get_instance_id() で自身のユニークなインスタンスIDを取得できます。特定のグループに自分を含むインスタンスが登録されているものの、自分以外のすべてと判定したい場合などに、このIDを使用します。

インスタンス固有の情報を設定したい

できればメンバ変数 (プロパティ) を追加したほうがよいですが、とりあえず追加したい場合は get_meta() で文字列をキーとした値を設定できます。取り出しは get_meta() で行います。

インスタンスの型情報を判定したい

is」キーワードで型比較ができるのでそれで判定します。

if obj is KinematicBody2D:
  print("objは KinematicBody2D")

(シーン)オブジェクトの型情報をスクリプトで定義したい

(シーン)オブジェクトはデフォルトでは型情報は定義されません。class_name キーワードを指定することで型情報を明示的に定義する必要があります。

extends KinematicBody2D

class_name Enemy # 型情報を定義.

...

func is_alive() -> bool:
	return _state == eState.MAIN

このように定義して型情報を明示的に記述すると、別のスクリプトからでも補完ができるようになっておすすめです。

なお、インスタンスを生成するための preload() で読みんだ(シーン)オブジェクトを格納するための変数は、型ではなくて変数であるので、この名前は異なる名前にしておくと良いです。

extends Node2D

# もとはEnemy型となるので、"EnemyObj" のように別名にしておく
const EnemyObj = preload("res://src/enemy/Enemy.tscn")

インスタンスの情報をprint()で出力したい

オブジェクトのインスタンスを print() で出力しても得られるのはリファレンス番号のみとなります。そこで、_to_string() を実装すると、print() でも情報が出力されるようになります。

class Obj:
	var name:String = "勇者"
	var hp:int = 100
	var mp:int = 20
	# 文字列表現を返す
	func _to_string() -> String:
		return "%s hp:%d mp:%d"%[name, hp, mp]

func _ready() -> void:
	var obj = Obj.new()
	print(obj)

インスタンスの動きを一時停止したい

get_tree().paused でゲーム全体を停止する方法と、特定のインスタンスのみ停止する Object.set_process() を使用する方法があります。

ゲーム全体を停止したい場合は以下の記事が参考になるかもしれません。

【Godot】ゲームを一時停止するポップアップウィンドウの実装方法

特定のオブジェクトのみ停止したい場合は以下が参考になると思います。

【Godot】オブジェクトを一時停止する方法

フレームレート固定で呼びされる更新関数を使いたい

_physics_process() 内で処理を行うことで更新タイミングが固定化されます

_prcess() の呼び出しは可変レートであり、呼び出される間隔は不定となります。それに対して物理システムの更新関数 _physics_prcess() はフレームレート固定で呼び出されるためとなります。余談ですが、Godot 2.x では _fixed_process() という関数があったのですが、Godot 3 に移行したときにこの仕様に置き換えられたようです。

シーンの制御

別のシーンを読み込む

get_tree().change_scene() で別のシーンを読み込むことができます。

# Main.tscn に遷移する
get_tree().change_scene("res://Main.tscn")

シングルトン(常駐)のスクリプトを定義したい

プロジェクト設定から「自動読み込み」に、スクリプト(.gd) または シーン (.tscn) を設定すると、その名前でどこからでもアクセスできる常駐のスクリプト・シーンとなります。

乱数

乱数の基本的な使い方を知りたい

乱数は、整数の乱数を得る randi() 、浮動小数点の範囲を指定してその間で乱数を得る rand_range() などがあります。詳細は以下の記事に書きました。

【Godot】乱数の使い方について

数学

三角関数について知りたい

Godot Engineにおける基本的な(ゲームでよく使う)三角関数は以下のとおりです。

  • cos(): コサインの値を得る (引数はラジアン)
  • sin(): サインの値を得る (引数はラジアン)
  • atan2(): アークタンジェント2
  • deg2rad(): 引数に角度を与えるとラジアンに変換する
  • rad2deg(): 引数にラジアンを与えると角度に変換する

より詳しくは公式ドキュメント GODOT DOCS > @GDScript にかかれています。

ベクトルを操作する関数について知りたい

Vector2 のよく使いそうな関数については以下の記事にまとめました。

【Godot】Vector2でよく使いそうな関数まとめ

曲線

動的にベジェ曲線を作りたい

スクリプトでCurve2D モジュールを使うと、始点と終点、制御点を指定することでベジェ曲線を作ることができます。

詳しくは以下の記事に書きました。

【Godot】Curve2Dを使ったベジェ曲線の作り方

Array

Arrayでよく使いそうな関数は以下の記事にまとめました。

【Godot4.x】Arrayのよく使う関数まとめ

Arrayの中身をシャッフルしたい

Array.shuffle() で配列の中身をシャッフルできます。

func _ready() -> void:
    # 乱数初期化
    randomize()

    # 山札作成
    var deck = [1, 2, 3, 4, 5, 6, 7, 8, 9]

    # 山札をシャッフル
    deck.shuffle()

    print(deck)

独自のソートを実装したい

Array.sort() は標準の比較演算子によるソートとなるので、独自のソート処理を行いたい場合には、Array.sort_custom() を使用します。

# カードを "pos_index" でソートするクラス
class CardSorter:
    static func sort_ascending(a:Card, b:Card) -> bool:
        # 昇順ソート
        if a.pos_index < b.pos_index:
            return true
        return false

    static func sort_descending(a:Card, b:Card) -> bool:
        # 降順ソート
        if a.pos_index > b.pos_index:
            return true
        return false

呼び出しは以下のように記述します。

func get_pyramid_list():
    # ピラミッドに含まれるカードのリストを返す
    var ret = []
    for c in cards:
        var card:Card = c
        if card.place == Card.ePlace.Pyramid:
            ret.append(card)

    # 昇順ソート
    ret.sort_custom(CardSorter, "sort_ascending")

    return ret

そのスクリプト内でしか使用しなければ、self を使っても良いです。

func sort_ascending(a:Card, b:Card) -> bool:
  # 昇順ソート
  if a.pos_index < b.pos_index:
    return true
  return false

# 呼び出し
var arr = []
arr.sort_custom(self, "sort_ascending")

ちなみに Godot.4.x 以降では lambda 式がサポートされるようになるので、式が渡せるようになるのかもしれません。

文字列操作

文字列操作の便利関数を知りたい

よく使いそうな文字列操作関数を紹介します。

  • length(): 文字列の長さを求める
  • find(): 指定の文字の位置を返す
  • to_int(): intに変換する
  • to_float(): floatに変換する
  • hex_to_int(): 16進数の文字列表現をintに変換する
  • to_upper(): 大文字に変換する
  • to_lower(): 小文字に変換する
  • split(): 文字列を分割する
  • replace(): 指定の文字を別の文字に置き換える
  • strip_edges(): 文字の前後の空白文字を削除する
  • pad_decimals(): 小数部のゼロ埋め
  • pad_zeros(): 整数部のゼロ埋め

使い方の詳細は公式ドキュメント GODOT DOCS > String 参照のこと。

【Godot】文字列操作の便利関数まとめ

文字列を式として評価したい

Godot Engine (GDScript) には、”Expression” というモジュールが用意されているのでそれを使うと文字列を式として評価することができます。こういった関数は、自作のスクリプト言語を作るときに便利だったりします。

var expression = Expression.new()
# 評価したい文字列表現を渡す
expression.parse("(1+2) * 5")
# 式として評価する
var result = expression.execute()

# "15" と出力される
print(result)
【Godot】文字列を式として評価する方法

未使用変数の警告を消したい

関数の引数で未使用変数の警告を消したい場合がたまにあります。例えば _process(delta) の delta が未使用である場合です

func _process(delta):
  pass

このように未使用変数は警告が出てしまうのですが、引数の変数名の前に「_」をつけると未使用変数として警告を抑制することができます。(_deltaなど)

func _process(_delta):
  pass

エクスポート関連

Steam向けに出力したい

GodotSteamからGodotで Steamworks を利用するためのモジュールをダウンロードします (おそらくエンジンビルドが必要)。

まだ試していないですが、GDNativeを使っていると少しビルドがややこしそうな感じです。

Android向けにビルドしたい

少し昔に書いた記事ですがビルド手順をまとめておきました。

ただ色々と不完全な記事なので、今後調べ直して新しく記事を書きたいと思っています…。

Webブラウザ向け (HTML5) に出力したい

HTML5で出力する方法については以下の記事に書きました。

【Godot】HTML5へのエクスポート手順

ただ、HTML5は GDNativeが動かなかったり、Webサーバーがないと動作確認できない、などの制限があります。

チュートリアル

2Dクリックゲームチュートリアル

公式のチュートリアル (最初の2Dゲーム – Godot Docs) が最初に作るにはややヘビーな内容と個人的に感じて、かなりシンプルなものに削ぎ落としたチュートリアルです。

【Godot】2Dクリックゲームチュートリアル (1/3)

Godot Engine でゲームを作る上で、以下の最低限必要な機能を理解することを目的としました。

  • プロジェクトの作成方法
  • シーンの仕組み
  • 当たり判定を持つオブジェクトの作り方
  • オブジェクトを動かす方法
  • オブジェクトを消滅させる方法
  • シグナルの使い方
  • パーティクルの使い方

フラッピーバードを作るチュートリアル

2D Platformer (プラットフォーマー) はゲーム開発者には人気のジャンルですが、個人的に初心者が手を出すには難易度の高いジャンルと思っていて、もう少しシンプルなものを作った方が良いのかな…と思って用意したチュートリアルです。

学べることとしては以下のとおりです。

  • 2Dアクションゲームを作るときに便利な KinematicBody2Dの使い方(移動と衝突)
  • スプライトのフレーム番号を変更してアニメーションする方法
  • ゲームオブジェクトの動的な生成と破棄の方法
  • フォントの設定方法

ラン&ジャンプゲームを作るチュートリアル

ゲーム開発者に人気の 2D Platformer (プラットフォーマー) のシンプルなルールである「ラン&ジャンプゲーム」のチュートリアルを書きました。

スクロールや地形の自動生成、一方通行床や2段ジャンプの実装方法について学べる記事となっています。

【Godot】ラン&ジャンプゲームのチュートリアル

会話イベントを楽に作れるアドオン「Dialogic」の紹介

Visual novel (ノベルゲーム) は一部に人気のゲームジャンルで、「Godot Engine でノベルゲームを作りたい人は多いのかも…?」と思って、「Dialogic」というアドオンの使い方を解説した記事となります。

【Godot】会話イベントが楽に作れるアドオン「Dialogic」の紹介

ただ、Dialogicは日々進化を続けていて、最新のバージョンとは動作が異なる部分があるのかもしれません。

個人的にはノベルゲームエンジンは自作したい派なので、自作するときの基本的な機能の説明については以下の記事に書きました。

こちらの記事に書いたように、スクリプトエンジンとしては字句解析や構文解析を作ってプログラム言語に近いものを自作するのがおすすめですが、吉里吉里のKAGのような「1行1命令」のシンプルな実装もありかもしれない…と思って、吉里吉里のKAGを自作する方法についての記事も書いています。

【Godot】吉里吉里のKAGっぽいスクリプトを自作するヒント

クォータービューの基本的な作り方

Godot Engine は標準機能でクォータービューが作れる素敵なゲームエンジンです。クォータービューは Turn-based (ターン制) のストラテジーゲームに向いているので、そういったゲームを作りたい方におすすめの記事となります。

【Godot】クォータービューの基本的な作り方

落ち物ゲームの作り方

落ち物ゲームの実装サンプルとして、マッチ3ゲームを作ってみたのでサンプルコードと、そのコードを解説する記事を書いています。

【Godot】マッチ3ゲームの実装サンプルと解説

外部リンク

他にもTips(メモ書き)をまとめている方がいらっしゃるので、リンクしておきます。