I’m having my first go at creating a custom movement component (extending the default Character Movement Component), and have stumbled upon a problem when it comes to getting my character to move at the correct speed.
Based on some tests it seems that CalcVelocity either isn’t setting the Velocity correctly, or fails to cap it, and I can’t figure out why. Everything is fine when moving about regularly. By checking the vector length of Velocity it shows me that the Walking movement mode caps at 500 which matches the max walking speed. However, when I enter my custom movement mode (which has a max speed of 200) I start moving at a speed of 1500 instead.
I’ve used UE_LOG to test that GetMaxSpeed returns the correct value (200 in my case). Coincidentally I noticed that the third person template which my project is based on has it’s max acceleration set to 1500 on the character. So I did a test and reduced max acceleration to something else, and the speed I moved matched the max acceleration exactly.
I also noticed that where the default walking movement mode returns a Velocity of 0,0,0 when I’m walking stuck against a wall (as it should), my custom movements Velocity returns approx. 0,0,-16 when I keep holding the input to climb downwards after having hit a floor.
I am unfortunately not particularly skilled at C++, so although I’ve tried going through both my code and also trying to work backwards into the engine code, I’m still without an answer. Could anyone tell me where I’m going wrong here?
Please keep in mind this isn’t finished code, so lots still missing and I know there are other minor things I need to fix and clean up later.
void UClockCharacterMovementComponent::PhysClimbing(float deltaTime, int32 Iterations)
{
// TODO: Add all the root motion stuff.
// TODO: Logic for mantling the top, and potentially for ledgehanging.
// TODO: Logic for dropping down when hitting the floor.
if (!CharacterOwner || (!CharacterOwner->Controller && !bRunPhysicsWithNoController && !HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity() && (CharacterOwner->GetLocalRole() != ROLE_SimulatedProxy)))
{
Acceleration = FVector::ZeroVector;
Velocity = FVector::ZeroVector;
return;
}
bJustTeleported = false;
float remainingTime = deltaTime;
while ((remainingTime >= MIN_TICK_TIME) && (Iterations < MaxSimulationIterations) && CharacterOwner && (CharacterOwner->Controller || bRunPhysicsWithNoController || HasAnimRootMotion() || CurrentRootMotion.HasOverrideVelocity() || (CharacterOwner->GetLocalRole() == ROLE_SimulatedProxy)))
{
Iterations++;
bJustTeleported = false;
const float timeTick = GetSimulationTimeStep(remainingTime, Iterations);
remainingTime -= timeTick;
/** Something is iffy about this.Character moves ridiculously fast when climbing. Did the following logging just to check that the max speed is correctly.
UE_LOG(LogTemp, Warning, TEXT("Max speed: %f"), GetMaxSpeed());
It returns a Max Speed of 200 as expected for the climbing movement mode. When walking the vector length of velocity is 500 as expected, but during climbing this becomes 1500. Turns out that 1500 is the Max Acceleration listed in the movement components general settings. Turning this down to 200 and doing the same vector length of velocity check showed a speed of 200, so it is clearly using max acceleration without limiting the max speed.
Is CalcVelocity supposed to limit the acceleration to the max speed, but for some reason not doing it? */
CalcVelocity(timeTick, GetMaxSpeed(), true, GetMaxSpeed());
FHitResult Impact;
SafeMoveUpdatedComponent(Velocity, TargetRotation, true, Impact);
HandleImpact(Impact);
}
}