Level 1 • Day 1 Hands-on

Object Composition & Scene Tree Architecture

1. Setup 2. Concept 3. Drill 4. Mini-Check
Day 1 of 7-Day Foundation

ลุย Day 1 กันเลยครับ!
Object Composition & Scene Tree

วันนี้เราจะใช้เวลา 20–30 นาที ปูพื้นฐานสถาปัตยกรรมที่สำคัญที่สุดของ Godot Engine 4 เน้นการเปลี่ยนผ่านจากแนวคิดคลาสแม่ผูกแน่น (Inheritance) สู่การใช้ Component Nodes อิสระ พร้อมเปิด Strict Type Safety ใน Editor ตั้งแต่นาทีแรก!

2m

1. Editor Setup

เปิด Strict Typing

5m

2. Micro-Concept

Composition vs Tree

15m

3. Rotator Drill

โค้ด Component แรก

D1

กฎสำคัญของวันนี้

"เขียนสคริปต์ให้เหมือน LEGO ตัวต่อ ไม่ต้องรู้ว่าใครเป็นตัวต่อข้างเคียง แต่ทำหน้าที่หมุนวัตถุให้ดีที่สุด"

หลีกเลี่ยง Deep Inheritance
Node ต้องอยู่ใน SceneTree เสมอ
คูณ delta เพื่อ Frame-rate Independence
Step 1 • 2 Minutes Prep

1. การตั้งค่า Editor สำหรับ Strict Type Safety

ป้องกันบั๊กตั้งแต่ตอนพิมพ์

ก่อนเริ่มเขียนโค้ด แนะนำให้เปิดใช้งานการแจ้งเตือน (Warnings) ของ GDScript ใน Godot 4 เพื่อให้ Editor ช่วยตรวจสอบชนิดข้อมูลทันที และช่วยให้ระบบ Autocomplete แนะนำฟังก์ชันได้แม่นยำ 100%:

1

เปิด Project Settings

ไปที่เมนูด้านบนของ Godot 4:
Project > Project Settings

2

ค้นหาหมวด GDScript

เลือกแท็บ General แล้วพิมพ์คำว่า GDScript ในช่องค้นหาด้านบน

3

ปรับค่า Warnings

ในส่วน Warnings ให้ตั้งค่าดังนี้:

  • • Untyped Declaration: Warn / Error
  • • Unsafe Property Access: Warn
Step 2 • 5 Minutes Micro-Concept

2. Micro-Concept Breakdown: Composition vs. Inheritance

สถาปัตยกรรมโหนด Godot 4

แนวคิดแบบเดิม (Deep Inheritance)

สร้าง Class แม่ขนาดใหญ่ เช่น Character > Player > WarriorPlayer ส่งผลให้โค้ดผูกติดกันแน่น (Tight Coupling) หากต้องการสร้างหุ่นโดรนบินที่หมุนตัวได้เหมือนดาวเคราะห์ เราต้องเขียนซ้ำหรือดึงโครงสร้างคลาสแม่ขนาดใหญ่มาโดยไม่จำเป็น

ข้อเสีย: แก้ไขระบบย่อยส่งผลกระทบต่อทั้งเกมทันที

แนวคิดของ Godot (Pure Composition)

มองทุกอย่างเป็น Node เดี่ยวๆ ที่มีหน้าที่เฉพาะทาง (Single-responsibility) เช่น หมุนตัว (Rotator), เลือด (Health), ตัวยิง (Spawner) แล้วนำมาประกอบเป็นกิ่งก้าน (Node Tree) ใต้โหนดอะไรก็ได้ที่ต้องการฟังก์ชันนั้น

ข้อดี: นำกลับมาใช้ซ้ำ (Reusable) ได้ทันที ไม่ว่าจะแปะกับยานอวกาศ ดาว หรือปุ่ม UI

SceneTree คือศูนย์กลางการมีชีวิตของ Node

Node ทุกตัวที่จะทำงานได้ (เช่น ได้รับรอบการประมวลผล _process(delta) หรือ _physics_process(delta)) จะต้องถูกเพิ่มเข้าไปอยู่ใน SceneTree เท่านั้น หาก Node ถูกสร้างขึ้นด้วย Node.new() แต่อยู่เฉยๆ ในหน่วยความจำโดยไม่ได้สั่ง add_child() มันจะอยู่นิ่งๆ ใน RAM และไม่ถูกรันเฟรมใดๆ ทั้งสิ้น

Step 3 • 15–20 Mins Drill

3. Hands-on Drill: สร้าง RotatorComponent

เราจะสร้าง Component สำหรับหมุน Node แม่ (Parent Node) โดยที่ตัว Component ไม่จำเป็นต้องรู้ว่า Node แม่คืออะไร ขอแค่เป็นวัตถุ 2D (Node2D) ก็พอครับ

โครงสร้าง Node Tree ใน Godot Editor
Sprite2D (Planet) ── [ใส่ Texture/รูปภาพอะไรก็ได้ เช่น โลโก้ Godot]
└── RotatorComponent (Node) [แนบสคริปต์ RotatorComponent.gd]
ไฟล์: RotatorComponent.gd 100% Strict Type Safety
class_name RotatorComponent
extends Node
## RotatorComponent
## ใช้สำหรับหมุน Parent Node (Node2D) ด้วยความเร็วที่กำหนด

# @export ช่วยให้ปรับค่าความเร็วในการหมุนได้ผ่าน Inspector
@export var rotation_speed: float = 2.0

func _process(delta: float) -> void:
    # ดึง Node แม่ที่เป็น Node2D มาใช้งาน
    var parent := get_parent() as Node2D

    # ตรวจสอบเพื่อความปลอดภัยว่า Parent มีอยู่จริงและเป็น Node2D
    if parent:
        # หมุน Node แม่ตามเวลาที่ผ่านไป (delta) เพื่อให้ความเร็วคงที่ทุก Frame Rate
        parent.rotation += rotation_speed * delta

ขั้นตอนการลงมือทำจริงใน Godot Engine 4:

  1. สร้าง Scene ใหม่: เลือก Root Node เป็น Sprite2D (ใส่รูปโลโก้ Godot หรือรูปอะไรก็ได้ลงในช่อง Texture ของ Inspector)
  2. เพิ่ม Component: คลิกขวาที่ Sprite2D เลือก Add Child Node > เลือกประเภท Node แล้วเปลี่ยนชื่อโหนดเป็น RotatorComponent
  3. สร้างและแนบสคริปต์: คลิกขวาที่ RotatorComponent เลือก Attach Script ตั้งชื่อไฟล์ว่า RotatorComponent.gd แล้วพิมพ์หรือวางโค้ดด้านบนลงไป
  4. ทดสอบการรัน: ลองกด Play Scene (F6) แล้วสังเกตว่าภาพ Sprite2D จะเริ่มหมุนตัวอย่างนุ่มนวล
  5. ทดลองปรับค่าแบบ No-Code: ลองคลิกที่ RotatorComponent แล้วเปลี่ยนค่า Rotation Speed ในหน้าต่าง Inspector ด้านขวาดูว่าความเร็วเปลี่ยนตามไหมโดยไม่ต้องแก้ไขโค้ดแม้แต่บรรทัดเดียว!
Reflect & Validate

4. 🎯 Mini-Check สำหรับ Day 1

ก่อนจะจบการฝึกของวันนี้ ลองตอบคำถามนี้สั้นๆ เพื่อทดสอบความเข้าใจครับ:

คำถาม: ในบรรทัด parent.rotation += rotation_speed * delta ทำไมเราถึงต้องคูณด้วย delta เสมอ?
กดดูเฉลยและคำอธิบายเชิงสถาปัตยกรรม

คำตอบ: เพื่อให้ความเร็วในการหมุน "คงที่เท่าเดิมทุกเครื่อง โดยไม่ขึ้นกับ Frame Rate" (Frame-rate Independence)

ค่า delta คือระยะเวลาจริงที่ผ่านไปของแต่ละเฟรม (เป็นวินาที เช่น ที่ 60 FPS delta จะประมาณ 0.0166 วินาที) หากไม่คูณ delta หากเกมรันบนหน้าจอ 144Hz วัตถุจะหมุนเร็วกว่าบนหน้าจอ 60Hz ถึงกว่า 2 เท่าตัว!

เตรียมตัวสำหรับวันถัดไป

พร้อมต่อ Day 2 แล้วหรือยังครับ?

วันพรุ่งนี้เราจะเจาะลึก Day 2: GDScript 2.0 Type Safety & Editor Annotations (@export, @onready) เพื่อสร้างระบบสถิติตัวละครที่ปลอดภัย 100%!

คัดลอก GDScript ไปยังคลิปบอร์ดแล้ว!