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\$
    – MichaelHouse
    Sep 24 '12 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\$ Sep 24 '12 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
    Sep 25 '12 at 0:24
  • \$\begingroup\$ @jhocking Yep, it wasn't tagged anything but programming when I asked. Though it's still fairly vague. \$\endgroup\$
    – MichaelHouse
    Sep 25 '12 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\$ Sep 25 '12 at 4:05
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
    Sep 25 '12 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
    Sep 25 '12 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
    Sep 24 '12 at 22:11
  • \$\begingroup\$ He said he's performing a trace, so there is no body in motion. \$\endgroup\$
    – jhocking
    Sep 25 '12 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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.