Download

Any reason this Delegate won't fire?

For some reason, I can’t get this delegate to fire. At least, it doesn’t seem to be, since I get no message printed to the screen. The idea is that when the object is destroyed, it’s mesh will be catapulted into the air and will switch on ‘Generate Hit Events’. When it hits the floor, it’ll call ‘OnCrash’ which calls explosions & destruction n’stuff.

I haven’t hit a compiler error or anything so I think I’m passing all of the correct parameters to OnCrash(), it just never seems to get called. The Delegate is of course, added at runtime (since this is the only time I want it to be registering the ‘Hit’ events).



void ABZGame_Vehicle::KillVehicle()
{
	if (Role == ROLE_Authority && !bPendingKillPending && !bKilled)
	{
		bKilled = true;

		if (!bPilotWantsToExit && HasPilot())
		{
			OnBailout();
		}

		if (bCrash)
		{
			/* Enable 'Ragdoll' */
			GetVehicleMesh()->SetAllBodiesSimulatePhysics(true);
			GetVehicleMesh()->SetAllBodiesPhysicsBlendWeight(1.0f, false);
			GetVehicleMesh()->AddImpulse(FVector(0.f, 0.f, 2500.0f), NAME_None, true);

			/* Add Dynamic Hit */
			GetVehicleMesh()->BodyInstance.bNotifyRigidBodyCollision = true;
			GetVehicleMesh()->OnComponentHit.AddDynamic(this, &ABZGame_Vehicle::OnCrash); // THIS DELEGATE NEVER GETS CALLED
		}
		else
		{
			SetActorEnableCollision(false);
			GetVehicleMesh()->CastShadow = false;
			GetVehicleMesh()->bHiddenInGame = true;

			DisableAndDestroy();
		}

		/* Play Initial Explosion */
		if (DeathExplosion)
		{
			FHitResult Hit;

			ABZGame_Explosion* ExplosionEffect = GetWorld()->SpawnActorDeferred<ABZGame_Explosion>(DeathExplosion, GetActorLocation(), GetActorRotation());
			if (ExplosionEffect)
			{
				ExplosionEffect->Instigator = this;
				ExplosionEffect->FindFloor(GetActorLocation());
				UGameplayStatics::FinishSpawningActor(ExplosionEffect, FTransform(GetActorRotation(), GetActorLocation()));
			}
		}
	}
}

void ABZGame_Vehicle::OnCrash(AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
	GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, FString::Printf(TEXT("Hiya"))); // I NEVER SEE THIS :O

	if (Role == ROLE_Authority && !bPendingKillPending)
	{
		SetActorEnableCollision(false);
		GetVehicleMesh()->CastShadow = false;
		GetVehicleMesh()->bHiddenInGame = true;

		/* Play Initial Explosion */
		if (CrashExplosion)
		{
			ABZGame_Explosion* ExplosionEffect = GetWorld()->SpawnActorDeferred<ABZGame_Explosion>(CrashExplosion, GetActorLocation(), GetActorRotation());
			if (ExplosionEffect)
			{
				ExplosionEffect->Instigator = this;
				ExplosionEffect->SurfaceHit = Hit;
				UGameplayStatics::FinishSpawningActor(ExplosionEffect, FTransform(GetActorRotation(), GetActorLocation()));
			}
		}

		DisableAndDestroy();
	}
}


EDIT: Just in case I was being stupid, I tried this too. Even this doesn’t get called.

…Annnd just like that I fixed it as soon as I post this. For future reference, here’s what you need to do:

The Physics Asset also needs to have ‘Simulation Generates Hit Events’ turned on for whatever bone’s / primitives you want to check against.

And the code becomes this (which updates the BodyInstance itself):



			/* Add Dynamic Hit */
			GetVehicleMesh()->SetNotifyRigidBodyCollision(true);
			GetVehicleMesh()->OnComponentHit.AddDynamic(this, &ABZGame_Vehicle::OnCrash);