2
\$\begingroup\$

I perform a trace and when it hits the world I get a location and the surface normal. Does anyone have a good way to find out if I hit a wall or a floor?

\$\endgroup\$
5
  • 3
    \$\begingroup\$ This is pretty vague... How are you performing the trace? 2D or 3D? How is the world data stored? \$\endgroup\$
    – House
    Commented Sep 24, 2012 at 21:20
  • 2
    \$\begingroup\$ The normal from the surface can tell you. If it is pointing up or down, it is a floor or ceiling. If it is pointing left/right/forward/backwards, it is a wall. \$\endgroup\$ Commented Sep 24, 2012 at 22:20
  • \$\begingroup\$ @byte56 By "trace" I'm guessing he means raytrace. And since this question is tagged "udk" I'm assuming he means 3D. \$\endgroup\$
    – jhocking
    Commented Sep 25, 2012 at 0:24
  • \$\begingroup\$ @jhocking Yep, it wasn't tagged anything but programming when I asked. Though it's still fairly vague. \$\endgroup\$
    – House
    Commented Sep 25, 2012 at 0:59
  • \$\begingroup\$ @Byte56 I added the UDK tag because he mentioned he was using it in a comment. I figured it added needed context. \$\endgroup\$ Commented Sep 25, 2012 at 4:05

3 Answers 3

2
\$\begingroup\$

What Thomas said in his comment: the surface normals on the floor are pointed up, while the walls are pointed sideways.

(I'm leaving my response about the dot product because that will work too and helps explain how to work with 3D vectors, but phillips comment points out a simpler approach I didn't think of)

Just check the normal's Z component. So, if you wanted "floors" to be surfaces with normals < 45°, you could check if the Z value is > 0.707 (because sin(45°)=0.707). In fact, this is how Unreal checks if the Pawn is on a "floor" -- it compares the floor's normal Z value to WalkableFloorZ, which is 0.7 by default.


What you should probably do is get the dot product of the surface normal and a vector pointed straight up: if the trace crossed the floor then the dot product will be near 1, while if it was a wall then the dot product will be near 0, and if it was the ceiling then it'll be near -1

The threshold of how near is a value you can tune to see what works for your level:

var threshold = .1;
if (abs(1 - dotProduct) < threshold) {then...
\$\endgroup\$
2
  • \$\begingroup\$ Ah, I was looking at the wrong way. I was using the surface normal with the dot of the current orientation of the camera. Using the an up vector make much more sense. Thanks \$\endgroup\$
    – Jack
    Commented Sep 25, 2012 at 2:49
  • 1
    \$\begingroup\$ That will work. However, it would be cheaper to check the normal's Z component. So, if you wanted "floors" to be surfaces with normals > 45°, you could check if the Z value is > 0.707 (because sin(45°)=0.707). In fact, this is how Unreal checks if the Pawn is on a "floor" -- it compares the floor's normal Z value to WalkableFloorZ, which is 0.7 by default. \$\endgroup\$
    – Phillip
    Commented Sep 25, 2012 at 22:16
0
\$\begingroup\$

Without knowing more about your implementation, a simple way to determine if you're hitting a wall or a floor is by taking the direction your body is moving into consideration.

  • If you're moving left or right, and a collision occurs, then you've hit a wall.
  • If you're moving or falling down, and a collision occurs, then you've hit a floor.

So you can use the velocity of your entity to determine the nature of the collision.

\$\endgroup\$
2
  • \$\begingroup\$ This is UDK so 3D Vectors. \$\endgroup\$
    – Jack
    Commented Sep 24, 2012 at 22:11
  • \$\begingroup\$ He said he's performing a trace, so there is no body in motion. \$\endgroup\$
    – jhocking
    Commented Sep 25, 2012 at 0:18
0
\$\begingroup\$

As "Zack The Human" said, you should consider which way your character is moving. Another idea is to check which side of your player/object collided. If the bottom of your character collide you either hit the floor or an object you can stand on. Another method is to provide a pointer/reference to the object you collided with and conclude from that what you collided with.

Each of them has there perks in different situations, and they can all be implemented together. For example if I'm making a platformer I check the direction my player is moving and where the object I collided with is located. This way I can conclude if my player was moving down and collided with an object under it, that is hit the floor or a platform. Same goes for walls, if my player is moving left and hits an object to the left of it, stop moving left.

You should really learn 2D before 3D. Its easier to learn the concepts.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .