This tutorial can be considered more like a 'cheat sheet' aimed at intermediate programmers who could achieve the result themselves. You should know vector math, algebra, and functions.
For a more in-depth tutorial, watch the youtube video.
To save time and support me, purchase the code from the Unreal Marketplace (now much more advanced with extra features).
Open the FirstPersonCPP/FirstPersonProjectile blueprint. With the ProjectileMovement component, add an OnProjectileBounce event.
Create a pure function called ComputeExitLocation that performs a backtrace (multispheretraceforobjects).
The backtrace start is 500cm behind the hit, in the direction of the impact velocity. The backtrace end is at the hit location.
The function goes through each hit in reverse order and returns the first hit whose 'hit actor' matches the original 'hit actor.'
It should then move the exit location a short distance away from the hit location to prevent collision.
Finally it checks the exit location is not obstructed by another object, and if so finds the next exit location by recursion.
It returns a location vector, a boolean, and a HitResult struct. Objects larger than 500cm deep will not return an exit location. We will use the HitResult struct later.
Back in the event graph, add a placeholder area for a 'DecideWhetherToPenetrate' function. At the moment we will simply check that the projectile's velocity is over a certain amount.If the projectile has enough velocity, and an exit location was found, spawn a new FirstPersonProjectile.
We cannot teleport the current projectile as Unreal's ProjectileMovementComponent precludes this. A cleaner but more time-consuming alternative would be to create a clone of Unreal's ProjectileMovementComponent and change its behavior so teleporting the object at this point is possible.
After spawning a new projectile, set it's velocity to half the impact velocity. We will create a more complex function to replace this later.
Finally call the destroy function to get rid of the original projectile. Also destroy the original projectile if no exit location was found.
You should now be able to test that the projectile penetrates objects.
If desired, open YourProjectProjectile.cpp and comment out the "Destroy();" line so that projectiles can bounce off physics objects.