Unity – Personagem anda mais rápido na diagonal e às vezes anda pra trás

Fala pessoal, beleza?

Tô com um problema na movimentação do meu personagem usando o CharacterController com o Input System novo da Unity.

Quando aperto W+A ou W+D, o personagem anda rápido demais (bug da diagonal). E quando aperto só W, ele anda pra trás ou desliza sozinho, tipo o “Michael Jackson moonwalk” :joy:


Já tentei normalizar o vetor, ajustar o transform.forward, e revisar os valores do CharacterController, mas nada resolveu 100%.

Alguém já passou por isso? Segue o script: `using UnityEngine;
using UnityEngine.InputSystem;

public class JogadorController : MonoBehaviour
{
public float velocidade = 5f;
public float gravidade = -9.81f;
public Transform cameraTransform;

private CharacterController controller;
private Vector3 velocidadeVertical;
private Vector2 inputMovimento;

private void Awake()
{
    controller = GetComponent<CharacterController>();
}

// Input System - chama quando houver input de movimento
public void OnMovimento(InputAction.CallbackContext context)
{
    inputMovimento = context.ReadValue<Vector2>();
}

void Update()
{
    // cria vetor de direção a partir do input
    Vector3 direcao = new Vector3(inputMovimento.x, 0f, inputMovimento.y).normalized;

    if (direcao.magnitude >= 0.1f)
    {
        // calcula o ângulo em relação à câmera
        float anguloAlvo = Mathf.Atan2(direcao.x, direcao.z) * Mathf.Rad2Deg + cameraTransform.eulerAngles.y;

        // gira suavemente na direção da câmera
        Vector3 direcaoMovimento = Quaternion.Euler(0f, anguloAlvo, 0f) * Vector3.forward;
        direcaoMovimento.Normalize();

        // move o personagem
        controller.Move(direcaoMovimento * velocidade * Time.deltaTime);
    }

    // gravidade
    if (controller.isGrounded && velocidadeVertical.y < 0)
    {
        velocidadeVertical.y = -2f; // impede flutuação
    }

    velocidadeVertical.y += gravidade * Time.deltaTime;

    // aplica a gravidade separadamente (eixo Y)
    controller.Move(Vector3.up * velocidadeVertical.y * Time.deltaTime);
}

}
`

Em vez de usar .normalized no código, você pode configurar isso direto no seu Input Actions:

  1. Abre o editor de Input Actions.
  2. Seleciona a ação de movimento.
  3. No campo Processors, adiciona Normalize Vector2.

image

Isso já garante que o valor lido em context.ReadValue<Vector2>() venha sempre normalizado (com magnitude máxima de 1). Assim você evita o boost na diagonal e mantém a consistência no movimento.

Sobre o moonwalk

Esse bug normalmente rola quando:

  • O input está invertido (ex: eixo Y invertido em relação ao forward).
  • Ou quando o cálculo da rotação baseado na câmera não está combinando com a direção real.

Novo código

Acredito que o código abaixo já deve resolver os problemas que você está tendo:

using UnityEngine;
using UnityEngine.InputSystem;

public class JogadorController : MonoBehaviour
{
    public float velocidade = 5f;
    public float gravidade = -9.81f;

    private Vector2 inputMovimento;
    private Vector3 velocidadeVertical;

    public CharacterController controller;
    public Transform cameraTransform;

    public void OnMovimento(InputAction.CallbackContext context)
    {
        inputMovimento = context.ReadValue<Vector2>(); // já normalizado se houver Processor
    }

    void Update()
    {
        Vector3 direcao = Vector3.zero;

        if (inputMovimento.magnitude >= 0.1f)
        {
            float anguloAlvo = Mathf.Atan2(inputMovimento.x, inputMovimento.y) * Mathf.Rad2Deg + cameraTransform.eulerAngles.y;
            Vector3 rotacao = Quaternion.Euler(0f, anguloAlvo, 0f) * Vector3.forward;
            direcao = rotacao * velocidade;
        }

        // Gravidade
        if (controller.isGrounded && velocidadeVertical.y < 0)
            velocidadeVertical.y = -2f;

        velocidadeVertical.y += gravidade * Time.deltaTime;

        // Movimento final
        Vector3 movimentoFinal = direcao * Time.deltaTime + Vector3.up * velocidadeVertical.y * Time.deltaTime;
        controller.Move(movimentoFinal);
    }
}



Permanece as mesmas coisas e o código é o mesmo

Nos meus testes a solução acima funcionou bem. Poderia enviar um video mostrando o comportamente que está tendo aí?