【Godot】Godotの描画順入門:キャラが木の後ろに回り、HUDは常に手前に残る

作成: 2026-09-22最終更新: 2026-10-10

見下ろしのマップでキャラが木の後ろへ回るように、CanvasLayer・z_index・Y Sortの3段の描画順を整理して解説します。

見下ろしのマップでは、キャラが木より下(画面の手前側)にいるときは幹の手前に、上へ回ったら幹の裏に隠れてほしくなります。Godot では、Y座標の順に並べ替える Y Sort でこれを作ります。

前後を決める数字の z_index で直そうとすると、キャラは一度も隠れなくなるか、常に隠れるかのどちらかになります。z_index は歩くたびに入れ替える数字ではなく、描く段そのものを移す数字だからです。

この記事では、CanvasLayer・z_index・Y Sort がそれぞれどこまで効くかを整理して、キャラが木の後ろへ回るようにする方法を解説します。

同じ z_index 0 のまま、左では人形が幹の手前に立ち、右では幹の後ろに回って胴体が幹に隠れている

この記事でわかること

  • 描画順が3段に分かれていて、段をまたぐと数字が届かないこと
  • Y Sort Enabled をどのノードに付けるのか
  • Y Sort が比べるのはノードの原点で、絵の足元に合わせる方法
  • 子の z_index が親からどう足されるのか

動作確認環境: Godot 4.7

Sponsored

描画順を決める3つの段

Godot の2Dは、次の3段で前後を決めます。

  1. どの CanvasLayer に載っているか
  2. 同じキャンバス(2Dの絵が描き込まれる1枚の板)の中の実効 z_index。大きいほうが手前
  3. 同じ実効 z の中の並び。ツリー順か、Y Sort の順
描画順は CanvasLayer・実効 z_index・同じ z の中の並びの3段で決まり、上の段が違うと下の段の数字は届かない

上の段が違う相手とは、下の段の数字では争えません。

「実効 z」というのは、そのノードで実際に使われる z のことです。あとで出てくるとおり、子の z_index は親の値に足されるので、インスペクタで見える数字とは違う値になることがあります。

他のエンジンでいうと: Unity の2Dでは、固定の前後を決める z_index が Sorting Layer と Order in Layer、Y Sort が Transparency Sort Mode を Custom Axis・(0, 1, 0) にした並べ替え、キャラの部品を外に対して一式で並べるのが Sorting Group に近い役割です。

CanvasLayerどうしの前後

CanvasLayer は、絵を描く板を1枚増やすノードです。layer の数字が大きいほうがまとめて手前に来て、板どうしの中身は混ざりません。

同じ板なら z_index 100 のキャラがハートより手前に出るが、板を分けると CanvasLayer の境目で止まる

HUD(体力や得点など、画面に重ねて出す表示)やポーズ画面を CanvasLayer の下に置くのは、この性質で「常に手前」を固定するためです。かわりに、ワールド側からその前後へ割り込む手段も無くなります。キャラの Z Index を 100 にしてもハートの後ろのまま、というのはこれが起きています。

割り込みたいときは、そのノードもHUDより大きい layer の CanvasLayer へ移します。CanvasLayer は既定で画面に固定されます。ワールドの物として、カメラを動かすと画面の中で流れていくように置きたいなら、Follow Viewport もオンにします。ロード画面を 100 のような大きめの値にしておく話は 動的ロード入門 にあります。

ここから先は、同じキャンバスの中の話です。

Sponsored

同じ層の中のツリー順

Z Index を1つも触っていないシーンでは、全員が同じ層(同じ実効 z)にいます。この中の前後はシーンツリーの並びで決まり、ツリーで下にあるノードほど後から描かれて手前に出ます。

床を先に置き、その上に立つものをあとに並べれば足ります。TileMapLayer を3枚重ねるときも同じで、草を床の上に出したいなら草のレイヤーをツリーの下へ置きます(TileMapLayer入門)。

行き止まりが来るのは、キャラと木を兄弟に並べたときです。ツリーの並びは動かないので、キャラが北へ歩いても南へ歩いても前後が変わりません。

Player の Z Index を 1 にすると、人形が上にいても下にいても、幹の手前から動かなくなる

キャラの Z Index を 1 にすれば、確かに木より手前に出ます。かわりに一度も隠れなくなります。木を 2 にすれば、今度は常に隠れます。z_index で決められるのは「どっちが上か」だけです。値を入れておくだけでは、歩く位置に合わせて自動で入れ替わりはしません。

入れ替わってほしいものには、z_index を使いません。

Y Sortの付け方と比べる位置

Y Sort は、同じ層の中の並びを、ツリー順ではなくY座標の順に変えます。Yが大きい、つまり画面で下にいるものほど手前です。見下ろしのゲームで「手前にいる=カメラに近い」を表すのが、このYです。

つまずくのはオンにする場所です。Y Sort Enabled は、そのノードの中をYの順に並べ替えるスイッチです。キャラ自身と木自身にそれぞれ付けても、それぞれの中を並べ替えるだけなので、2人の前後は変わりません。

Tree と Player に Y Sort を付けても前後は変わらず、2つを抱える親の Actors に付けると人形が幹の裏へ回る

付ける相手は、キャラと木を兄弟として抱えている親です。

Level (Node2D)          Y Sort Enabled = オフ
├─ Ground
└─ Actors (Node2D)      Y Sort Enabled = オン   ← ここだけ
   ├─ Tree
   └─ Player

Godot 3 にあった YSort というノードは、Godot 4 には無くなりました。同じ役割が、この Y Sort Enabled です。

比べているのは、絵の輪郭でも重なり具合でもなく、ノードの原点のYです。エディタでノードを選んだときに出る十字が、その点になります。

Sprite2D は Centered が初期状態でオンなので、原点は絵の真ん中にあります。このままだと、切り替わりも絵の真ん中で起きます。読者が期待するのは足元と根元なので、ここがずれると「効いていない」ように見えます。

Centered のままでは原点が絵の中心にあり、Offset を (0, -64) にすると原点が絵の下辺に来る

直し方は、ノードの位置を足元に置いて、絵のほうを Offset で上へずらすことです。128×128 の画像なら Offset を (0, -64) にすると、絵の下辺がノードの位置に来ます。Centered はオンのままでかまいません。

もうひとつ、キャラのシーンの中には付けないでください。キャラ側でオンにすると、体・影・武器がそれぞれ別の参加者として並び始めます。武器を少し上に持たせていれば、そのYは体より小さいので、武器だけが体の奥へ回ります。

Sponsored

z_indexと親子の足し算

z_index は、層そのものを移す数字です。子に付けたときだけ、考えることが少し増えます。

Z As Relative は初期状態でオンです。このとき子の実効 z は、親の実効 z に自分の z_index を足した値になります。親が 10 で子が 1 なら、子は 11 です。オフにすると親の値は足されず、自分の z_index がそのキャンバスの中の値になります。どちらにしても CanvasLayer は越えません。

親の Y Sort がオフで同じ実効 z のとき、子は親より後に描かれます。子を 0 にしても親の後ろには回りません。回す方法は2つあって、Z Index に -1 を入れるか、Show Behind Parent(z はそのままで、親より先に描くチェック)をオンにするかです。この2つは結果が違います。-1 のほうは実効 z そのものを下げるので、親との前後だけでなく、外にいる相手との関係まで変わります。

影に Z Index -1 を入れると、実効 z が -1 になり、実効 z 0 の地面より奥へ潜る

ここが影でつまずくところです。影をキャラの子に置いて、体より後ろに回そうと -1 を入れると、体の後ろには回ります。かわりに実効 z が -1 になるので、地面が 0 のままなら地面より奥へ潜ります。キャラの中で直したつもりが、キャラの外の地面との勝負になっています。影は 0 のまま、ツリーで体より上に置けば、体の後ろで地面の手前に出ます。

ノード親Z Index実効 z見える位置
GroundLevel00影より手前(ほかより奥)
TreeActors00Player とYで争う
PlayerActors00Tree とYで争う
ShadowPlayer-1-1地面の下に消える
WeaponPlayer11常に木より手前

表の下2行(影と武器)が、つまずきやすいところです。

そのままなら体と武器が一式で木と比べられ、Weapon に Z Index 1 を入れると武器だけがまとまりから抜ける

部品の実効 z が体と違う値になると、その部品は親のまとまりから出て、外の相手と直接勝負を始めます。 武器を 1 にすると、キャラが木の裏へ回っても武器だけが幹の手前に残ります。

部品どうしの前後だけを決めたいなら、Z Index は全部 0 のままにして、ツリーの上下で並べます。影・体・武器の順に置けば、影は体の下、武器は体の上です。そして一式がキャラの足元を基準にして、まとめて木と入れ替わります。

実践:木の前と後ろに、歩いて回る

見下ろしARPGの森、牧場シミュレーションの果樹と住人、トップビューのシューティングで柱の裏に隠れる場面——どれも同じ形です。ここでは木を1本とキャラを1人だけ置いて、Z Index を1つも触らずに前後を入れ替えます。

① 置くもの

新しいシーンを1つ作ります。絵はプロジェクトに最初から入っている icon.svg だけを使うので、素材の用意は要りません。

ルートに Node2D を置いて Level、level.gd を付けます。

  • Level の子に ColorRect を置いて Ground。位置 (0, 0)、Size を (1152, 648)、Color を濃いグレー、Mouse Filter を Ignore(クリックを受け取らない)
  • Level の子に Node2D を置いて Actors。インスペクタの Ordering にある Y Sort Enabled をオンにする
  • Actors の子に Sprite2D を置いて Tree。位置 (400, 300)、Texture に icon.svg、Scale を (0.6, 1.4)、Offset を (0, -64)
  • Actors の子に CharacterBody2D を置いて Player。位置 (400, 360)、Motion Mode を Floating、Y Sort Enabled はオフのまま
  • Player の子に CollisionShape2D(CircleShape2D・半径 16)
  • Player の子に Sprite2D を3つ。上から Shadow(icon.svg・Scale (0.35, 0.12)・Modulate(絵に掛ける色)を黒)、Body(icon.svg・Scale (0.4, 0.4)・Offset (0, -64))、Weapon(icon.svg・Scale (0.15, 0.15)・位置 (24, -36))
  • Level の子に CanvasLayer を置いて Hud。Layer は 1 のまま。その子に Label を置いて InfoLabel、位置 (16, 16)
  • Tree・Player・InfoLabel は、右クリックして「Access as Unique Name」をオンにする

Ground の Size は画面と同じ数字です。プロジェクト設定で画面の大きさを変えているなら、そちらに合わせてください。Ground は Actors よりツリーの上にあるので、Z Index を触らなくても常にいちばん奥に描かれます。

Tree の Offset を (0, -64) にしてあるので、絵の下辺が (400, 300) に来ます。この点が幹の根元で、前後が切り替わる高さです。Player も同じ理屈で、原点が足元にあります。見下ろしなので Motion Mode は Floating にしておきます(モーションモードの違い)。

② 組み立て

# level.gd
extends Node2D

const SPEED := 160.0

@onready var player: CharacterBody2D = %Player
@onready var tree_node: Sprite2D = %Tree
@onready var info: Label = %InfoLabel

func _physics_process(_delta: float) -> void:
	var direction := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	player.velocity = direction * SPEED
	player.move_and_slide()
	info.text = "Player Y %.1f / Tree Y %.1f" % [   # %.1f は小数1桁で出す
		player.global_position.y, tree_node.global_position.y
	]

やっていることは移動と、2つのYを画面に出すことだけです。前後を決めるコードは1行もありません。ラベルに出しているYが、Y Sort が実際に比べている値です。

%Player のような書き方は、ツリーの道順ではなく固有名でノードを取ります。あとでツリーを組み替えても、この3行は書き換えずに済みます(ノードの取り方)。

③ 動かして確かめる

Y 320 では人形が幹の手前、280 では裏に隠れる。武器に Z Index 1 を入れると武器だけ幹の上に残る

F6(いま開いているシーンを実行)で動かし、矢印キーで上下に歩きます。見るのは3つです。

開始位置の 360 では、体と幹は離れています。上へ歩くと 351 あたりから重なり始め、320 では体の上6割が幹と重なります。それでも Player Y が Tree Y の 300.0 より大きいあいだは、体が手前です。さらに上へ歩いて 280 まで来ると、体は幹の裏に回って見えなくなります。Z Index はどちらも 0 のままで、切り替わるのは 300 をまたいだ1フレームです。だんだん透けるのではなく、まるごと入れ替わります。

次に、Actors の Y Sort Enabled をオフにしてみます。Yをどこへ動かしても、体が幹の手前から動かなくなります。オンに戻して 280 のあたりで体を幹に隠したまま、Weapon の Z Index を 1 にすると、武器だけが幹の上に残ります。部品の実効 z が体と違う値になると、その部品だけが一式から抜けるのが見えます。

最後に、Weapon を 0 に戻し、360 まで下へ歩いてから Player の Y Sort Enabled をオンにします。武器が体の奥へ回り、部品が別々に並び始めます。Player の Z Index を 100 にして左上のラベルの上まで歩いても、ラベルは手前のままです。試したものは、そのつど元へ戻してください。

ポイントは2つです。

  • 入れ替わってほしいものは、実効 z をそろえて Y Sort に任せる: この記事の実践が Z Index を1つも使わないのは、そのためです。相手と実効 z が違った瞬間、Yでの入れ替わりは止まります
  • 並べる範囲を作るのは親、一式で動くのは Y Sort がオフのノード: Actors をオンにすると、その中が並べ替えの対象になります。Player をオフのままにしておけば、体・影・武器が一式で1人分として扱われます。部品の実効 z を体と違う値にすると、その部品だけが一式から抜けます

影と体の前後を変えたくなったら、Z Index ではなく Shadow と Body のツリー順を入れ替えてください。同じ層の中で済むので、地面との関係は変わりません。

うまくいかないときは

症状原因直し方
木を Trees の下にまとめたら、キャラが森ぜんぶの手前か奥にしか来ない入れ物の Trees がオフで、森が Trees の原点のYで1人として並ぶTrees でも Y Sort Enabled をオンにする。TileMapLayer に木を描いたときも同じ
木とキャラの両方に Y Sort Enabled を付けたのに、前後が入れ替わらないY Sort Enabled は、そのノードの中を並べ替えるスイッチ。木とキャラそれぞれの中を並べ替えているだけ木とキャラを兄弟として抱えている親(Actors)でオンにする
前後が切り替わる高さが、幹の根元ではなく絵の真ん中Sprite2D の Centered がオンで、ノードの原点が絵の中心にあるノードの位置を足元に置き、Offset で絵を上へずらす(128×128 なら (0, -64))
整理のために素の Node の下へ移したら、Y Sort が効かなくなった素の Node は CanvasItem(Node2D や Sprite2D、Control の共通の親)ではないので、そこで位置・z の足し算・Y Sort のつながりが切れる入れ物には Node2D を使う

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

  • 木をタイルで置くとき: 背の高いものを TileMapLayer に描いたなら、そのレイヤーを Actors の子にして、レイヤー側でも Y Sort Enabled をオンにします。オフのままだと森ぜんぶが1枚として比べられ、キャラが森ぜんぶの手前か奥に出ます。根元の高さがずれるタイルは、TileSet の Rendering にある Y Sort Origin で直します
  • 同じ番号の CanvasLayer を2つ作らない: layer が同じでも2枚の板の中身は混ざらず、どちらが手前かはツリーの並びで決まります。置き場所を変えただけで入れ替わるので、前後をはっきりさせたいものには違う数字を振ります
  • 画面の暗転も板ごと: ワールドを暗くする CanvasModulate は CanvasLayer 単位で効くので、板を分けると暗転の範囲も分かれます(2Dライティング入門)
Sponsored

まとめ

  • 描画順は3段: CanvasLayer → 実効 z_index → 同じ層の中の並び。上の段が違う相手とは、下の段の数字では争えない
  • 同じ層の中は、既定でツリー順: ツリーで下にあるノードほど手前に描かれる
  • Y Sort は親に付ける: Y Sort Enabled はそのノードの中をYの順に並べ替えるスイッチ。並べたいもの同士を抱えている親でオンにする
  • 比べるのはノードの原点のY: Sprite2D は原点が絵の中心なので、Offset で絵を上へずらして足元に合わせる
  • 入れ替わってほしいものに z_index は使わない: 子の z_index は親に足され、部品の実効 z が体と違うと、その部品だけが一式から抜ける

まずは自分のシーンで、いま z_index が入っているノードを1つ選んでみてください。「常にこっち」を決めたくて入れた数字なら、そのままで合っています。上下で入れ替わってほしくて入れた数字なら、それは Y Sort の仕事です。あなたのゲームで、キャラが裏へ回れるようにしたいものは何でしょうか。

次に読む学習パスの次の記事
描画・エフェクト

Godot 2Dライティング入門: PointLight2Dと影の設定で実現する深みのある表現

この記事を読む
Godot このセクションのノート104