Start with tick disabled and opt in
The projectile never ticks. The missile turns ticking on when it actually needs a per-frame update.
AProjectile::AProjectile()
{
PrimaryActorTick.bCanEverTick = false;
}
void AProjectile::BeginPlay()
{
Super::BeginPlay();
GetWorld()->GetTimerManager().SetTimer(
LifetimeTimer,
this,
&AProjectile::HandleLifetimeExpired,
MaxLifetimeSeconds,
false);
}
AHomingMissile::AHomingMissile()
{
// Steering needs a per-frame update, and it has to run before physics.
PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.bStartWithTickEnabled = false;
PrimaryActorTick.TickGroup = TG_PrePhysics;
}
void AHomingMissile::BeginPlay()
{
Super::BeginPlay();
SetActorTickEnabled(IsValid(CurrentTarget));
}- Why
- Every ticking actor costs a function call and a cache miss each frame, whether or not it does work. Disabling tick in the constructor makes the cost opt-in rather than the default.
- Costs
- Setup now lives in two places, and a subclass that needs ticking has to remember to enable it. Enabling in
BeginPlaykeeps that decision next to the runtime state it depends on. - Instead
- Use
TickIntervalwhen work needs to run regularly but not every frame. Use a timer for a one-shot delay, and a delegate for anything that reacts to an event rather than to time.

