← 목차
Godot 4.7 · 노드 구조

인스펙터는
상속 사슬이다

노드를 고를 때 본 상속 사슬과 인스펙터에 늘어선 그룹은 같은 것을 두 방향으로 보여주는 화면입니다. 이걸 알면 어떤 속성이 왜 거기 있는지가 전부 설명됩니다.

4.7.2.stable 에서 확인 --doctool 로 대조 요약본 · 상세는 아래 링크

한 장으로 보기

왼쪽 Create New Node 창의 CSGCylinder3D 상속 사슬과 오른쪽 인스펙터의 그룹이 화살표로 일대일 대응하는 화면
왼쪽은 Create New Node 창, 오른쪽은 인스펙터입니다. 왼쪽 아래 Description 의 상속 사슬 한 줄이, 오른쪽에서는 위에서 아래로 늘어선 그룹 머리글로 그대로 나타납니다. (이미지를 클릭하면 원본 크기)

세 가지 질문에 답하면

인스펙터 맨 위가 현재 노드고, 아래로 부모 클래스 속성이 이어지나요?
그렇습니다. 맨 위가 그 노드만의 것이고, 내려갈수록 더 많은 노드가 공유하는 것입니다.
Node3D 를 상속하면 전부 Transform·Rotation·Scale 을 갖나요?
그렇습니다. 엔진에서 세어 보니 120개 클래스가 해당합니다.
그 값을 수정할 수 있나요?
그렇습니다. 인스펙터에서도, 코드에서도 똑같이 다룹니다.

두 화면이 어떻게 대응하나

노드를 추가할 때 뜨는 창의 Description 첫 줄이 상속 사슬입니다.

Class CSGCylinder3D < CSGPrimitive3D < CSGShape3D < GeometryInstance3D
      < VisualInstance3D < Node3D < Node < Object

엔진에서 확인한 사슬도 정확히 같습니다. 그리고 인스펙터가 이것을 뒤집어 늘어놓습니다.

Create New Node 의 사슬                인스펙터의 그룹 (위 → 아래)
────────────────────────              ─────────────────────────
CSGCylinder3D          ─────────────→  ▸ CSGCylinder3D   ← 현재 노드 자신
  < CSGPrimitive3D     ─────────────→  ▸ CSGPrimitive3D
  < CSGShape3D         ─────────────→  ▸ CSGShape3D
  < GeometryInstance3D ─────────────→  ▸ GeometryInstance3D
  < VisualInstance3D   ─────────────→  ▸ VisualInstance3D
  < Node3D             ─────────────→  ▸ Node3D          ← Transform 이 여기
  < Node               ─────────────→  ▸ Node
  < Object                              (Object 는 표시되지 않는다)

인스펙터에서 어떤 속성이 안 보이면, 그 노드가 그 클래스를 상속하지 않는 것입니다. 반대로 낯선 그룹 이름이 보이면 그것이 이 노드의 조상입니다.

Node3D 가 주는 것 — 9개

프로퍼티기본값
positionVector3(0, 0, 0)
rotationVector3(0, 0, 0)
scaleVector3(1, 1, 1)
transformTransform3D(1,0,0, 0,1,0, 0,0,1, 0,0,0)
rotation_edit_mode0 (Euler)
rotation_order2 (YXZ)
top_levelfalse
visibletrue
visibility_parentNodePath("")

인스펙터의 Node3D > Transform 을 펼치면 나오는 Position·Rotation·Scale, 그 아래 Rotation Edit Mode·Rotation Order·Top Level·Visibility정확히 이 목록입니다.

사슬 길이는 달라도 결과는 같다

노드상속 사슬
Camera3DCamera3D < Node3D
CollisionShape3DCollisionShape3D < Node3D
MeshInstance3D… < GeometryInstance3D < VisualInstance3D < Node3D
CharacterBody3D… < PhysicsBody3D < CollisionObject3D < Node3D
DirectionalLight3D… < Light3D < VisualInstance3D < Node3D

끝에 Node3D 가 있으면 결과는 같습니다. 그래서 카메라를 옮기든 캐릭터를 옮기든 Position 을 고치는 방법은 하나입니다.

🛑 반례 — WorldEnvironment 에는 Transform 이 없다

WorldEnvironment < Node < Object      ← Node3D 가 없다

하늘·안개는 공간의 한 지점에 있는 것이 아니라 씬 전체에 걸리는 설정이라 위치가 필요 없습니다. 인스펙터에도 Transform 그룹이 나오지 않습니다. "3D 씬에 있으니 당연히 위치가 있겠지"가 아니라 상속 사슬이 답입니다.

읽어보기 — MeshInstance3D 의 인스펙터

MeshInstance3D 를 선택하면 그룹이 다섯 개 나옵니다. 각 그룹은 그 클래스가 새로 보탠 것만 담습니다. 아래는 실제 인스펙터를 그대로 옮긴 것입니다.

MeshInstance3D 무엇을 그릴 것인가
Mesh <empty>
Skeleton
▢ GeometryInstance3D 어떻게 그릴 것인가
Geometry cast_shadow · material_override
Global Illumination gi_mode
Visibility Range lod_bias
⋮⋮ VisualInstance3D 어느 레이어에
Layers layers
Sorting sorting_offset
○ Node3D 어디에 놓을 것인가
Transform position · rotation · scale
Visibility visible
○ Node 트리의 일원으로서
Process process_mode
Physics Interpolation
Auto Translate
Editor Description

아래로 갈수록 추상적이고 위로 갈수록 구체적입니다. Node 는 "트리에 있다", Node3D 는 "공간에 있다", VisualInstance3D 는 "화면에 그려진다", GeometryInstance3D 는 "형상을 그린다", MeshInstance3D 는 "이 메시를 그린다".

🛑 추가했는데 왜 아무것도 안 보이나

Mesh<empty> 이기 때문입니다. 그릴 형상이 없으니 그릴 것도 없습니다.

갓 만든 MeshInstance3D
  mesh       = <Object#null>
  get_aabb() = [P: (0,0,0), S: (0,0,0)]      ← 차지하는 공간이 0

BoxMesh 를 넣으면
  get_aabb() = [P: (-0.5,-0.5,-0.5), S: (1,1,1)]
  삼각형 12개 · 정점 24개 (인덱스 36개)

MeshInstance3D 는 "메시를 담는 그릇"이지 형상 자체가 아닙니다. 같은 그릇이 어떤 메시를 담느냐에 따라 상자도 되고 사람도 됩니다.

mesh 는 물려받은 것인가 — 고유합니다

각 클래스가 자기가 선언한 프로퍼티만 뽑아 확인했습니다.

클래스자기가 선언한 mesh
MeshInstance3D✅ 있다
GeometryInstance3D
VisualInstance3D
Node3D
Node

meshMeshInstance3D 가 처음 도입한 것이라 인스펙터에서도 맨 위 그룹에 놓입니다. 위치는 우연이 아닙니다.

Mesh · 삼각형 · Collision

용어한 줄
Mesh(메시)삼각형을 모아 만든 3D 형상 데이터. 노드가 아니라 리소스라서 여러 노드가 공유한다
삼각형3D 형상의 최소 단위. GPU 는 삼각형만 그린다 — 상자 하나가 12개(실측)
Collision부딪히는 모양. 보이는 메시와 별개이고, 없으면 그냥 통과한다

보이는 것과 부딪히는 것은 다른 물건입니다. MeshInstance3D 는 보이기만 하고 부딪히지 않습니다. 부딪히게 하려면 StaticBody3D + CollisionShape3D 를 따로 둡니다.

MeshInstance3DCSGBox3D 를 나란히

MeshInstance3D <                        GeometryInstance3D < VisualInstance3D < Node3D < Node
CSGBox3D < CSGPrimitive3D < CSGShape3D < GeometryInstance3D < VisualInstance3D < Node3D < Node
                                        └──────────── 여기부터 같다 ────────────┘

공통 조상은 GeometryInstance3D 부터입니다. 그래서 둘 다 그림자·LOD·레이어·Transform 을 같은 방식으로 다룹니다. 다른 것은 위쪽 두세 칸뿐입니다.

MeshInstance3DCSGBox3D
형상을 어디서mesh 에 담아 준 리소스size 로 그 자리에서 계산
콜리전없다 (따로 만든다)use_collision 으로 켠다
형상 합치기안 된다operation 으로 더하고 뺀다
비용싸다런타임 CPU 계산 — 최종물로 쓰지 않는다

🛑 "대부분의 노드가 이 구조인가" — 아니다

Node 는 공통 조상이 맞지만 아래로 갈수록 급격히 좁아집니다. 엔진의 클래스 1,074개를 세어 본 결과입니다.

Node 283개 100% Node3D 120개 42% VisualInstance3D 43개 15% GeometryInstance3D 18개 6%

GeometryInstance3D 까지 내려가는 것은 6% 뿐입니다. 게다가 Node 바로 아래에서 갈래가 갈립니다.

Node ─┬─ CanvasItem ──┬─ Node2D ── Sprite2D …        127개  (2D·UI)
      │               └─ Control ── Button …
      ├─ Node3D ──── VisualInstance3D ── …           120개  (3D)
      ├─ Viewport …                                   11개
      └─ Timer · HTTPRequest · WorldEnvironment …      각 0개

2D·UI 갈래(CanvasItem)가 127개로 3D 갈래(120개)보다 오히려 많습니다.

그래서 "대부분 비슷한 속성을 갖나" — 공통은 위쪽에만

속성어느 클래스가몇 개가 갖나
name · process_mode · ownerNode283개 전부
position · rotation · scaleNode3D120개
layers · sorting_offsetVisualInstance3D43개
cast_shadow · visibility_range_*GeometryInstance3D18개

"모든 노드가 비슷하다"가 아니라 "위로 갈수록 공통이 많아진다" 가 맞습니다. ButtonMeshInstance3D 가 공유하는 것은 Node 수준의 것뿐입니다.

그래서 상속 사슬을 읽는 것이 곧 "이 노드가 무엇을 할 수 있는가"를 읽는 것입니다. 사슬에 Node3D 가 없으면 위치가 없고, VisualInstance3D 가 없으면 화면에 그려지지 않습니다.

📖 더 자세히 — 스킬 문서 원문

이 페이지는 요약본입니다. 확인 절차, 스크립트의 extends 와의 관계, 그 밖의 기본 개념은 저장소의 basics/01-world.md 에 있습니다.