Cannot Disable ActorComponent Ticking

I have a custom C++ component derived from UActorComponent. This is added to various actors. I want to disable ticking on that component so I can handle that manually. But I am not able to do so. Despite deactivating ticking on the component it gets re-activated every frame.

How can I disable the automatic ticking of the TickComponent() method of the MovementComponent?

MovementComponent Constructor:

UMovementComponent::UMovementComponent()
{
    // Tried many ways found on the Internet to disable ticking, none works
	PrimaryComponentTick.bCanEverTick = false;
	PrimaryComponentTick.bStartWithTickEnabled = false;
	PrimaryComponentTick.SetTickFunctionEnable(false);
	SetComponentTickEnabled(false);
}

SomeActor Constructor:

SomeActor::SomeActor()
{
	// Movement Component
	MovementComp = CreateDefaultSubobject<UMovementComponent>(TEXT("Spaceship Movement Component"));
	MovementComp->PrimaryComponentTick.bCanEverTick = false;
	MovementComp->SetComponentTickEnabled(false);
	MovementComp->PrimaryComponentTick.SetTickFunctionEnable(false);
	AddOwnedComponent(MovementComp);
}

SomeActor Tick:

SomeActor::Tick(float DeltaTime)
{
        // Only works if called every frame. Comment the following out and the MovementComp gets ticked again.
	MovementComp->PrimaryComponentTick.bCanEverTick = false;
	MovementComp->SetComponentTickEnabled(false);
	MovementComp->PrimaryComponentTick.SetTickFunctionEnable(false);
...
}

I moved the “disable functions” to BeginPlay() of the MovementComponent which seems to work. Not working in the constructor though. Same thing as here? 'Set Actor Tick Enabled' not working after spawning - Programming & Scripting - Epic Developer Community Forums

Still wondering: It should be disabled for good after disabling it in the Actors’ Tick() method but gets re-activated every frame.

Same issue. Exact same solution. I’m pretty baffled by this one.

Setting PrimaryComponentTick.BCanEverTick will not work instead PrimaryActorTick.bCanEverTick has to be set. Also with the default constructor wit ill not work, bCanEverTick has to be set in the UMovementComponent(const FObjectInitializer& ObjectInitializer) constructor instead.

PrimaryComponentTick is for the ComponentTick(float DeltaSeconds) function while PrimaryActorTick is for the Tick(DeltaSeconds) function.

UMovementComponent::UMovementComponent(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) {
    PrimaryActorTick.bCanEverTick = false;
}

Do not forget to add this constructor in the header as well.

class WHATEREVER_API UMovementComponent: public SomeUnkownComponent
{
	GENERATED_BODY()

	UMovementComponent(const FObjectInitializer& ObjectInitializer);
}

Even if you set the ComponentTickFunction to disabled in the constructor it will be activated later during the component activation.

ActorComponent.cpp

void UActorComponent::Activate(bool bReset)
{
	if (bReset || ShouldActivate()==true)
	{
		SetComponentTickEnabled(true);
		SetActiveFlag(true);

		OnComponentActivated.Broadcast(this, bReset);
	}
}

This Activate function is called during component registration on OnRegister ActorComponent.cpp

void UActorComponent::OnRegister()
{

 // Previous code hidden

	if (bAutoActivate)
	{
		AActor* Owner = GetOwner();
		if (!WorldPrivate->IsGameWorld() || Owner == nullptr || Owner->IsActorInitialized())
		{
			Activate(true);
		}
	}
}

So based on that, to completly disable the component tick on constructor you need to set bAutoActivate to false:

UMovementComponent::UMovementComponent()
{
	PrimaryComponentTick.bCanEverTick = true;
	PrimaryComponentTick.bStartWithTickEnabled = false;
	PrimaryComponentTick.SetTickFunctionEnable(false);
	bAutoActivate = false;
}

Hope the explanation helped!

1 Like