How to get the surface type, and physical material with a projectile in C++?(No Linetraces)

I did a you said I just need to apply physical materials to all forms of collision within the mesh and textures in order to prevent a collision returning null.

I will keep that in mind. But I am trying to use the hit information that the component hit function is providing for now.

Thank you for the suggestions.

I figured it out! I created a socket and attached it to the mesh then I attached a line trace to the mesh and on comp hit the line trace fires out of the socket attached to the mesh in order to create the decal! This is the solution.

void ABullet::BulletHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit2)
{
	if(AActor* Actor = Cast<AActor>(OtherActor)
{
	FHitResult TraceEndHit;
	FCollisionResponseParams BulletLineParams;
	FCollisionQueryParams BulletLineQueryParams = FCollisionQueryParams(SCENE_QUERY_STAT(WeaponTrace), false, this);
	FActorSpawnParameters BulletLineSpawnParams;
	BulletLineQueryParams.bReturnPhysicalMaterial = true;
	BulletLineSpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
	BulletLineQueryParams.AddIgnoredComponent(ShellCasing);
	BulletLineQueryParams.AddIgnoredComponent(HitSphereComp);
	
	const FVector BulletLineStartTrace = ShellCasing->GetSocketLocation("BulletSocket");
	FRotator BulletCurrentRotation = ShellCasing->GetSocketRotation("BulletSocket");
	FVector BulletLineEndTrace = BulletLineStartTrace + BulletCurrentRotation.Vector() * 1000;
	if (GetWorld()->LineTraceSingleByChannel(TraceEndHit, BulletLineStartTrace, BulletLineEndTrace, ECollisionChannel::ECC_Visibility, BulletLineQueryParams, BulletLineParams))
	{
		
		
			if (AActor* Actor = Cast<AActor>(TraceEndHit.GetActor()))
			{
				FVector DecalSize(10.0f, 10.0f, 10.0f);
				FRotator DecalRotation = TraceEndHit.ImpactNormal.Rotation();
				FVector DecalLocation = TraceEndHit.Location;
				
				switch (TraceEndHit.PhysMaterial->SurfaceType)
				{
				case SurfaceType2:
					UGameplayStatics::SpawnDecalAtLocation(Actor, Damage, DecalSize, DecalLocation , DecalRotation, 5.0f);
					Destroy();
					break;
				default:
					Destroy();
					break;

				}
			}
		
	}
}
}

Using a linetrace in of itself is better because it seems to prevent crashing in general as opposed to using OnCompHit events hit results.

If you want to get physical materials from component hit/move events, all you need to do is this:

CollisionComp->bTraceComplexOnMove = true;
CollisionComp->bReturnMaterialOnMove = true;

You can put that in the constructor. TraceComplex is optional but usually desirable for projectiles, you want the detail collision not simple collision (which will give you the proper physical material from the shaders too)

2 Likes

I appreciate the advice I will make sure to try it out.

Bro you just saved me from moving all my logic from my projectile to my player thank you so much!

1 Like

Thank you for the help!