How would you go about tracing into the world and determining where the hit is on the “floor”, a “wall” or “ceiling” ?
For example if the surface is either flat or up to a 35 deg. slope, it would be considered a “floor”, if the slope is at more than 35 deg. - “wall” and I am guessing if surface normal is -Z (regardless of the slope) it would be “ceiling”.
You cannot do one point normal. Because if you hit something like pipe or some decorations, normal of single point may be totally different than average normal of mesh.
You could instead do multiple normal traces (for eg 4x4 grid, and 16 traces), then get average vector of it.
Or trace location of 3 points on surface of mesh, then make cross product of any 2 vectors made from that 3 points. This will tell you what is normal to surface mede by those 3 points.
Then for guessing angle between that normal and UP direction do DOT product. It will give you cosinus of angle between those 2 directions.
The idea is to ignore any and all decorations. Only “world” surfaces should be valid surfaces (I am guessing I could use physics material type to filter that). So any pipes, chairs, tables, etc. should be ignored.
Then do line trace for collision only, not for visible chanel. And make all meshes with proper collision.
Thinking of it even if you do very clean collision and later you or your level designer will stack up few random rocks, you will get same undesired “random normal” effect.
Just imagine placing 9 of exactly same cubes in one spot with random rotation. You will get spikes that may have normal pointing into half of sphere.
Why would I get it, if only actual floor would have physical surface type, and rocks won’t ? Isn’t there a way to filter trace hit by physics material type ? Add new surface type to the material used on the floor and then do something like if (type == “solid” ), but in BP ? This way when trace hit the rocks, it would just ignore them since they don’t have surface type “solid”.
Yes you can filter hit results by physics material.
But later you or your level designer will want to add more shapes everywhere. Line trace will get only what is on top it will not go trough those shapes down to your physics material. Well theoretically you can do multi line trace there to get deeper, but that means levels need double geometry everywhere. It kind of doubles work needed to make levels, and in return you get a bit less code in one function.
About double geometry:
moment you add more detailed geometry, normal at some random point above “flat” ground may be quite random. Imagine you dropped some M&Ms on flat desk. Now what happens if you try to see direction of normal to desk surface if you choose side of candy? That normal will not be facing up, it will face to the side and be normal of that M&M candy not normal of a desk. Now if you make hovercraft that uses single normal, it would just do barrel roll above each candy.
With single line trace you need to trace only DESK surface. but what if you made wall just of M&Ms, and there would be no flat surface behind it? Every single normal you check would point in random direction from half of sphere.
So your choices are:
do 3 points tracing, use my idea of cross product from 3 location.
do single line trace, use normal. But make double geometry and trace only to “flat” surfaces.
or do just single line trace and have errors with normal.
Can we do such trace in UE4 (that penetrates all objects on its way) ? If we can, then this is what I am thinking - trace, filter hits by physics surface type, then do dot product on hit #3 (since M&Ms will be filtered out as they don’t have any physics surface type defined, hit #1 and hit #2 will be dismissed).
The reason I wanted to use material surface type is that if I have a trail on a terrain, I’d want to only get valid hits on that trail. I am not sure it would be possible with custom trace channel for whole mesh.
Btw, does trace hit returns world location ? Hmm… I see that Break Trace Results node has Location. Gotta be the world location, right ?