Wall Attachment

The idea is when the player presses Climb, as long as there is a surface to climb on, we'll attach the player to the wall.

We've already been setting the Movement Mode to MOVE_Custom, and _Climbing, but haven't actually done anything with that yet. Let's hook into the CharacterMovementComponent::PhysCustom by overriding it and adding our own logic.

.h

// ZCCharacterMovementComponent.h

private:
	virtual void PhysCustom(float deltaTime, int32 Iterations) override;
	
	void PhysClimbing(float DeltaTime, int32 Iterations);

.cpp

// ZCCharacterMovementComponent.cpp

void UZCCharacterMovementComponent::PhysCustom(float deltaTime, int32 Iterations)
{
	if (CustomMovementMode == ECustomMovementMode::CMOVE_Climbing)
	{
		PhysClimbing(deltaTime, Iterations);
	}

	Super::PhysCustom(deltaTime, Iterations);
}

void UZCCharacterMovementComponent::PhysClimbing(float DeltaTime, int32 Iterations)
{
	// Note: Taken from UCharacterMovementComponent::PhysFlying
	if (DeltaTime < MIN_TICK_TIME)
		return;
}

Where to attach

Since we're using a shape sweep we will most likely have a few collision points, ones on corners of one wall, and the crest of another and even a third.

multiple surface collisions

To determine where we should attach, we can just average all the hits to find our final location.

Likewise for our orientation we can add up all the surface normals then normalize the aggregate vector to get an average normal.

Let's store these in some new members and make a function to calculate them.

.h

.cpp

Then add a call to our new function in PhysClimbing

.cpp

Now when we press Climb next to multiple surfaces, the position to attach is an average of all the hits

Green sphere is CurrentClimbingPosition with CurrentClimbingNormal facing the walls

When to Detach

The player should detach from the wall when any of the following occurs

  • Input press to detatch

  • Climbing on a flat surface

  • Or if the climbing normal is zero (meaning the plane doesn't exist) since it will be used to determine other aspects of the climb

.h

Implement the functions and add it to PhysClimbing()

.cpp

The last thing we need to do is make sure we don't accidentally collide with anything outside of where it makes sense while we're on the wall.

Essentially we want our capsule collider to only collide with things in our more "scrunched up" climbing pose ( like the image below)

Capsule Size

The idea is when the movement changes, if we're in the climbing mode, shrink the capsule colider.

If it changes and we're not climbing but we were we'll reset the size, make sure you character is standing upright (because who knows what position they released from the wall), and stop their movement (CharacterMovementComponent gives us this function nicely)

.h

We want to change the capsule size while on the wall.

Additionally once we're attached to the surface we want to always stay facing the surface versus what the Third Person Template is currently having us do which is rotate with the input.

While climbing we want to turn bOrientRotationToMovement off, and then re-enable it when we're not climbing

.cpp

a little hard to see but here the capsule collider can be seen changing size when attached and detached

If you're trying to figure out how to see the capsule component, I find it useful to just type in 'hidden' in the BP's details

Last updated