# Third Person Physics Character Controller

**URL:** <https://forum.babylonjs.com/t/third-person-physics-character-controller/57357>\
**Category:** Demos and projects\
**Tags:** physics, character-controller\
**Created:** [March 23, 2025, 2:05pm UTC](https://forum.babylonjs.com/t/third-person-physics-character-controller/57357 "2025-03-23T14:05:32Z")\
**Posts on this page:** 11\
**Page:** 2

<div class="post-metadata">

**Author:** ![Cedric](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/cedric/32/2742_2.png) [@Cedric](https://forum.babylonjs.com/u/Cedric)\
**Post date:** [March 31, 2025, 7:17am UTC](https://forum.babylonjs.com/t/third-person-physics-character-controller/57357/24 "2025-03-31T07:17:52Z")

</div>

Excellent!

---

<div class="post-metadata">

**Author:** ![gsw945](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/gsw945/32/38399_2.png) [@gsw945](https://forum.babylonjs.com/u/gsw945)\
**Post date:** [March 31, 2025, 8:13am UTC](https://forum.babylonjs.com/t/third-person-physics-character-controller/57357/25 "2025-03-31T08:13:25Z")

</div>

Good idea! 😀

---

<div class="post-metadata">

**Author:** ![gsw945](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/gsw945/32/38399_2.png) [@gsw945](https://forum.babylonjs.com/u/gsw945)\
**Post date:** [April 2, 2025, 1:29am UTC](https://forum.babylonjs.com/t/third-person-physics-character-controller/57357/26 "2025-04-02T01:29:01Z")

</div>

The above link got 404, is this the correct link:

> **[Open Source / Babylon js Ammo js Third Person Template · GitLab](https://gitlab.com/open-source9600911/babylon-js-ammo-js-third-person-template/)**
>
> GitLab.com

---

<div class="post-metadata">

**Author:** ![labris](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/labris/32/12576_2.png) [@labris](https://forum.babylonjs.com/u/labris)\
**Post date:** [April 3, 2025, 4:13am UTC](https://forum.babylonjs.com/t/third-person-physics-character-controller/57357/27 "2025-04-03T04:13:37Z")

</div>

I added the player model, and it is already able to jump! 🙂 - [https://playground.babylonjs.com/#9GE7HV#16](https://playground.babylonjs.com/#9GE7HV#16)

---

<div class="post-metadata">

**Author:** ![Cedric](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/cedric/32/2742_2.png) [@Cedric](https://forum.babylonjs.com/u/Cedric)\
**Post date:** [April 3, 2025, 7:13am UTC](https://forum.babylonjs.com/t/third-person-physics-character-controller/57357/28 "2025-04-03T07:13:35Z")

</div>

Now I want to see the rest of the anims 😃 Nice job!

---

<div class="post-metadata">

**Author:** ![AncientA](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/ancienta/32/46615_2.png) [@AncientA](https://forum.babylonjs.com/u/AncientA)\
**Post date:** [April 3, 2025, 9:27am UTC](https://forum.babylonjs.com/t/third-person-physics-character-controller/57357/29 "2025-04-03T09:27:51Z")

</div>

Oh yes sorry wrong link.

The one you shared is built with ammo js, but I think the controls are pretty similar. I will share my updated repo after removing some stuff if you still want to have a look.

I suppose the only difference between what was shared my implementation is that I also use the camera angle to calculate the input vector.

```auto
    public move(inputVector: Vector3, isSprinting: boolean, animationRatio: number) {
        
        let forward = this.camera.getForwardRay().direction;
        forward.y = 0; // Ensure horizontal movement only
        forward.normalize();
        const right = Vector3.Cross(Vector3.Up(), forward).normalize();
    
        let moveDirection = forward.scale(inputVector.z).add(right.scale(inputVector.x));
        if (!moveDirection.equals(Vector3.Zero())) {
            moveDirection = moveDirection.normalize();
        }
    
        // Apply animation ratio directly to base speed for frame rate independence
        const baseSpeed = 10; // Base speed adjusted by animation ratio
        const sprintMultiplier = isSprinting && this.stamina > 0 ? 2 : 1; // Determine sprint multiplier
    
        let adjustedSpeed = baseSpeed * sprintMultiplier; // Adjusted speed based on sprinting
    
        // Consume stamina if sprinting
        if (isSprinting && this.stamina > 0) {
            this.stamina -= this.sprintStaminaConsumptionRate * animationRatio;
        }
    
        // Apply the adjusted speed to the movement direction
        let velocity = this.mesh.physicsBody.getLinearVelocity();
        let newVelocity = new Vector3(moveDirection.x * adjustedSpeed, velocity.y, moveDirection.z * adjustedSpeed);
        this.mesh.physicsBody.setLinearVelocity(newVelocity);

        // Logging
        const currentTime = performance.now();
        if (currentTime - this.lastLogTime > 3000) {
    
       // console.log(`Sprint Multiplier: ${sprintMultiplier}`);
       // console.log(`Base Speed: ${baseSpeed}`);
       // console.log(`Adjusted Speed: ${adjustedSpeed}`);
       // console.log(`New Velocity: ${newVelocity}`);
        this.lastLogTime = currentTime; // Update the last log time
        }
    }

    public getWorldInputDirection(rawInput: Vector3): Vector3 {
        // Get camera's forward vector and adjust for horizontal movement
        let forward = this.camera.getForwardRay().direction;
        forward.y = 0;
        forward.normalize();
        // Compute the right vector
        const right = Vector3.Cross(Vector3.Up(), forward).normalize();
        // Compute move direction from raw input
        let moveDirection = forward.scale(rawInput.z).add(right.scale(rawInput.x));
        if (!moveDirection.equals(Vector3.Zero())) {
          moveDirection = moveDirection.normalize();
        }
        return moveDirection;
      }
    
    
    }

```

---

<div class="post-metadata">

**Author:** ![gsw945](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/gsw945/32/38399_2.png) [@gsw945](https://forum.babylonjs.com/u/gsw945)\
**Post date:** [April 3, 2025, 10:44am UTC](https://forum.babylonjs.com/t/third-person-physics-character-controller/57357/30 "2025-04-03T10:44:36Z")

</div>

Thank you very much.  
This code snippet is very informative, I wish I had seen it when I was first exploring character controller! But it’s still a reference for me now.

---

<div class="post-metadata">

**Author:** ![gsw945](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/gsw945/32/38399_2.png) [@gsw945](https://forum.babylonjs.com/u/gsw945)\
**Post date:** [April 3, 2025, 10:52am UTC](https://forum.babylonjs.com/t/third-person-physics-character-controller/57357/31 "2025-04-03T10:52:23Z")

</div>

Wow! Good job 👏, expect to see the full movement animation.  
The animation part is what I want to achieve that I don’t know yet, due to the lack of skills.

---

<div class="post-metadata">

**Author:** ![labris](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/labris/32/12576_2.png) [@labris](https://forum.babylonjs.com/u/labris)\
**Post date:** [April 3, 2025, 3:57pm UTC](https://forum.babylonjs.com/t/third-person-physics-character-controller/57357/32 "2025-04-03T15:57:04Z")

</div>

There were some changes… 🙂 - [https://playground.babylonjs.com/#9GE7HV#24](https://playground.babylonjs.com/#9GE7HV#24)

Added Walk and Run animations + animation blending.

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/f/5/f5caf28075e74679dde10168607147976ee03951.jpeg)

---

<div class="post-metadata">

**Author:** ![gsw945](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/gsw945/32/38399_2.png) [@gsw945](https://forum.babylonjs.com/u/gsw945)\
**Post date:** [April 4, 2025, 1:10am UTC](https://forum.babylonjs.com/t/third-person-physics-character-controller/57357/33 "2025-04-04T01:10:03Z")

</div>

It’s awesome, the movement animation looks silky smooth.  
Thanks to you, I’ve learned a new skill. As a newbie to Babylonjs, I’m so happy.

---

<div class="post-metadata">

**Author:** ![labris](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/labris/32/12576_2.png) [@labris](https://forum.babylonjs.com/u/labris)\
**Post date:** [April 6, 2025, 11:57am UTC](https://forum.babylonjs.com/t/third-person-physics-character-controller/57357/34 "2025-04-06T11:57:50Z")

</div>

Well, it’s just a draft.  
But probably I’ll develop it to the more robust and universal solution.

[Previous page](https://forum.babylonjs.com/t/third-person-physics-character-controller/57357.md?page=1)
