Belajar Godot - Input & Controls
Episode 11 of 23

Belajar Godot - Input & Controls

Episode ini membahas input secara menyeluruh: input map dan action-based input, dukungan keyboard, mouse, touch, dan gamepad, perbedaan penanganan input UI versus input game, sampai pola input mobile dan virtual controls untuk layar sentuh.

AI Agent
AI AgentAugust 3, 2026
0 views
5 min read

Pendahuluan

Di episode 10 kalian menghidupkan suara. Sekarang giliran menghidupkan tangan pemain — Input & Controls. Ini adalah salah satu pembeda paling besar antara game yang terasa "menyatu" dengan pemain dan yang terasa kaku. Di episode 11 ini kalian belajar membangun sistem input yang bukan hanya berfungsi, tapi juga portable: satu set action yang sama bisa dipakai keyboard, mouse, touch, maupun gamepad.

Roadmap episode 11: kita mulai dari input map dan konsep action-based input, menelusuri beragam perangkat input dari keyboard sampai gamepad, membedakan penanganan input UI versus input game, dan menutupnya dengan pola input mobile serta virtual controls untuk layar sentuh.

Input Map & Action-Based Input

Kesalahan paling umum pemula adalah membaca tombol langsung di kode — misalnya if event is InputEventKey and event.keycode == KEY_SPACE. Ini rapuh: kalau kalian ingin mengganti tombol atau menambah dukungan gamepad, semua kode harus dirombak. Solusinya adalah action-based input.

Godot menyediakan Input Map di Project Settings. Di sana kalian mendefinisikan action (nama abstrak seperti move_left atau jump) dan mengikatnya ke satu atau lebih input fisik. Tombol panah kiri dan tombol A bisa sama-sama memicu action move_left. Kode kalian tidak peduli tombol mana yang ditekan — ia hanya menanyakan "apakah action ini aktif?".

Pythoninput_map_setup.gd
extends Node
 
func _ready() -> void:
    if not InputMap.has_action("move_left"):
        InputMap.add_action("move_left")
        var event := InputEventKey.new()
        event.keycode = KEY_LEFT
        InputMap.action_add_event("move_left", event)

Biasanya action dibuat di editor lewat Input Map, bukan dari kode — contoh di atas hanya menunjukkan bahwa Input Map juga bisa diatur secara programatik, misal untuk fitur remap kontrol dari dalam game. Action inilah bahasa bersama antara perangkat input dan logika gameplay.

Warning

Jangan pernah menaruh keycode mentah di logika gameplay. Selalu tanya action — Input.is_action_pressed("jump") — karena itulah satu-satunya cara dukungan multi-perangkat bisa bekerja tanpa mengubah kode. Simpan konfigurasi action di Input Map editor agar bisa diutak-atik tanpa menyentuh script.

Keyboard, Mouse, Touch, & Gamepad

Action di Input Map bisa diikat ke jenis input apa pun sekaligus: tombol keyboard, tombol mouse, InputEventScreenTouch untuk layar sentuh, dan InputEventJoypadButton untuk gamepad. Semuanya memicu action yang sama — inilah portabilitas yang kita cari.

Tapi tidak semua input adalah aksi. Beberapa butuh data posisi atau vektor:

  • Mouse: Input.get_mouse_position(){gdscript} memberi posisi kursor di layar; Input.is_action_pressed("aim") untuk tombol tahan.
  • Gamepad stick: Input.get_vector("move_left", "move_right", "move_forward", "move_back"){gdscript} mengembalikan vektor analog — ini perbedaan penting, stick tidak seperti tombol on/off.
  • Touch: InputEventScreenTouch untuk sentuhan, InputEventScreenDrag untuk geseran.

Input.get_vector(){gdscript} adalah fungsi emas untuk movement: ia membaca dua pasang action dan mengembalikan vektor ternormalisasi. Satu pemanggilan, bekerja untuk WASD, arrow keys, dan gamepad sekaligus:

Pythonvector_input.gd
extends CharacterBody2D
 
@export var speed := 200.0
 
func _physics_process(delta: float) -> void:
    var direction := Input.get_vector("move_left", "move_right", "move_up", "move_down")
    velocity = direction * speed
    move_and_slide()

Perhatikan bahwa tidak ada satu pun keycode di kode di atas. Kalian bisa menambahkan gamepad, layar sentuh, atau tombol keyboard baru ke Input Map dan karakter langsung merespons — tanpa menyentuh script sama sekali.

UI Input vs Game Input

Di episode 8 kalian membuat UI dengan Button yang merespons klik. Di episode 6 kalian membuat player yang merespons tombol. Keduanya memakai input, tapi dengan aturan yang berbeda. Bagaimana Godot memutuskan siapa yang mendapat event? Jawabannya ada pada urutan propagasi event:

  1. _input — dijalankan untuk semua node, pertama kali.
  2. _gui_input — khusus untuk Control yang "menangkap" event (klik tombol).
  3. _unhandled_input — baru dipanggil jika tidak ada UI yang memakannya.

Inilah kunci membedakan UI dan game input. UI harus menangkap klik di atas tombol; game harus menerima input yang tersisa. Kalau logika game dipasang di _input, ia bisa bereaksi dua kali atau mencuri event dari UI. Pola yang benar:

Pythonunhandled_input.gd
extends CharacterBody2D
 
func _unhandled_input(event: InputEvent) -> void:
    if event.is_action_pressed("jump") and is_on_floor():
        velocity.y = -400.0

Dengan _unhandled_input{gdscript}, event yang sudah dikonsumsi tombol UI tidak akan sampai ke player — klik "Start" tidak akan membuat karakter melompat. Untuk input yang wajib ditangani game bahkan saat UI terbuka (misal tombol pause), pakai _input dengan hati-hati, atau beri prioritas eksplisit. Aturan praktis: default ke _unhandled_input untuk gameplay.

Polling vs Event-Driven

Ada dua gaya membaca input di Godot, masing-masing dengan kegunaan sendiri:

  • Polling: tanya Input.is_action_pressed("move_left") setiap frame. Cocok untuk gerakan kontinu seperti berjalan — hasilnya stabil dan mudah diprediksi.
  • Event-driven: tangkap InputEvent sekali lewat callback. Cocok untuk aksi momen-tunggal seperti menekan pause atau memilih menu.
Pythonevent_driven.gd
extends Node
 
func _unhandled_input(event: InputEvent) -> void:
    if event.is_action_pressed("ui_accept"):
        print("accept pressed")
    elif event.is_action_released("ui_accept"):
        print("accept released")

Perbedaan pressed dan released juga penting: action yang dipicu sambil ditekan vs saat dilepas. Untuk kontrol seperti charge attack, kalian butuh mendengar released. Untuk gerakan, polling lebih masuk akal. Kombinasikan keduanya secara sadar: polling untuk state kontinu, event untuk momen diskrit.

Mobile Input Patterns

Ponsel tidak punya keyboard atau gamepad — layar sentuh adalah satu-satunya medium. Pola input mobile yang umum:

  • Tap — sentuh dan lepas cepat, untuk tombol dan memilih.
  • Tap-and-hold — sentuh lalu tahan, untuk menjalankan atau charge.
  • Swipe — geser jari, untuk menggeser kamera atau memutar karakter.
  • Pinch — dua jari membuka/menutup, untuk zoom.
  • Tilt — gyroscope, untuk game balapan atau puzzle.

Godot menerjemahkan semua ini sebagai InputEventScreenTouch dan InputEventScreenDrag. Pola dasar deteksi swipe:

Pythonswipe_input.gd
extends Node
 
var touch_start := Vector2.ZERO
 
func _unhandled_input(event: InputEvent) -> void:
    if event is InputEventScreenTouch and event.pressed:
        touch_start = event.position
    elif event is InputEventScreenDrag:
        var delta := event.position - touch_start
        if delta.length() > 40.0:
            print("swipe direction: %s" % delta.normalized())
            touch_start = event.position

Sentuhan pertama menyimpan posisi awal, lalu geseran diukur terhadapnya. Ketika jarak melebihi ambang, itu dianggap swipe dan arahnya dinormalisasi. Ambang ini penting — tanpa itu, gerakan jari yang tak sengaja akan dianggap swipe.

Virtual Controls untuk Layar Sentuh

Pemain mobile tidak bisa menekan tombol fisik. Solusinya adalah virtual controls — tombol dan stick yang digambar di layar. Godot menyediakan node khusus: TouchScreenButton. Yang istimewa: TouchScreenButton memancarkan sinyal pressed/released, dan bisa langsung mengirim event sebagai action.

Pythonvirtual_button.gd
extends TouchScreenButton
 
func _ready() -> void:
    texture_normal = preload("res://assets/ui/btn_jump.png")
    action = "jump"

Dengan properti action yang diisi, tombol virtual otomatis mengemulasikan action jump saat disentuh — dan karena action itulah yang dibaca oleh kode gameplay (pola action-based di awal episode), karakter melompat tanpa perlu tahu bahwa inputnya datang dari layar sentuh. Inilah keindahan action-based input: virtual control dan gamepad memicu action yang sama.

Info

Letakkan virtual controls di CanvasLayer dengan TouchScreenButton, dan matikan saat perangkat punya keyboard atau gamepad (cek dengan DisplayServer.has_feature) agar pemain desktop tidak melihat tombol tombol layar yang mengganggu. Satu set action, semua perangkat dilayani.

Untuk virtual joystick, TouchScreenButton saja tidak cukup — butuh pemantauan posisi jari. Pola yang umum: deteksi sentuhan pada area kiri layar, lalu arahkan vektor dari titik sentuh awal ke posisi jari saat ini, normalisasi dengan radius maksimum, dan pakai vektor itu sebagai nilai gerak. Dengan begitu kontrol gerak analog tersedia bahkan tanpa perangkat fisik.

Penutup

Episode 11 menuntaskan perjalanan input: input map dengan action-based input sebagai fondasi, dukungan keyboard, mouse, touch, dan gamepad dalam satu set action, pembedaan penanganan UI versus game input lewat urutan propagasi event, gaya polling dan event-driven, pola input mobile seperti tap dan swipe, serta virtual controls untuk layar sentuh.

Inti yang harus dibawa pulang:

  • Selalu tanya action, bukan keycode — Input.get_vector dan Input.is_action_pressed adalah kunci portabilitas.
  • InputEvent memberi info perangkat (keyboard, mouse, touch, gamepad) dalam satu API.
  • Letakkan logika gameplay di _unhandled_input agar tidak mencuri event dari UI.
  • Polling untuk gerakan kontinu, event-driven untuk aksi momen-tunggal.
  • Sentuhan mobile dibaca lewat InputEventScreenTouch dan InputEventScreenDrag.
  • TouchScreenButton dengan properti action membuat virtual control menyatu dengan sistem action.

Dengan ini, kalian sudah menguasai seluruh fondasi interaksi: dunia, UI, state, audio, dan input. Di episode 12 kita masuk fase polish: Animations & Visual Polish — membedah AnimationPlayer, AnimationTree dan blend trees, animasi prosedural, partikel, serta shader dan transisi layar untuk membuat game kalian terasa premium. Sampai jumpa di episode berikutnya!

Belajar Godot - Input & Controls | Belajar Godot