(Sorry, I should’ve included the code in the post)
When moving the character, if it bumps into an object, it applies a force to it and also slides along its side (it works as intended up to this point). Then, if it bumps into another object, it also tries to apply a force to it (however this part does not work, it doesn’t apply a force to the second object, only the first). Here’s the code for the movement part:
void UPlatformerMovementComponent::ApplyMovementInput(float DeltaTime)
{
FVector DesiredMovementThisFrame = ConsumeInputVector();
if (!DesiredMovementThisFrame.IsNearlyZero())
{
FHitResult Hit;
//Safe move character.
SafeMoveUpdatedComponent(DesiredMovementThisFrame, UpdatedComponent->GetComponentRotation(), true, Hit);
//If we bump into something...
if (Hit.IsValidBlockingHit())
{
AActor* FirstHitActor = Hit.GetActor();
//apply force to it...
ApplyForceToHitObject(DesiredMovementThisFrame, Hit, DeltaTime);
//Compute new slide desired movement (for future use):
FVector SlideMovementVector = ComputeSlideVector(DesiredMovementThisFrame, Hit.Time, Hit.Normal, Hit);
//then slide along its side.
SlideAlongSurface(DesiredMovementThisFrame, 1.f - Hit.Time, Hit.Normal, Hit, true);
//Store new slide desired movement to desired movement this frame (for future use):
DesiredMovementThisFrame = SlideMovementVector;
//And if we bump into second object...
if (Hit.IsValidBlockingHit())
{
//apply force to it too.
ApplyForceToHitObject(DesiredMovementThisFrame, Hit, DeltaTime);
AActor* SecondHitActor = Hit.GetActor();
SlideMovementVector = ComputeSlideVector(DesiredMovementThisFrame, Hit.Time, Hit.Normal, Hit);
SlideAlongSurface(DesiredMovementThisFrame, 1.f - Hit.Time, Hit.Normal, Hit);
DesiredMovementThisFrame = SlideMovementVector;
}
else
{
//GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No second valid blocking hit "));
}
}
}
}
And here is the function that actually applies force to the objects:
void UPlatformerMovementComponent::ApplyForceToHitObject(FVector DesiredMovementThisFrame, FHitResult& Hit, float DeltaTime)
{
//if we bump into physics simulating object, apply force to it
if (Hit.GetComponent() && Hit.GetComponent()->IsSimulatingPhysics())
{
//Calculate force vector:
FVector Force = DesiredMovementThisFrame.ProjectOnTo(Hit.Normal * -1.f) * CharacterMass / DeltaTime;
//Add force along normal of impoact (less realistic but avoids some issues):
Hit.GetComponent()->AddForceAtLocation(Force, Hit.Location);
//GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Applying force to " + Hit.GetActor()->GetActorNameOrLabel() + "\n Force vector: " + Force.ToString()));
}
else
{
//GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Ttried to apply force to " + Hit.GetActor()->GetName() + " but is not simulating physics"));
}
}