# Grappling hook force resolution

Our team is creating a 3rd person adventure platformer in Unreal 4.22. One of the mechanics is a grappling hook. Think less-so a 'pull-to-point' grappling hook (Widowmaker, Just cause etc.). However more an actual physical simulation (Closer to that of a pendulum kinematics simulation).

Of course, my task is creating this grappling hook mechanic.

My Approach

I didn't see any way of approaching this that wasn't with vector math, so I went with that.

I created a derivative of the CharacterMovementComponent written by Unreal, and started working with this to attempt to recreate this physical simulation.

Initially, I attempted to create my own PhysCustom implementation. However after a month of development and no results, I switched my direction of attack.

I found, by chance, that Unreal allows you to add force to the CharacterMovementComponent, not to the character themselves, as I had previously thought.

My approach right now can be summed up as follows:

• Allow the character to be in their MOVE_Falling state (as provided by unreal)

• Perform all of the force applications in TickComponent

TickComponent

void UPlatformerMovementComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction * ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

// perform tick taught length update if required.
if (m_bUpdateTaughtDistanceEveryFrame) { UpdateTaughtDistance(); }

/* If the movement mode is falling and the player is attached to a point:
- Apply forces to the player                 */
float remainder = 0.f;
if (MovementMode == EMovementMode::MOVE_Falling && m_OwnerGrappleHook_Ref->IsAttached()) {

// If the rope is taught.Apply a force to the player to keep them at the grapple.
if (PlayerIsAtOrPastTaughtLength(&remainder)) {

if (m_bWantsInitialSwingVelChange) {
//Ver 2 - Used.
float velSize = Velocity.Size();
FVector ToGrapple = GetVectorToPoint(); ToGrapple.Normalize();
Velocity += ToGrapple * velSize;

m_bWantsInitialSwingVelChange = false;
}

FVector Force = GetVectorToPoint() * 980.f;

}
// If the rope is not taught, then decay the velocity to prevent bouncing.
else {
Velocity *= 0.97f;
}
}
}


Some code explanation

remainder and bool PlayerIsAtOrPastTaughtLength(float *)

• remainder is used to store the distance past the m_TaughtDistance from the grapple point that the player lies at.

• bool PlayerIsAtOrPastTaughtLength(float *) returns whether the player is past this m_TaughtDistance or not, and places the amount in the float* if true.

m_TaughtDistance

• The theoretical distance from the grapple point which would reach the radius of the grapple point's 'influence' sphere.

m_OwnerGrappleHook_Ref

• A reference to the GrappleHookComp object that works with the MovementComponent

GrappleHookComp

• An object that stores and deals with most of the grapple hook variables, functions and states.

m_bWantsInitialSwingVelChange

• a Bool that is set to true when initially attaching to a point.

• Causes a velocity change by adding the same size vector as the player's velocity towards the grapple point.

The problem

This causes a jitter at the bottom of the radius of the circle. Where the player never comes to rest at the m_TaughtDistance point below the grapple point.

Am I missing something in my force applications?

Am I approaching this wrong?

Any help would be appreciated.