Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Controles, gamepads e joysticks

O Godot suporta centenas de modelos de controles nativamente. Os controles são suportados no Windows, macOS, Linux, Android, iOS e Web.

Nota

Desde o Godot 4.5, o motor depende do SDL 3 para suporte a controles no Windows, macOS e Linux. Isso significa que a lista de controles suportados e seu comportamento devem corresponder de perto ao que está disponível em outros jogos e motores que usam o SDL 3. Note que o SDL é usado apenas para entrada, não para gerenciamento de janelas ou som.

Antes do Godot 4.5, o motor usava seu próprio código de suporte a controles. Isso pode fazer com que certos controles se comportem incorretamente. Esse código personalizado ainda é usado para suportar controles no Android e na Web, portanto, pode fazer com que problemas apareçam apenas nessas plataformas.

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")
).limit_length(1.0)
  • 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")

Nota

Se você precisar saber se uma entrada foi acabou de ser pressionada no quadro anterior, use Input.is_action_just_pressed() em vez de Input.is_action_pressed(). Ao contrário de Input.is_action_pressed(), que retorna true enquanto a entrada for mantida pressionada, Input.is_action_just_pressed() só retornará true por um quadro após o botão ter sido pressionado.

Vibração

A vibração (também chamada de feedback tátil) pode ser usada para aprimorar a sensação de um jogo. Por exemplo, em um jogo de corrida, você pode transmitir a superfície pela qual o carro está dirigindo atualmente por meio da vibração, ou criar uma vibração repentina em uma colisão.

Use o método start_joy_vibration do singleton Input para iniciar a vibração em um gamepad. Use stop_joy_vibration para parar a vibração mais cedo (útil se nenhuma duração tiver sido especificada ao iniciar).

Em dispositivos móveis, você também pode usar vibrate_handheld para vibrar o próprio dispositivo (independentemente do gamepad). No Android, isso requer que a permissão VIBRATE esteja ativada no preset de exportação do Android antes de exportar o projeto.

Nota

A vibração pode ser desconfortável para certos jogadores. Certifique-se de fornecer um controle deslizante (slider) no jogo para desativar a vibração ou reduzir sua intensidade.

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.

O Godot possui um sistema de deadzone integrado para lidar com esse problema. O valor padrão é 0.5, mas você pode ajustá-lo para cada ação individualmente na aba Mapa de Entrada das Configurações do Projeto. Para Input.get_vector(), a deadzone pode ser especificada como um 5º parâmetro opcional. Se não for especificada, ela calculará o valor médio da deadzone 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.

Foco da janela

Ao contrário da entrada de teclado, as entradas de controle podem, por padrão, ser vistas por todas as janelas do sistema operacional, incluindo janelas sem foco.

Embora isso seja útil para funcionalidades de tela dividida de terceiros, também pode ter efeitos adversos. Os jogadores podem acidentalmente enviar comandos de controle para o projeto em execução enquanto interagem com outra janela.

Se você deseja ignorar eventos de entrada do controle quando o projeto não estiver focado, defina ProjectSettings.input_devices/joypads/ignore_joypad_on_unfocused_application como true. Alternativamente, você também pode definir Input.ignore_joypad_on_unfocused_application como true.

Prevenção de economia de energia

Ao contrário da entrada de teclado e mouse, as entradas de controle não inibem as medidas de suspensão e economia de energia (como desligar a tela após um certo tempo decorrido).

Para combater isso, o Godot ativa a prevenção de economia de energia por padrão quando um projeto está em execução. Se você notar que o sistema está desligando a tela ao jogar com um gamepad, verifique o valor de Display > Window > Energy Saving > Keep Screen On nas Configurações do Projeto.

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 o seu controle é reconhecido por outros aplicativos. Você pode usar o site Gamepad Tester para confirmar se o seu controle é reconhecido.

No Windows, o Godot suporta apenas até 4 controles por vez. Isso ocorre porque o Godot usa a API XInput, que é limitada a suportar 4 controles simultaneamente. Controles adicionais acima desse limite são ignorados pelo Godot.

Meu controle tem botões ou eixos atribuidos incorretamente.

Primeiro, se o seu controle fornecer algum tipo de utilitário de atualização de firmware, certifique-se de executá-lo para obter as correções mais recentes do fabricante. Por exemplo, os controles do Xbox One e Xbox Series podem ter seu firmware atualizado usando o aplicativo Acessórios Xbox. (Este aplicativo só roda no Windows, então você deve usar uma máquina Windows ou uma máquina virtual Windows com suporte a USB para atualizar o firmware do controle.) Após atualizar o firmware do controle, desemparelhe o controle e emparelhe-o novamente com o seu PC se estiver usando o controle no modo sem fio.

Se os botões estiverem mapeados incorretamente, isso pode ser devido a um mapeamento errôneo do banco de dados de controles SDL usado pelo Godot ou do banco de dados de controles do Godot. Neste caso, você precisará criar um mapeamento personalizado para o seu controle.

Existem muitas maneiras de criar mapeamentos. Uma opção é iniciar o Steam no modo Big Picture, configurar o controle e depois procurar por config/config.vdf no diretório de instalação do Steam pela entrada SDL_GamepadBind. Outra opção é usar o aplicativo testcontroller da SDL (o link fornece apenas um executável para Windows). Assim que tiver um mapeamento funcional para o seu controle, 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

Assim que estiver satisfeito com o mapeamento personalizado, você pode contribuir com ele para a próxima versão do Godot abrindo um pull request na base de dados de controles do Godot ou criando uma issue no repositório do Godot.

Como o Godot usa o SDL 3 para entrada de controle, considere também contribuir com o mapeamento para a biblioteca SDL abrindo um pull request no banco de dados oficial de gamepads do SDL, ou criando uma issue no repositório do SDL.

Nota

Note que existem controles "genéricos" no mercado (geralmente a propriedade Input.get_joy_info(device)["raw_name"] deles contém a string "USB Gamepad"), e controles genéricos diferentes podem usar o mesmo chipset, mas ter uma disposição de botões diferente, de modo que criar um mapeamento para um desses controles muito provavelmente entrará em conflito com outros, porque o motor não tem como diferenciar entre controles com o mesmo chipset.

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

Linux

Se você estiver usando uma versão binária do motor compilada por conta própria, certifique-se de que ela foi compilada com suporte ao udev. Isso é ativado por padrão, mas é possível desativar o suporte ao udev especificando udev=no na linha de comando do SCons. Se você estiver usando um binário do motor fornecido por uma distribuição Linux, verifique se ele foi compilado com suporte ao udev.

Os controles ainda podem funcionar sem o suporte ao udev, mas é menos confiável, pois a varredura regular (polling) deve ser usada para verificar se os controles foram conectados ou desconectados durante a jogabilidade (hotplugging).

Android

Como descrito no topo da página, o suporte a controles em plataformas móveis depende de uma implementação personalizada em vez de usar o SDL para entrada. Isso significa que o suporte a controles pode ser menos confiável do que em plataformas desktop.

O suporte para entrada de controle baseada em SDL em plataformas móveis está planejado para uma versão futura.

Web

O suporte a controles na Web costuma ser menos confiável em comparação com plataformas "nativas". A qualidade do suporte a controles tende a variar drasticamente entre os navegadores. Como resultado, você pode ter que instruir seus jogadores a usar um navegador diferente se eles não conseguirem fazer o controle funcionar.

Assim como para plataformas móveis, o suporte para entrada de controle baseada em SDL na plataforma web está planejado para uma versão futura.