Controles, gamepads e joysticks

Godot suporta centenas de modelos de controles graças ao banco de dados de controladores de jogos SDL de origem comunitária.

Os controles são compatíveis com Windows, macOS, Linux, Android, iOS e HTML5.

Observe que dispositivos mais especializados, como volantes, pedais de leme e HOTAS são menos testados e nem sempre funcionam como esperado. Substituir o feedback de força para esses dispositivos também não foi implementado ainda. Se você tiver acesso a um desses dispositivos, não hesite em reportar bugs no GitHub.

Neste guia, você aprenderá:

  • Como escrever sua lógica de entrada para suportar as entradas de teclado e de controles.

  • Como os controles podem se comportar de maneira diferente da entrada do teclado/mouse.

  • Solução de problemas com controles no Godot.

Suportando entrada universal

Graças ao sistema de ação de entrada do Godot, o Godot torna possível suportar a entrada do teclado e do controlador sem ter que escrever caminhos de código separados. Em vez de codificar teclas ou botões do controlador em seus scripts, você deve criar ações de entrada nas configurações do projeto, que se referirão às entradas de chave e controle especificadas.

As ações de entrada são explicadas em detalhes na página Usando InputEvent.

Nota

Ao contrário da entrada do teclado, o suporte à entrada do mouse e do controle para uma ação (como olhar ao redor em um jogo em primeira pessoa) exigirá caminhos de código diferentes, pois devem ser tratados separadamente.

Qual método singleton de entrada devo usar?

Existem 3 maneiras de obter entrada com reconhecimento analógico:

  • Quando você tem dois eixos (como joystick ou movimento WASD) e deseja que ambos os eixos se comportem como uma única entrada, use 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)
  • Quando você tem um eixo que pode funcionar em ambos os sentidos (como um acelerador em um stick de vôo), ou quando você deseja manipular eixos separados individualmente, use 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")
  • Para outros tipos de entrada analógica, como manipulação de um gatilho ou manipulação de uma direção por vez, use Input.get_action_strength():

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

Para entrada digital/booleana não analógica (apenas valores "pressionado" ou "não pressionado"), como botões do controle, botões do mouse ou teclas do teclado, use 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");

Nas versões do Godot anteriores a 3.4, como 3.3, Input.get_vector() e Input.get_axis() não estão disponíveis. Somente Input.get_action_strength() e Input.is_action_pressed() estão disponíveis no Godot 3.3.

Diferenças entre teclado/mouse e entrada do controle

Se você está acostumado a lidar com entrada de teclado e mouse, pode se surpreender com a forma como os controles lidam com situações específicas.

Zona morta

Ao contrário dos teclados e mouses, os controles oferecem eixos com entradas analógicas. A vantagem das entradas analógicas é que elas oferecem flexibilidade adicional para ações. Ao contrário das entradas digitais que só podem fornecer intensidades de 0.0 e 1.0, uma entrada analógica pode fornecer qualquer intensidade entre 0.0 e 1.0. A desvantagem é que sem um sistema de zona morta, a força de um eixo analógico nunca será igual a 0.0 devido à forma como o controle é construído fisicamente. Em vez disso, ele permanecerá em um valor baixo, como 0.062. Esse fenômeno é conhecido como drifting e pode ser mais perceptível em controles antigos ou com defeito.

Vamos pegar um jogo de corrida como um exemplo do mundo real. Graças às entradas analógicas, podemos dirigir o carro lentamente em uma direção ou outra. No entanto, sem um sistema de zona morta, o carro giraria lentamente sozinho, mesmo que o jogador não estivesse tocando o joystick. Isso ocorre porque a força do eixo direcional não será igual a 0.0 quando esperamos. Como não queremos que nosso carro gire sozinho neste caso, definimos um valor de "zona morta" de 0.2 que irá ignorar todas as entradas cuja força seja inferior a 0.2. Um valor de zona morta ideal é alto o suficiente para ignorar a entrada causada pelo desvio do joystick, mas é baixo o suficiente para não ignorar a entrada real do jogador.

Godot apresenta um sistema de zona morta integrado para resolver esse problema. O valor padrão é 0.2, mas você pode aumentá-lo ou diminuí-lo por ação na guia Mapa de entrada das configurações do projeto. Para Input.get_vector(), a zona morta pode ser especificada ou, caso contrário, calculará o valor médio da zona morta de todas as ações no vetor.

Eventos de "Eco"

Ao contrário da entrada do teclado, manter pressionado um botão do controle, como uma direção do D-pad, não gerará eventos de entrada repetidos em intervalos fixos (também conhecidos como eventos de "eco"). Isso ocorre porque o sistema operacional nunca envia eventos de "eco" para a entrada do controle em primeiro lugar.

Se você quiser que os botões do controlador enviem eventos de eco, você terá que gerar objetos InputEvent por código e analisá-los usando Input.parse_input_event() em intervalos regulares. Isso pode ser feito com a ajuda de um nó Timer.

Solução de problemas

Ver também

Você pode ver uma lista de problemas conhecidos com suporte de controladores no GitHub.

Meu controle não é reconhecido pelo Godot.

Primeiro, verifique se seu controlador é reconhecido por outros aplicativos. Você pode usar o site Gamepad Tester para confirmar que seu controle é reconhecido.

Meu controle tem botões ou eixos atribuidos incorretamente.

Se os botões estiverem atribuidos incorretamente, isso pode ser devido a um mapeamento incorreto do banco de dados do controlador de jogos SDL <https://github.com/gabomdq/SDL_GameControllerDB>`__. Você pode contribuir com um mapeamento atualizado para ser incluído na próxima versão do Godot abrindo uma solicitação pull no repositório vinculado.

Há muitas maneiras de criar mapeamentos. Uma opção é usar o assistente de mapeamento na demonstração oficial dos Joypads. Depois de ter um mapeamento funcional para o seu controlador, você pode testá-lo definindo a variável de ambiente SDL_GAMECONTROLLERCONFIG antes de executar o Godot:

export SDL_GAMECONTROLLERCONFIG="your:mapping:here"
./path/to/godot.x86_64

Para testar mapeamentos em plataformas não desktop ou para distribuir seu projeto com mapeamentos de controladores adicionais, você pode adicioná-los chamando Input.add_joy_mapping() o mais cedo possível em uma função _ready() no script.

Meu controle funciona em uma determinada plataforma, mas não em outra plataforma.

Linux

Antes do Godot 3.3, os binários oficiais do Godot eram compilados com suporte udev, mas os binários auto-compilados eram compilados sem suporte udev, a menos que udev=yes fosse passado na linha de comando SCons. Isso tornou o suporte de hotplugging do controlador indisponível em binários autocompilados.

HTML5

HTML5 controller support is often less reliable compared to "native" platforms. The quality of controller support tends to vary wildly across browsers. As a result, you may have to instruct your players to use a different browser if they can't get their controller to work.

Além disso, observe que o suporte ao controlador foi significativamente melhorado no Godot 3.3 e versões posteriores.