Some bugs and how I fixed them

Published by

on

UE5 character standing on the top of the mesh

Half Capsule Problem

I left off last post where I finally fixed collision, but my character’s collision capsule appeared to be half inside of the mesh. This took me a good long while to figure out and finally with help from the author of Jolt he cracked what I was doing wrong. Spoiler, units in Unreal Engine (cm) != units in Jolt Physics (m)!

The fix was to follow the documentation and scale before/after calling into Jolt. With that out of the way, I also have to offset by half the size of the capsule the call to Character->GetPosition() since the UE5 mannequin considers the actor location the center of the object. But now my character looks right and has the capsule in the right location!

Fixing movement

During the process of switching to Jolt, I decided to also take advantage of the Jolt’s CharacterVirtual class. This class will allow me to handle more complex things like walking up stairs, jumping and handling other movement related tasks. Unfortunately, due to how I serialize movement / input for the network, it wasn’t a drop in replacement and had to do some calculations on my own.

If you remember my old post about getting movement in manually, we need to update movement depending on the camera’s forward vector (direction it’s looking). In the JoltSamples they also don’t rotate the character model (because it’s just a capsule). I was on my own for this.

// Calculate the X/Z given our serialized Yaw value.
JPH::Vec3 CameraForward = JPH::Vec3::sZero();
CameraForward.SetX(JPH::Cos(Yaw));
CameraForward.SetY(0.f);
CameraForward.SetZ(JPH::Sin(Yaw));
CameraForward = CameraForward.NormalizedOr(JPH::Vec3::sAxisX());
JPH::Quat Rot = Quat::sFromTo(JPH::Vec3::sAxisX(), CameraForward);

ControlInput = Rot * ControlInput;

Not going to lie, I don’t really understand the Quat::sFromTo function, which states:

/// Create quaternion that rotates a vector from the direction of inFrom to the direction of inTo along the shortest path
/// @see https://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm
JPH_INLINE static Quat sFromTo(Vec3Arg inFrom, Vec3Arg inTo);

All I know is by multiplying the rotation by our input vector (which is just 1/-1 depending on which keys are pressed for the X/Y coordinates). Everything works with regards to moving the correct direction, depending on which way the camera is facing.

Fixing the rotation of the character

While my character is now moving in the correct direction, when we move and set this as our new rotation, the character rotates funny:

The only way I could actually get the character to both move and face the correct direction was to use the sFromTo for movement, and the following for rotation:

auto FacingRot = JPH::Quat::sRotation(JPH::Vec3::sAxisY(), Yaw);

Passing this to the Character->SetRotation(FacingRot); we now have both correct movement and rotation:

So that’s it, we have physics in, with our landscape mesh loaded into the physics engine, we have a character and movement now working. Next up? Delta snapshots of the world so we can start actually adding more clients and visualizing the movement in UE5! Exciting!