Character custom movement mode is overriden when in the air

So, I have a custom movement mode that handles grappling. When the player presses the grapple button, the movement mode is set to MOVE_Grappling and the player is flung into the air towards the target grapple point.

However, my movement mode is overriden by the character movement component and set to MOVE_Falling since the character is in the air. I know I can set my movement mode to MOVE_Grappling every frame, however this seems a little hackish and I don’t know if that might cause problems later on. Any ideas?

Your problem is that the character movement component sets the state to falling in several places.

SimulateMovement:


if (!CurrentFloor.IsWalkableFloor())
                {
                    if (!bSimGravityDisabled)
                    {
                        // No floor, must fall.
                        Velocity = NewFallVelocity(Velocity, FVector(0.f, 0.f, GetGravityZ()), DeltaSeconds);
                    }
                    SetMovementMode(MOVE_Falling);
                }

Also in ApplyRootMotionToVelocity (and 1 or 2 more physics calc functions):


if( AppliedVelocityDelta.Z > LiftoffBound )
        {
            SetMovementMode(MOVE_Falling);
        }

And more importantly, any time you perform the action “jump”.

DoJump:


// Don't jump if we can't move up/down.
        if (!bConstrainToPlane || FMath::Abs(PlaneConstraintNormal.Z) != 1.f)
        {
            Velocity.Z = JumpZVelocity;
            SetMovementMode(MOVE_Falling);
            return true;
        }

The right way to do this would be to write your own movement logic, is it worth it? Porbably not…

You can have a boolean that forcibly sets the state to Grappling within tick if true, this way you only cheat the engine for as long as you need it.

My suspicions were correct then. I’m just going to duplicate the UCharacterMovementComponent and modify it from there, but for now I’ll rely on setting the mode manually every frame. Thanks!