Contrôleurs, manettes de jeu et joysticks

Godot prend en charge des centaines de modèles de contrôleurs grâce à la SDL game controller database, alimentée par la communauté.

Les contrôleurs(manettes, etc) sont pris en charge sur Windows, macOS, Linux, Android, iOS et HTML5.

Notez que les dispositifs plus spécialisés tels que les volants, les pédales de direction et les HOTAS sont moins testés et peuvent ne pas toujours fonctionner comme prévu. Si vous avez accès à l'un de ces dispositifs, n'hésitez pas à reporter les bugs sur GitHub.

Dans ce guide, vous apprendrez :

  • Comment écrire votre logique d'entrée pour supporter à la fois les entrées du clavier et de contrôleur.

  • Comment les contrôleurs peuvent se comporter différemment des entrées clavier/souris.

  • Dépannage des problèmes avec les contrôleurs dans Godot.

Prise en charge de l'entrée universelle

Grâce au système d'actions d'entrée de Godot, Godot permet de prendre en charge à la fois l'entrée par clavier et par contrôleur sans avoir à écrire des chemins de code séparés. Au lieu de coder en dur les touches ou les boutons de la manette dans vos scripts, vous devez créer des actions d'entrée dans les paramètres du projet qui feront ensuite référence aux entrées spécifiées des touches et de la manette.

Les actions de saisie sont expliquées en détail sur la page Utilisation d'InputEvent.

Note

Contrairement à la saisie au clavier, la prise en charge de la saisie à la souris et à la manette pour une action (comme regarder autour de soi dans un jeu à la première personne) nécessitera des chemins de code différents puisqu'ils doivent être traités séparément.

Quelle méthode singleton d’entrée dois-je utiliser ?

There are 3 ways to get input in an analog-aware way:

  • Lorsque vous avez deux axes (comme un joystick ou un mouvement WASD) et que vous voulez que les deux axes se comportent comme une seule entrée, utilisez Input.get_vector() :

# `velocity` will be a Vector2 between `Vector2(-1.0, -1.0)` and `Vector2(1.0, 1.0)`.
# This handles deadzone in a correct way for most use cases.
# The resulting deadzone will have a circular shape as it generally should.
var velocity = Input.get_vector("move_left", "move_right", "move_forward", "move_back")

# The line below is similar to `get_vector()`, except that it handles
# the deadzone in a less optimal way. The resulting deadzone will have
# a square-ish shape when it should ideally have a circular shape.
var velocity = Vector2(Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
            Input.get_action_strength("move_back") - Input.get_action_strength("move_forward")).clamped(1)
// `velocity` will be a Vector2 between `Vector2(-1.0, -1.0)` and `Vector2(1.0, 1.0)`.
// This handles deadzone in a correct way for most use cases.
// The resulting deadzone will have a circular shape as it generally should.
Vector2 velocity = Input.GetVector("move_left", "move_right", "move_forward", "move_back");

// The line below is similar to `get_vector()`, except that it handles
// the deadzone in a less optimal way. The resulting deadzone will have
// a square-ish shape when it should ideally have a circular shape.
Vector2 velocity = new Vector2(Input.GetActionStrength("move_right") - Input.GetActionStrength("move_left"),
            Input.GetActionStrength("move_back") - Input.GetActionStrength("move_forward")).Clamped(1);
  • Lorsque vous avez un axe qui peut aller dans les deux sens (comme la manette des gaz sur un manche de vol), ou lorsque vous voulez gérer des axes séparés individuellement, utilisez Input.get_axis() :

# `walk` will be a floating-point number between `-1.0` and `1.0`.
var walk = Input.get_axis("move_left", "move_right")

# The line above is a shorter form of:
var walk = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
// `walk` will be a floating-point number between `-1.0` and `1.0`.
float walk = Input.GetAxis("move_left", "move_right");

// The line above is a shorter form of:
float walk = Input.GetActionStrength("move_right") - Input.GetActionStrength("move_left");
  • Pour d'autres types d'entrées analogiques, comme le traitement d'un déclencheur ou le traitement d'une direction à la fois, utilisez Input.get_action_strength() :

# `strength` will be a floating-point number between `0.0` and `1.0`.
var strength = Input.get_action_strength("accelerate")
// `strength` will be a floating-point number between `0.0` and `1.0`.
float strength = Input.GetActionStrength("accelerate");

Pour les entrées numériques/booléennes non analogiques (uniquement les valeurs "pressed" our "not pressed"), comme les boutons de la manette, les boutons de la souris ou les touches du clavier, utilisez Input.is_action_pressed() :

# `jumping` will be a boolean with a value of `true` or `false`.
var jumping = Input.is_action_pressed("jump")
// `jumping` will be a boolean with a value of `true` or `false`.
bool jumping = Input.IsActionPressed("jump");

In Godot versions before 3.4, such as 3.3, Input.get_vector() and Input.get_axis() aren't available. Only Input.get_action_strength() and Input.is_action_pressed() are available in Godot 3.3.

Différences entre les entrées clavier/souris et contrôleur

Si vous avez l’habitude de gérer les entrées au clavier et à la souris, vous pouvez être surpris par la façon dont les contrôleurs gèrent des situations spécifiques.

Zone morte

Contrairement aux claviers et aux souris, les contrôleurs offrent des axes avec des entrées analogiques. L'avantage des entrées analogiques est qu'elles offrent une flexibilité supplémentaire pour les actions. Contrairement aux entrées numériques qui ne peuvent fournir que des forces de 0.0 et 1.0, une entrée analogique peut fournir n'importe quelle force entre 0.0 et 1.0. L'inconvénient est que sans un système de zone morte, l'intensité d'un axe analogique ne sera jamais égale à "0,0" en raison de la façon dont le contrôleur est physiquement construit. Au lieu de cela, il s'attardera à une valeur faible telle que "0.062". Ce phénomène est connu sous le nom de drifting et peut être plus visible sur les contrôleurs anciens ou défectueux.

Prenons un jeu de course comme exemple concret. Grâce aux entrées analogiques, nous pouvons diriger lentement la voiture dans une direction ou une autre. Cependant, sans un système de zone morte, la voiture se dirigerait lentement d'elle-même, même si le joueur ne touche pas le joystick. C'est parce que la force de l'axe directionnel ne sera pas égale à 0.0 quand nous l'attendons. Puisque nous ne voulons pas que notre voiture se dirige toute seule dans ce cas, nous définissons une valeur de "zone morte" de 0.2 qui ignorera toute entrée dont la force est inférieure à 0.2. La valeur idéale de la zone morte est suffisamment élevée pour ignorer l'entrée causée par la dérive du joystick, mais suffisamment basse pour ne pas ignorer l'entrée réelle du joueur.

Godot dispose d'un système de zone morte intégré pour résoudre ce problème. La valeur par défaut est de 0.2, mais vous pouvez l'augmenter ou la diminuer par action dans l'onglet Input Map des paramètres du projet. Pour Input.get_vector(), la zone morte peut être spécifiée, sinon il calculera la valeur moyenne de la zone morte de toutes les actions dans le vecteur.

Événements "Echo"

Contrairement à la saisie au clavier, le fait de maintenir enfoncé un bouton de contrôleur, comme la direction du D-pad, ne génère not d'événements de saisie répétés à intervalles fixes (également appelés événements "écho"). En effet, le système d'exploitation n'envoie jamais d'événements "écho" pour les entrées de la manette.

Si vous voulez que les boutons du contrôleur envoient des événements d'écho, vous devrez générer des objets InputEvent par code et les analyser à l'aide de Input.parse_input_event() à intervalles réguliers. Ceci peut être accompli à l'aide d'un nœud Timer.

Dépannage

Voir aussi

Vous pouvez consulter la liste des problèmes connus avec le support des contrôleurs sur GitHub.

Mon contrôleur n'est pas reconnu par Godot.

Tout d'abord, vérifiez que votre contrôleur est reconnu par les autres applications. Vous pouvez utiliser le site Gamepad Tester pour confirmer que votre contrôleur est reconnu.

Les boutons ou les axes de ma manette sont mal affectés.

Si les boutons sont incorrectement mappés, cela peut être dû à un mappage erroné de la base de données SDL du contrôleur de jeu. Vous pouvez contribuer à un mappage mis à jour qui sera inclus dans la prochaine version de Godot en ouvrant une demande de pull sur le dépôt lié.

Il y a plusieurs façons de créer des mappings. Une option consiste à utiliser l'assistant de mappage dans la official Joypads demo. Une fois que vous avez un mappage fonctionnel pour votre contrôleur, vous pouvez le tester en définissant la variable d'environnement SDL_GAMECONTROLLERCONFIG avant de lancer Godot :

export SDL_GAMECONTROLLERCONFIG="your:mapping:here"
./path/to/godot.x86_64
set SDL_GAMECONTROLLERCONFIG=your:mapping:here
path\to\godot.exe
$env:SDL_GAMECONTROLLERCONFIG="your:mapping:here"
path\to\godot.exe

Pour tester les mappings sur des plateformes autres que l'ordinateur de bureau ou pour distribuer votre projet avec des mappings de contrôleurs supplémentaires, vous pouvez les ajouter en appelant Input.add_joy_mapping() le plus tôt possible dans la fonction _ready() d'un script.

Mon contrôleur fonctionne sur une plate-forme donnée, mais pas sur une autre plate-forme.

macOS

Les contrôleurs ne sont actuellement pris en charge que sur les Macs basés sur des processeurs x86. Cela signifie que les contrôleurs ne fonctionneront pas sur les Macs équipés de processeurs ARM tels que l'Apple M1.

Linux

Avant Godot 3.3, les binaires officiels de Godot étaient compilés avec le support udev mais les binaires auto-compilés étaient compilés sans le support udev à moins que udev=yes soit passé sur la ligne de commande SCons. Cela rendait le support du hotplugging du contrôleur indisponible dans les binaires auto-compilés.

HTML5

La prise en charge des contrôleurs HTML5 est souvent moins fiable que celle des plateformes "natives". La qualité de la prise en charge des contrôleurs a tendance à varier énormément d'un navigateur à l'autre. Par conséquent, vous devrez peut-être demander à vos joueurs d'utiliser un autre navigateur s'ils ne parviennent pas à faire fonctionner leur contrôleur.

Notez également que le support des contrôleurs a été considérablement amélioré dans Godot 3.3 et plus.