Rotating player character smoothly in top down view

Hello, I´ve just starting building my first simple game in top-down view with static camera. I managed to move my player character on my plane and make it face in the direction it is moving. Quite proud of that :slight_smile: But I can´t figure out how to make the character turn smootly from one direction to another. Right now it turns in 45 degree steps. Do you know a good tutorial on building a top down game in babylonjs or could guide me in the right direction? Thanks a lot!

Here is my current snippet to turn my character:

    run() {
        this.engine.runRenderLoop(() => {
          
          this.moveDirection = new Vector3(
            (this.pressedKeys["d"] ? 1 : 0) + (this.pressedKeys["a"] ? -1 : 0),
            0,
            (this.pressedKeys["w"] ? 1 : 0) + (this.pressedKeys["s"] ? -1 : 0)
          ).normalize();
      
          // Rotate player to face move direction
          if (!this.moveDirection.equals(Vector3.Zero())) {
            this.player?.lookAt(this.player.position.add(this.moveDirection));
          }
          
          // Move player with collisions
          this.player?.moveWithCollisions(this.moveDirection.scale(0.01));     
          this.scene.render();
        });
    }

Hello and welcome!

Here is one of good examples - GitHub - ssatguru/BabylonJS-CharacterController: A CharacterController for BabylonJS

1 Like

Hey labris, thank you very much for your answer. I just looked at the CharacterController Plugin and it looked quite helpful on first look, but it seems to not support the behaviour I´m trying to achieve. I want the player only to be able to move up, down, left, right and diagonally across the gameboard, but I want the character to turn smoothly from one direction to another. Maybe i have to use some kind of animation when switching from one direction to another?

I somehow came up with a working (but ugly) solution using dark magic (GPT) and some good old trial and error… don´t even know how those quarternions exactly work :unamused:

    run() {
      this.scene.debugLayer.show();
      const rotationAxis = new Vector3(0, 1, 0);
      const targetQuaternion = new Quaternion();
    
      this.engine.runRenderLoop(() => {
        // Update move direction based on currently pressed keys
        const moveDirection = new Vector3(
          (this.pressedKeys["ArrowRight"] ? 1 : 0) +
            (this.pressedKeys["ArrowLeft"] ? -1 : 0),
          0,
          (this.pressedKeys["ArrowUp"] ? 1 : 0) +
            (this.pressedKeys["ArrowDown"] ? -1 : 0)
        ).normalize();
    
        // Rotate player smoothly to face move direction
        if (!moveDirection.equals(Vector3.Zero())) {
          targetQuaternion.copyFrom(
            Quaternion.RotationAxis(
              rotationAxis,
              Math.atan2(-moveDirection.z, moveDirection.x) + Math.PI / 2
            )
          );
          Quaternion.SlerpToRef(
            this.player!.rotationQuaternion!,
            targetQuaternion,
            0.05,
            this.player!.rotationQuaternion!
          );
        }
    
        // Move player with collisions
        this.player?.moveWithCollisions(moveDirection.scale(0.01));
    
        this.scene.render();
      });
    }
1 Like