Third Person Physics Character Controller

I implemented the demo about Third Person Physics Character Controller, Using TypeScript, playground: Babylon.js Playground

Base code and inspiration from documentation Physics character controller and playground https://playground.babylonjs.com/#WO0H1U#13

There is a CustomCharacterController class also in the playground, which is the parent class of ThirdPersonCharacterController.
So it’s easy to create a FirstPersonCharacterController, which I envisioned replacing with a UniversalCamera instead of FollowCamera, but I’m not interested in implementing that right now.

4 Likes

Added Virtual Joystick for Character movement, this is useful for mobile devices.
playground: https://playground.babylonjs.com/#9GE7HV#1

Good for a start, but you are missing some stuff.

  • Camera should not be zooming in and out when rotating around the “player”.
  • add some objects like stairs \ steps, slopes of different angles, tunnels, complex geometry, even basic fall \ fall down the slope.

Can’t test much without it ¯_(ツ)_/¯

Example PG has a flaw too with velocity projection (jump often result in sliding up the slope instead of jumping).

There’s more then meets the eye.

1 Like

I don’t have complex demands, and this level of what has been implemented so far is good enough for my usage needs.

1 Like

One glaring issue at the moment is that the Physics Character is moving without the orientation changing to the direction it is moving in.
I don’t currently know how to accomplish this without changing the camera orientation.

I think I can help with that when I’ll have a bit more time, is it a single \ merged mesh you are using?

Where were you a year ago when I started working on my game? :joy:

In all seriousness, great work though! I’ve implemented something similar for my game (CosmoKick.io), with most likely more complicated solutions that it needed to be.

But hey, if it works it works :smiley:

This is an amazing project. I’m excited to see what you do next!
And I’m so happy to see a great use of the physics controller :slight_smile:

Twin stick shooters use 2 sticks: 1 for direction, 1 for shooting orientation. It’s pretty standard when you had a pad and 2 mini sticks. I’m not used to this kind of gampleay on a phone, so there might be better solution.

Virtual Joystick is only used to provide the ability to move on a mobile device, in the absence of other available inputs.
I don’t have a complete idea for a game yet, so I’m just going to try to implement various demos first. but I’m probably leaning more towards an open world rpg, running around.
The PhysicsCharacterController playground inspired me, but it changes the camera rotation during left and right movement, causing the trajectory to curve when I move horizontally, and I’m currently leaning towards manually adjusting the camera orientation.

Very good soccer game! Would be fun to add competitive multiplayer.

1 Like

Thanks, any suggestions are welcome, it’s just a single capsule mesh.

Thanks :folded_hands:

I’m working on it right now actually!

Once I’m happy enough with the server and start hosting it I’ll start sharing the progress in a post here!

2 Likes

Ohh and by the way for the orientation issue I implemented a work around, where I make the player mesh “face” the camera and the camera target is an invisble mesh.

There is a public repo I shared in the discord almost a year ago, feel free to check it out, might give you some ideas. I also have the mobile controls working pretty well.

https://gitlab.com/open-source9600911/babylontemplate/-/tree/main/src?ref_type=heads

1 Like

Looking forward to competing at CosmoKick.io!

1 Like

Thanks for sharing, I’ll look into it.

Just to put something for right now - basic idea behind making mesh face direction it is movign is there:

  1. Get direction player is moving by inputs as Vector3.
  2. Get target Y rotation by - Math.atan2(moveDirection.x, moveDirection.z).
  3. Set Y rotation of a mesh to that.

That is most basic, that is not going to be smooth.


If you want something more complex - you would need to

  1. get current mesh Y rotation
  2. get Target Y rotation (calculated from input direction)
  3. Calculate their difference
  4. Smoothly frame by frame rotate mesh Y to target Y.

Here’s what I was doing in my implementation for smooth rotation with free camera control:

            //get input velocity vector
			const moveDirection = inputVelocity.clone()

			// Only rotate if there's movement
			if (moveDirection.lengthSquared() < 0.001) return

			moveDirection.normalize()

			// Calculate target rotation - where you want mesh to rotate
			const targetY = Math.atan2(moveDirection.x, moveDirection.z)

            //get current mesh rotation
			const currentY = mesh.rotation.y
			const rotationDifference = targetY - currentY

			// Find shortest path to rotate to, so it's not wildly rotating like 300 degrees around itself.
			const normalizedDifference = Math.atan2(Math.sin(rotationDifference), Math.cos(rotationDifference))


			const maxRotationChange = 8 * delta
			const rotationChange = Math.max(-maxRotationChange, Math.min(maxRotationChange, normalizedDifference))
            //apply new rotation to mesh
			mesh.rotation.y += rotationChange


Can do last part with lerp instead if you prefer:

			const lerpAmount = Math.min(1, 8 * delta)
			const newRotationY = currentY + normalizedDifference * lerpAmount

            //apply new rotation to mesh
			mesh.rotation.y = newRotationY

Hopefully my variables aren’t too confusing :eyes:
I can look through your thing and implement similar behavior if that’s too complicated and if that is what you want - camera can move freely, mesh \ player smoothly rotates itself towards input target.

P.s. changed some variables to make more sense, conceptually still should work.

3 Likes

Thank you very much, your code has inspired me very well.
After many attempts, I added a TransformNode for character position synchronization, added a lookTarget for FollowCamera tracking, and displayCapsule for rendering rotation. So far the character is facing the direction of movement.
playground: