How to implement physics substep logic?

I’ve found this comment about how to implement logic in the physics sub step. However I have trouble implementing that solution.

I figured I have to create a custom component and override the TickComponent function.




#pragma once

#include "Components/StaticMeshComponent.h"
#include "CustomMeshComponent.generated.h"

/**
 * 
 */
UCLASS()
class Custom_API UCustomMeshComponent : public UStaticMeshComponent
{
	GENERATED_BODY()
	
	UCustomMeshComponent();
	~UCustomMeshComponent();

public:

	virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;

	void CustomPhysics(float DeltaTime, FBodyInstance* BodyInstance);
	
};




#include "Custom.h"
#include "CustomMeshComponent.h"

UCustomMeshComponent::UCustomMeshComponent() : UStaticMeshComponent(FObjectInitializer::Get()) {
	PrimaryComponentTick.bCanEverTick = true;
	PrimaryComponentTick.bStartWithTickEnabled = true;
	PrimaryComponentTick.TickGroup = TG_PrePhysics;

	Activate();

	UE_LOG(LogTemp, Warning, TEXT("Constructed"));
}
UCustomMeshComponent::~UCustomMeshComponent() {
}

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

	FCalculateCustomPhysics onphysics;
	onphysics.BindUObject(this, &UCustomMeshComponent::CustomPhysics);
	GetBodyInstance()->AddCustomPhysics(onphysics);

	UE_LOG(LogTemp, Warning, TEXT("Tick got registered."));
}

void UCustomMeshComponent::CustomPhysics(float DeltaTime, FBodyInstance* BodyInstance) {
	UE_LOG(LogTemp, Warning, TEXT("Ticktime %f"), DeltaTime);
	BodyInstance->AddForce(FVector(1000, 0, -8000), false);
// also put a breakpoint here
}


I added the component to a pawn and assigned a mesh to it. SimulatePhysics has been enabled as well. But neither does something get logged (except “Constructed”), nor does the actor move. It looks like TickComponent never gets called. SubStepping is enabled in the project properties as well.

Sadly I can’t find much information about this functionality in the documentation or Google. Does anyone know more?

Alright, apparently it was required to add following code to the constructor:


if (GetOwner() && GetOwner()->GetWorld())
		RegisterComponent();


TickComponent now gets called, but following issues arise:

  • A CameraArm I attached to the CustomComponent doesn’t work anymore; it’s always at the center regardless what length or offset it’s set to.

  • CustomPhysics() still doesn’t get called even though it’s added as custom physics each tick (see the code in the first post).

  • When placed in the world it falls (normal physics), but when assigned as the player pawn it’s frozen in the air where placed. This also happens when all the custom physics code is removed.