Godot Version
Version 4.6
Question
Hi! I know that with the release of Godot 4.6 yesterday, we now have the option to change the color of the LED on a DualSense or DualShock 4 controller.
`Input.set_joy_light(device_idx, light_color)`
In my script, I created a system for dynamically unplugging and replugging the controllers. The controllers seem to be in the correct position, but the LED sometimes turns blue on the second or third controller.
Controller 1 = Blue Light
Controller 2 = Red Light Controller
3 = Green Light Controller
4 = Yellow Light
The only way to fix this is to refresh the LED, but it takes several seconds for the blue light to change to the correct color. Is there another reliable way to work around this problem?
extends Node2D
# --- RÉFÉRENCES ---
@onready var joystick_droit = $JoyStickDroit
@onready var joystick_gauche = $JoyStickGauche
@onready var dpad = $DPad
@onready var rumble = $Rumble
@onready var trigger = $Trigger
@onready var themebackground = $Themebackground
@onready var classicbutton = $ClassicThemeButton
@onready var anniversarybutton = $anniversarybutton
@onready var monochromebutton = $MonochromeThemeButton
@onready var lticon = $Trigger/Lticon
@onready var rticon = $Trigger/Rticon
@onready var classic_label = $Trigger/ClassicLabel
@onready var fifth_label = $Trigger/AnniversaryALabel
@onready var dark_label = $Trigger/DarkLabel
# Labels de statut
@onready var label_manette_un = $LabelManetteUn
@onready var label_manette_deux = $LabelManetteDeux
@onready var label_manette_trois = $LabelManetteTrois
@onready var label_manette_quatre = $LabelManetteQuatre
@onready var info_manette_un = $InfoManetteUn
@onready var info_manette_deux = $InfoManetteDeux
@onready var info_manette_trois = $InfoManetteTrois
@onready var info_manette_quatre = $InfoManetteQuatre
# Labels techniques
@onready var label_axis0_right = $JoyStickGauche/LabelAxis0Right
@onready var label_axis0_left = $JoyStickGauche/LabelAxis0Left
@onready var label_axis1_up = $JoyStickGauche/LabelAxis1Up
@onready var label_axis1_down = $JoyStickGauche/LabelAxis1Down
@onready var label_axis2_plus = $JoyStickDroit/LabelAxis2Plus
@onready var label_axis2_left = $JoyStickDroit/LabelAxis2Left
@onready var label_axis3_up = $JoyStickDroit/LabelAxis3Up
@onready var label_axis3_down = $JoyStickDroit/LabelAxis3Down
@onready var label_button14 = $DPad/LabelButton14
@onready var label_button13 = $DPad/LabelButton13
@onready var label_button12 = $DPad/LabelButton12
@onready var label_button11 = $DPad/LabelButton11
@onready var version_label = $Trigger/VersionLabel
@onready var label_axis5 = $Trigger/LabelAxis5
@onready var label_axis4 = $Trigger/LabelAxis4
# --- VARIABLES ---
var labels_buttons = []
var labels_info = []
enum ThemeType { CLASSIQUE, ANNIVERSAIRE_5, SOMBRE }
var current_theme = ThemeType.CLASSIQUE
const SAVE_PATH = "user://theme_settings.cfg"
var bouton_names = { 0:0, 1:1, 2:2, 3:3, 4:4, 5:5, 6:6, 7:7, 8:8, 9:9, 10:10, 15:15, 16:16, 17:17, 18:18, 19:19, 20:20 }
var elements_initial_data = {}
var base_size = Vector2(1280, 720)
var manettes_actuelles = []
# Couleurs
var led_colors_classic = [Color("#3f48cc"), Color("#ed1c24"), Color("#22b14c"), Color("#fff200")]
var led_color_anniversary = Color("#ed1c24")
var led_color_dark = Color.WHITE
func _ready():
labels_buttons = [label_manette_un, label_manette_deux, label_manette_trois, label_manette_quatre]
labels_info = [info_manette_un, info_manette_deux, info_manette_trois, info_manette_quatre]
classicbutton.pressed.connect(_on_classic_theme_pressed)
anniversarybutton.pressed.connect(_on_anniversary_theme_pressed)
monochromebutton.pressed.connect(_on_monochrome_theme_pressed)
_store_initial_data()
get_viewport().size_changed.connect(_on_window_resized)
_on_window_resized()
_detecter_manettes()
Input.joy_connection_changed.connect(_on_joy_connection_changed)
_load_theme_preference()
# --- LOGIQUE LED (LA CORRECTION EST ICI) ---
func _update_controller_leds():
for i in range(manettes_actuelles.size()):
var device_id = manettes_actuelles[i]
var color_to_set = Color.WHITE
match current_theme:
ThemeType.CLASSIQUE:
if i < led_colors_classic.size(): color_to_set = led_colors_classic[i]
ThemeType.ANNIVERSAIRE_5:
color_to_set = led_color_anniversary
ThemeType.SOMBRE:
color_to_set = led_color_dark
# On utilise .call() pour éviter l'erreur de "Static Function Not Found"
if Input.has_method("set_joy_led_color"):
Input.call("set_joy_led_color", device_id, color_to_set)
else:
# Si ton Godot reconnaît set_joy_light, on l'appelle normalement
Input.set_joy_light(device_id, color_to_set)
# --- GESTION THÈMES ---
func change_theme(new_theme: ThemeType):
current_theme = new_theme
_save_theme_preference()
match current_theme:
ThemeType.CLASSIQUE: _apply_classique_theme()
ThemeType.ANNIVERSAIRE_5: _apply_anniversaire_theme()
ThemeType.SOMBRE: _apply_sombre_theme()
_apply_theme_to_children()
_update_controller_leds()
func _on_classic_theme_pressed(): change_theme(ThemeType.CLASSIQUE)
func _on_anniversary_theme_pressed(): change_theme(ThemeType.ANNIVERSAIRE_5)
func _on_monochrome_theme_pressed(): change_theme(ThemeType.SOMBRE)
func _apply_classique_theme():
themebackground.texture = load("res://classictheme.png")
lticon.texture = load("res://lticon.png")
rticon.texture = load("res://rticon.png")
classic_label.visible = true
fifth_label.visible = false
dark_label.visible = false
for i in range(4):
labels_buttons[i].add_theme_color_override("font_color", led_colors_classic[i])
labels_info[i].add_theme_color_override("font_color", led_colors_classic[i])
_apply_axis_dpad_trigger_colors(Color.BLACK)
func _apply_anniversaire_theme():
themebackground.texture = load("res://classictheme.png")
lticon.texture = load("res://lticon.png")
rticon.texture = load("res://rticon.png")
classic_label.visible = false
fifth_label.visible = true
dark_label.visible = false
for i in range(4):
labels_buttons[i].add_theme_color_override("font_color", led_color_anniversary)
labels_info[i].add_theme_color_override("font_color", led_color_anniversary)
_apply_axis_dpad_trigger_colors(Color.BLACK)
func _apply_sombre_theme():
themebackground.texture = load("res://darkmode.png")
lticon.texture = load("res://ltmonochromeicon.png")
rticon.texture = load("res://rtmonochroemicon.png")
classic_label.visible = false
fifth_label.visible = false
dark_label.visible = true
for i in range(4):
labels_buttons[i].add_theme_color_override("font_color", led_color_dark)
labels_info[i].add_theme_color_override("font_color", led_color_dark)
_apply_axis_dpad_trigger_colors(led_color_dark)
func _apply_axis_dpad_trigger_colors(color: Color):
var targets = [label_axis0_right, label_axis0_left, label_axis1_up, label_axis1_down,
label_axis2_plus, label_axis2_left, label_axis3_up, label_axis3_down,
label_button14, label_button13, label_button12, label_button11,
version_label, label_axis5, label_axis4]
for t in targets: if t: t.add_theme_color_override("font_color", color)
# --- SYSTEM ---
func _on_joy_connection_changed(device_id: int, connected: bool):
if connected:
if device_id not in manettes_actuelles: manettes_actuelles.append(device_id)
else:
manettes_actuelles.erase(device_id)
_update_labels()
_propagate_controller_list()
_update_controller_leds()
func _detecter_manettes():
manettes_actuelles = Input.get_connected_joypads()
_update_labels()
_propagate_controller_list()
_update_controller_leds()
func _update_labels():
for i in range(labels_buttons.size()):
labels_buttons[i].text = "?"
labels_info[i].text = Input.get_joy_name(manettes_actuelles[i]) if i < manettes_actuelles.size() else "?"
func _propagate_controller_list():
for child in [joystick_gauche, joystick_droit, dpad, trigger, rumble]:
if child and child.has_method("update_controller_list"):
child.update_controller_list(manettes_actuelles)
func _save_theme_preference():
var config = ConfigFile.new()
config.set_value("Settings", "theme", current_theme)
config.save(SAVE_PATH)
func _load_theme_preference():
var config = ConfigFile.new()
if config.load(SAVE_PATH) == OK:
change_theme(config.get_value("Settings", "theme", ThemeType.CLASSIQUE))
else:
change_theme(ThemeType.CLASSIQUE)
func _apply_theme_to_children():
for node in [dpad, joystick_gauche, joystick_droit, trigger, rumble]:
if node and node.has_method("on_theme_changed"):
node.on_theme_changed(current_theme)
func _store_initial_data():
var targets = [joystick_droit, joystick_gauche, dpad, rumble, trigger, themebackground,
classicbutton, anniversarybutton, monochromebutton] + labels_buttons + labels_info
for elt in targets:
if elt: elements_initial_data[elt] = {"position": elt.position, "scale": elt.scale}
func _on_window_resized():
var win_size = get_viewport().get_visible_rect().size
for elt in elements_initial_data.keys():
var data = elements_initial_data[elt]
elt.position = Vector2(data.position.x * win_size.x / base_size.x, data.position.y * win_size.y / base_size.y)
elt.scale = Vector2(data.scale.x * win_size.x / base_size.x, data.scale.y * win_size.y / base_size.y)
func _input(event):
if event is InputEventJoypadButton:
var idx = manettes_actuelles.find(event.device)
if idx != -1 and idx < labels_buttons.size():
labels_buttons[idx].text = str(bouton_names.get(event.button_index, "?")) if event.pressed else "?"