Description
Changelog
Reviews (0)

BluetoothGD

Cross-platform Bluetooth Classic pairing and connection for Godot 4.x.
(Godot 4.4 and 4.7 tested)

Built as a GDExtension, it lets you discover, pair, and manage Bluetooth devices (including gamepads) directly from GDScript — ideal for in-game controller pairing flows without sending players to OS settings.

Includes a reference demo UI (example/scan_demo.tscn) for quick testing and integration.

Demo available on the GitHub repository.

Supported Platforms

  • Windows 10/11 (x86_64)
  • Linux (x86_64)

Features

  • Native device discovery using platform Bluetooth APIs
  • Pair / unpair, connect / disconnect devices
  • Real-time paired and connected state tracking
  • Signal-based API — easy to bind to UI
  • Non-blocking worker thread backend
  • Reference demo with device list, scan toggle, pair/unpair, and event log
  • Full GDScript API with detailed error reporting

Known Limitations

  • On Windows, disconnect_device() cannot force-disconnect Bluetooth HID gamepads (power off the controller or use OS settings).
  • On Linux, HID gamepads may auto-reconnect when powered on.

Requirements

  • Godot 4.4+
  • CMake 3.17+
  • Platform-specific build tools (Visual Studio on Windows, libdbus-1-dev + BlueZ on Linux)

Quick Start

1. Enable the addon

Enable the plugin in Project → Project Settings → Plugins.

2. Add a BluetoothManager node

Add a BluetoothManager node to your scene as a child or autoload. Keep your UI on a separate Control node — do not attach your UI script to BluetoothManager itself.

YourScene (Control)
├── Bluetooth          # BluetoothManager node
└── ... your UI ...

Alternatively, register it as an autoload named Bluetooth pointing at a scene that contains only a BluetoothManager node.

3. Connect signals and call methods

Wire up the API from your UI script:

extends Control

@onready var _bluetooth: BluetoothManager = $Bluetooth

func _ready() -> void:
    _bluetooth.bluetooth_ready.connect(_on_bluetooth_ready)
    _bluetooth.scan_started.connect(_on_scan_started)
    _bluetooth.scan_stopped.connect(_on_scan_stopped)
    _bluetooth.device_found.connect(_on_device_found)
    _bluetooth.pairing_succeeded.connect(_on_pairing_succeeded)
    _bluetooth.pairing_failed.connect(_on_pairing_failed)
    _bluetooth.pairing_pin_requested.connect(_on_pairing_pin_requested)
    _bluetooth.error_occurred.connect(_on_error_occurred)

func _on_bluetooth_ready() -> void:
    # Backend is initialized — safe to scan and query paired devices.
    var paired: Array = _bluetooth.get_paired_devices()
    print("Bluetooth ready on %s" % _bluetooth.get_platform_name())

func _on_start_scan_pressed() -> void:
    _bluetooth.start_scan({
        "named_only": false,
        "gamepads_only": true,
    })

func _on_stop_scan_pressed() -> void:
    _bluetooth.stop_scan()

func _on_scan_started() -> void:
    print("Scan started")

func _on_scan_stopped() -> void:
    print("Scan stopped")

func _on_device_found(device_info: Dictionary) -> void:
    # device_info keys: address, name, paired, connected, device_class, device_id, rssi
    print("Found: %s (%s)" % [device_info.get("name", "Unknown"), device_info.get("address", "")])

func _on_pair_pressed(address: String) -> void:
    _bluetooth.pair_device(address)

func _on_unpair_pressed(address: String) -> void:
    _bluetooth.unpair_device(address)

func _on_pairing_pin_requested(address: String) -> void:
    _bluetooth.confirm_pairing("0000")  # or reject_pairing() / cancel_pairing()

func _on_pairing_succeeded(address: String) -> void:
    print("Paired: %s" % address)

func _on_pairing_failed(address: String, error: String, error_code: int) -> void:
    print("Pairing failed: %s (%s)" % [error, _bluetooth.get_error_code_name(error_code)])

func _on_error_occurred(operation: String, message: String, error_code: int) -> void:
    print("Error [%s]: %s" % [operation, message])

Important: Wait for the bluetooth_ready signal before calling start_scan(). Scan and pairing results are delivered asynchronously via signals on the main thread.

4. Run the included example

Open and run addons/bluetooth_gd/example/scan_demo.tscn to see scanning, device listing, and pair/unpair in action.

Changelog for version v0.2

No changelog provided for this version.

Reviews

BluetoothGD has no reviews yet.

Login to write a review.