Download

Implementing a shadowstep type spell - random (valid) point in a radius

Shadow step spells pick a random nearby location to teleport the player to. This is pretty easy to do generally, you just rand the radius x,y. This works well except when dealing with uneven terrain, you could end up high in the air or under the map.

Once I have the X,Y, how can I find where a valid Z-axis is, regardless of if its a mesh/terrain/etc? I’m guessing two ray traces, Z up and down, that intersect with a collision and pick the nearest one?

Also is there any efficient way to trace 360 degrees around the player and only Rand() the X,Y in directions where a collision doesn’t intersect (so a Player can’t shadowstep through walls or outside level bounds)?

If you have an uneven terrain I’m assuming you want to be able to shadow step up and down the terrain as well. But you don’t want to glitch into - or through a wall or land on top of a roof?

I’d ray trace down from above.
The trace (where we can identify the hit actor from FHitResult) can either be:
Terrain (Good to teleport)
Roof(Not good to teleport)
Dog(Not good to teleport)
.
.
.
etc

But what if you hit a roof of a house, and house is placed on a lower Z value than the shadowsteppin’ ninja so the roof is actually roughly on the same Z level as the ninja?
You can check if (FMath::Abs(Ninja.GetActorLocation().Z - HitActor.GetActorLocation().Z) < 200) meaning if it’s a roof you CAN land on it if it’s no more than 2 meters above or below the ninja’s position.

If you don’t want to shadowstep through a wall between you and the found location, a trace from the ninja to that location sounds like a good idea.

When you want to shadow step, do some math to construct bounds of a circle of a given radius and place it some arbitrary amount above the ninja. Any point within this circle (X, Y) is your random trace start. Then just fire down onto the ground to find a spot to shadowstep to.