How to have fixed FollowCamera?

I have a working FollowCamera which has target set to player.

but when I move the camera automatically rotates to the front, and since player is set to move by force on Z axis this makes to move forward whereever the Camera is looking at and not exact where player intends to go.

here is complete source code: GitHub - steelx/bjs-game01: Babylon js game using vite and Typescript as well my first BabylonJs game.

// src/Game.ts


private initGame(): void {
    this.player = new Player(this)
    this.level = Level.FromInts(levels[this.currentLevel], this)
    this.scene.beginAnimation(this, 0, 100, true, 1.0)

    // Set the camera target to the player instance
    const camera = this.scene.getCameraByName("FollowCam") as FollowCamera;
    if (camera && this.player) {
      camera.lockedTarget = this.player;

    console.log("Level initialized!")

private static createScene(engine: Engine): Scene {
    const scene = new Scene(engine)

    const camera = new FollowCamera("FollowCam", new Vector3(0, 10, -10), scene);

    // The goal distance of camera from target
    camera.radius = 3
    // The goal height of camera above local origin (centre) of target
    camera.heightOffset = 4
    // The goal rotation of camera around local origin (centre) of target in x y plane
    camera.rotationOffset = 0
    // Acceleration of camera in moving from current to goal position
    camera.cameraAcceleration = 0.5
    // The speed at which acceleration is halted
    camera.maxCameraSpeed = 1
    // This attaches the camera to the canvas
    // camera.attachControl()

    // Materials
    // TODO: find a correct way to load materials
    const groundMaterial = new StandardMaterial("groundMaterial", scene)
    groundMaterial.diffuseTexture = new Texture(dirtRooted, scene)
    groundMaterial.emissiveColor = Color3.Blue()

    const playerMaterial = new StandardMaterial("playerMaterial", scene)
    playerMaterial.diffuseColor = Color3.White()
    playerMaterial.emissiveColor = Color3.White()
    playerMaterial.emissiveFresnelParameters = getEmmisiveFresnel()
    playerMaterial.opacityFresnelParameters = getOpacityFresnel()
    playerMaterial.alpha = 0.2

    const skyboxMaterial = new StandardMaterial("skyBox", scene)
    skyboxMaterial.backFaceCulling = false
    skyboxMaterial.reflectionTexture = new CubeTexture(
      ["px.bmp", "py.bmp", "pz.bmp", "nx.bmp", "ny.bmp", "nz.bmp"]
    skyboxMaterial.reflectionTexture.coordinatesMode = Texture.SKYBOX_MODE
    skyboxMaterial.diffuseColor = new Color3(0, 0, 0)
    skyboxMaterial.specularColor = new Color3(0, 0, 0)

    const skybox = MeshBuilder.CreateBox("skyBox", { size: 100 }, scene)
    skybox.material = skyboxMaterial

    scene.ambientColor = new Color3(1, 1, 1)
    const light = new HemisphericLight("light", new Vector3(0.5, 1, 0), scene)
    light.intensity = 0.7

    // Initialize the physics engine
    const gravityVector = new Vector3(0, -9.81, 0);
    const physicsPlugin = new CannonJSPlugin();
    scene.enablePhysics(gravityVector, physicsPlugin);

    console.log("Scene initialized!")
    return scene

  reset() {
    throw new Error("Method not implemented.")

cc @PolygonalSun

You should probably make a simplified version of your setup in a playground so we can help you better.

I did that back in like 2014. Will not get to digging that up today. The camera never moved, but sort of acted like the inverse of a billboard, where the mesh was always in the center of scene.

hi all I didnt understand what @JCPalmer suggested, but I will make a small playground version of what issue im facing. So far I have moved away from FollowCamera to ArcRotate camera now

issue video

hi all I managed to fix camera issue by moving to Grid based movement, since this is just a small game I dont want to get stuck on camera.
You can view here my PR exact changes I did → feat: Grid based movement by steelx · Pull Request #2 · steelx/bjs-game01 · GitHub

overall I changed camera to this code

const camera = new ArcRotateCamera("FollowCam", 0, Math.PI / 3, 5, Vector3.Zero(), scene)
camera.lowerRadiusLimit = 8
camera.upperRadiusLimit = 9
camera.setPosition(new Vector3(0, 5, 5))
1 Like