# [.net] [XNA] Viewport.Unproject() problems

This topic is 4159 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hey! I'm making a game where characters run around on the XY plane and one looks down straight along the Z axis. So, I was trying to calculate the point in the 3D world that the player clicks on when he/she clicks the screen. So I did a little research and found the Viewport.Unproject() method. In the example given it says:
Quote:
 Using Viewport.Unproject, determine points in world space on the near and far clip plane. For the point on the near plane, pass a source vector with x and y set to the mouse position and z set to 0. For the point on the far plane, pass a source vector with x and y set to the mouse position and z set to 1.
So I thought that I wanted the point on the XY plane, that is between the near and far clip plane. So I thought since near clip plane is 0 and far is 1 I could do something like CAMERA_HEIGHT / FAR_CLIP_PLANE to get something between 0 and 1 (the constants are floats, and yes it evaluates to 0.22). But when I viewed the results it looks like this:
Vector3 worldTarget = Tools.Unproject(new Vector3(x, y, 0.22f));
Vector3 worldTarget2 = Tools.Unproject(new Vector3(x, y, 0f));
Vector3 worldTarget3 = Tools.Unproject(new Vector3(x, y, 1f));
Console.WriteLine("Clicked in the world at: " + worldTarget.ToString());
Console.WriteLine("Clicked in the world at: " + worldTarget2.ToString());
Console.WriteLine("Clicked in the world at: " + worldTarget3.ToString());

Gives:
Clicked in the world at: {X:2,574506 Y:2,974289 Z:21,87183}
Clicked in the world at: {X:2,578318 Y:2,971995 Z:21,9}
Clicked in the world at: {X:-10,93982 Y:11,11092 Z:-78,00553}

This makes sense for the two calls with 0 and 1, since my near clip plane is at 0.1 and my far at 100 and my camera at height 22. But the call with 0.22 is almost the same as with 0. Is 0 and 1 the only two valid Z values? I know that the problem can be solved by using the 2 planes, but it just seemed more elegant to me to do it my way. I'm just curious if I missed something here or what.

##### Share on other sites
I'm not sure I understand what you're asking, but I'll give it a shot.

If you supply Viewport.Unproject with the correct parameters, it will already take the near and far clipping plane into account. Essentially it will translate your clip (or screen?) space coordinates back into your 3D world by applying the reverse of the transform your vertices go through, so your clip coordinates end up in the worldspace viewing frustum. So far, so good. The point is however, that the Z coordinate in world space doesn't get evenly distributed to [0;1] in your clip space (see here for more info), so you can't easily make straightforward assumptions to which world coordinate your clip space coordinate will be unprojected, except for the ones at the near and far clipping plane.

The failsafe way to use unproject therefore is to unproject the mouse coordinates at the near and far clipping planes (using z=0 and z=1) and use these to construct a ray. Everything that intersects with this ray is basically 'under the cursor', so when the user clicks you can find out on what. In your case, you'll probably want to intersect the ray with the XY ground plane that represents your playing field. IIRC the Plane utility class in XNA will handle the gritty details of the intersection for you.

Hope this helps and isn't utterly confusing :)

##### Share on other sites
Yeah it helped, with the link and all. I'm going with the fail safe way. Thank you! :)

1. 1
2. 2
Rutin
16
3. 3
4. 4
5. 5

• 26
• 11
• 9
• 9
• 11
• ### Forum Statistics

• Total Topics
633704
• Total Posts
3013457
×