My players is going to diagonal but i press only to up

Hi,

My players is going to diagonal but i press only to up.

Video:

Im only press “w” and it is going to diagonal.

Code:

import * as BABYLON from 'babylonjs';
import * as GUI from 'babylonjs-gui';
import 'babylonjs-loaders';
import './style.css';


const canvas = document.getElementById('renderCanvas');
const engine = new BABYLON.Engine(canvas, true);

let player = null;
let inputMap = {};
let vertical = 0.0;
let verticalAxis = 0;
let horizontal = 0.0;
let horizontalAxis = 0;
let moveDirection = new BABYLON.Vector3(0, 0, 0);

const updateFromKeyboard = function () {
  if (inputMap["w"]) {
    vertical = BABYLON.Scalar.Lerp(vertical, 1, 0.2);
    verticalAxis = 1;
  } else if (inputMap["s"]) {
    vertical = BABYLON.Scalar.Lerp(vertical, -1, 0.2);
    verticalAxis = -1;
  } else {
    vertical = 0;
    verticalAxis = 0;
  }

  if (inputMap["a"]) {
    horizontal = BABYLON.Scalar.Lerp(horizontal, -1, 0.2);
    horizontalAxis = -1;

  } else if (inputMap["d"]) {
    horizontal = BABYLON.Scalar.Lerp(horizontal, 1, 0.2);
    horizontalAxis = 1;
  } else {
    horizontal = 0;
    horizontalAxis = 0;
  }

  moveDirection = new BABYLON.Vector3(horizontal, 0, vertical);
  moveDirection.normalize();
}

const createScene = async function () {
  const scene = new BABYLON.Scene(engine);
  scene.enablePhysics(new BABYLON.Vector3(0, -9.81, 0));
  scene.collisionsEnabled = true;

  const camera = new BABYLON.ArcRotateCamera(
    'camera',
    -Math.PI / 2,
    Math.PI / 2.5,
    3,
    new BABYLON.Vector3(0, 0, 0),
    scene
  );

  camera.fov = 1;
  camera.attachControl(canvas, true);

  const light = new BABYLON.HemisphericLight('light', new BABYLON.Vector3(1, 1, 0));
  light.intensity = 0.5;
  scene.addLight(light);

  const ground = BABYLON.MeshBuilder.CreateGround('ground', { width: 100, height: 100 });
  ground.physicsBody = new BABYLON.PhysicsBody(BABYLON.PhysicsBody.STATIC_BODY, scene);
  ground.checkCollisions = true;
  scene.addMesh(ground);

  // Import character model and setup animations
  BABYLON.ImportMeshAsync("/models/character.glb", scene).then((result) => {
    // Log available animations
    console.log("Available animations in result:");
    result.animationGroups.forEach((animGroup, index) => {
      console.log(`Index: ${index}, Name: ${animGroup.name}`);
    });

    player = result.meshes[0];

    if (result.animationGroups && result.animationGroups.length > 0) {
      // Stop all animations first
      scene.animationGroups.forEach(animGroup => {
        animGroup.stop();
      });

      // Play the desired animation - index 10 (Run) as example
      const animationIndex = 10; // Index 10 = CharacterArmature|Run
      console.log(`Playing animation ${result.animationGroups[animationIndex].name} (index ${animationIndex})`);
      result.animationGroups[animationIndex].play(true);

      // Create GUI interface
      const advancedTexture = GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");

      const panel = new GUI.StackPanel();
      panel.width = "220px";
      panel.horizontalAlignment = GUI.Control.HORIZONTAL_ALIGNMENT_RIGHT;
      panel.verticalAlignment = GUI.Control.VERTICAL_ALIGNMENT_CENTER;
      advancedTexture.addControl(panel);

      const animationNames = result.animationGroups.map(ag => ag.name.replace("CharacterArmature|", ""));

      // Create buttons for each animation
      animationNames.forEach((name, index) => {
        const button = GUI.Button.CreateSimpleButton("btn_" + index, name);
        button.width = "200px";
        button.height = "30px";
        button.color = "white";
        button.background = "green";
        button.onPointerClickObservable.add(() => {
          // Stop all animations
          scene.animationGroups.forEach(animGroup => {
            animGroup.stop();
          });

          // Reset all skeletons
          result.skeletons.forEach(skeleton => {
            skeleton.returnToRest();
          });

          // Play the selected animation
          result.animationGroups[index].reset();
          result.animationGroups[index].play(true);
        });

        panel.addControl(button);
      });
    } else {
      console.error(`Error: Not enough animations. Total animations: ${result.animationGroups ? result.animationGroups.length : 0}`);
    }
  }).catch(error => {
    console.error("Error loading model:", error);
  });

  // Add keyboard input handling
  scene.actionManager = new BABYLON.ActionManager(scene);

  scene.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnKeyDownTrigger, (evt) => {
    inputMap[evt.sourceEvent.key] = evt.sourceEvent.type == "keydown";
  }));

  scene.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnKeyUpTrigger, (evt) => {
    inputMap[evt.sourceEvent.key] = false;
  }));

  scene.onBeforeRenderObservable.add(() => {
    updateFromKeyboard();
  });

  scene.registerBeforeRender(function () {
    if (player) {
      player.moveWithCollisions(moveDirection);
      console.log(moveDirection);
    }
  });

  return scene;
};

const scene = await createScene();

engine.runRenderLoop(function () {
  scene.render();
});

window.addEventListener('resize', function () {
  engine.resize();
});

any chance to repro in the PG?

shooting in the dark: moveDirection must be transformed from camera view to world view if you want your character to be aligned with camera POV

something like (not tested):

const invViewMartrix = BABYLON.Matrix.Invert(scene.getViewMatrix());
const theGoodMoveDirectionToUse = BABYLON.Vector3.TransformNormal(moveDirection , invViewMartrix );

The problem is these lines, i dont know why:

ground.physicsBody = new BABYLON.PhysicsBody(BABYLON.PhysicsBody.STATIC_BODY, scene);
ground.checkCollisions = true;

I removed it and worked.

Thanks.