Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

Targeting HUD/Crosshair in 3D Space Shooter


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
10 replies to this topic

#1 -XM-   Members   -  Reputation: 159

Like
0Likes
Like

Posted 30 January 2011 - 11:09 AM

Hey everyone, I'm working on another 3D space shooter in XNA and have been stuck on this for about a week now.

Right now I have a ship that can fly around and fire bullets, I also have a chase camera following it. I am trying to implement a targeting HUD similar to what you'd see in Star Wars: Rogue Squadron but I can't get the HUD to accurately line up with where the bullets are fireing. The targeting HUD is lined up maybe half of the time, but when the ship is in certain angles, or the player accelerates, it's totally off. I think my camera might have something to do with it, since it will pull back when the player accelerates and what not.

I'm thinking that maybe I can somehow calculate the bullet's projected path to update the HUD position. Is this the recommended way of approaching this? I've tried googling for samples to see how most people approach this kind of problem but haven't come up with much. I guess what I'm really needing help with is the logic/math to get the correct position.

Let me know if there is some certain code that you'd like to see but I'm not sure what would be helpful for me to post. I'm thinking the chase camera is a big problem with why it's not looking right, because it will pull back and whatnot at certain times. I've tried calculating HUD positions from both my ship and camera with no luck.

Thanks so much for the help, hopefully talking this out with you guys will help clear things up.

Sponsor:

#2 Buckeye   Members   -  Reputation: 1189

Like
1Likes
Like

Posted 30 January 2011 - 11:27 AM

To get the effect of targeting a specific object under the cross-hair, do a pick (ray-object intersection test) for the cross-hair to determine if any targets are in the cross-hair. If there is an intersection, the intersection point in world-space is the target position.

If there are no intersections (i.e., the cross-hair is over "nothing"), the target position is the cross-hair ray intersection with the far wall of the frustum in world units.

The bullet's start position is then the gun position (either the eyepoint in first-person, or the ship's gun position if you're using the chase camera). The direction for the bullet is the direction vector target_position - gun_position. EDIT: you'll probably want to normalize that direction. Depends how you move the bullet.

Note: once the bullet is fired, it's position and direction is no longer a function of the ship's position/direction/etc. It's independent. You'll need to keep a separate structure of data for each bullet (it's current position, direction, speed, etc.)

EDIT: a side benefit of doing the pick is: if there's an intersection with an enemy target, you can "light up" the cross-hairs, indicating "target found" or similar.
Please don't PM me with questions. If you have a question, ask it here in the forums to benefit all!

#3 -XM-   Members   -  Reputation: 159

Like
0Likes
Like

Posted 30 January 2011 - 12:46 PM

To get the effect of targeting a specific object under the cross-hair, do a pick (ray-object intersection test) for the cross-hair to determine if any targets are in the cross-hair. If there is an intersection, the intersection point in world-space is the target position.

If there are no intersections (i.e., the cross-hair is over "nothing"), the target position is the cross-hair ray intersection with the far wall of the frustum in world units.

The bullet's start position is then the gun position (either the eyepoint in first-person, or the ship's gun position if you're using the chase camera). The direction for the bullet is the direction vector target_position - gun_position. EDIT: you'll probably want to normalize that direction. Depends how you move the bullet.

Note: once the bullet is fired, it's position and direction is no longer a function of the ship's position/direction/etc. It's independent. You'll need to keep a separate structure of data for each bullet (it's current position, direction, speed, etc.)

EDIT: a side benefit of doing the pick is: if there's an intersection with an enemy target, you can "light up" the cross-hairs, indicating "target found" or similar.


Thanks for the reply,

So if what I'm getting from your post is correct... the bullet will fire towards the enemy if there is an intersection with the ray coming from the nose of the ship, rather than the bullet just fireing straight ahead reguardless of any intersections? So, if there is an intersection with the ray, the crosshair will move towards the intersection point. But I'm not sure I understand what it will do if there is no intersection. Could you explain that part a bit more?

Also, should I be drawing my crosshair in 3D or 2D? I'm thinking 2D would be more ideal, but if that's so I guess I will need to somehow convert the 3D intersection point into a Vector2?

Thanks a lot.

#4 Buckeye   Members   -  Reputation: 1189

Like
1Likes
Like

Posted 30 January 2011 - 01:17 PM

So if what I'm getting from your post is correct... the bullet will fire towards the enemy if there is an intersection with the ray coming from the nose of the ship, rather than the bullet just fireing straight ahead reguardless of any intersections?

The ray doesn't come from the nose of the ship. The ray (in world-space) is a pick-ray from the screen position of the cross-hair (whereever in 2D screen position you have it). That ray is used only to determine if there's an enemy under the cross-hair, and, if there's an intersection, to determine where you want the bullet to go. Where the bullet (not the ray) comes from is the nose of the ship.

So, if there is an intersection with the ray, the crosshair will move towards the intersection point.

Not sure about "moving the crosshair." I'm assuming that, when you fire a bullet, it leaves the ship in some direction and continues without further guidance until it times out or hits something. So, I guess the answer is no. I assume you have the crosshair either constantly in the middle of the screen, or positioned by the mouse pointer. When you click to fire (or whatever you do), the crosshair screen position at that time is used to find a world position for bullet to go to.

But I'm not sure I understand what it will do if there is no intersection. Could you explain that part a bit more?

If there is no intersection, the bullet should go somewhere reasonable - either in the direction the ship is facing, or where the screen position unprojects to the back wall of the projection frustum. I don't know how you do the pick so that's pretty much the best I can do right now.

EDIT:

Also, should I be drawing my crosshair in 3D or 2D? I'm thinking 2D would be more ideal, but if that's so I guess I will need to somehow convert the 3D intersection point into a Vector2?

Probably in 2D, drawn directly to some screen position over everything else. Sounds like you need to google for "picking" or "unproject" or something similar. Picking or unprojecting a ray is the process of converting a 2D screen position to a 3D ray in space. You don't want a Vector2 (that's screen space) but a Vector3 - a direction in world-space. Then you use your world-space eye position and the ray to try intersecting objects in world-space.

Think of the crosshair as a line in space, from your eyepoint to infinity. You only see the "back" of the line as a single point. You need to determine where the "back" of that ray is in world space (you only have the 2D screen position), and in what direction in world space the ray is pointing.

EDIT2: http://msdn.microsoft.com/en-us/library/bb203905.aspx explains how to select objects under the mouse position. If your crosshair is constantly in the middle of the screen, use the screen coords for the middle of the screen for the "mouse position."
Please don't PM me with questions. If you have a question, ask it here in the forums to benefit all!

#5 -XM-   Members   -  Reputation: 159

Like
0Likes
Like

Posted 30 January 2011 - 02:07 PM

Ok, so the 3D ray will be cast from the 2D Crosshair's position. And to get the 3D coordinates I will "project', and to get 2D coordinates from 3D I will "unproject". This is making a lot more sense!

However, let me try to better explain the movement issue. The game is for Xbox, so the crosshair doesn't move with the mouse, I have it set up in the middle of the screen and if you start the game and fire a bullet, without moving the ship, it will go right in the middle of the crosshair. But when the player rotates the ship at all and fires, the bullet goes nowhere near the crosshair. Also, when the player accelerates the crosshair is way above the ship. The only thing I'm not understanding is how the crosshair is going to actually move to the correct position so I can perform the ray tests and what not.

I've uploaded a picture to better explain: http://i53.tinypic.com/2dtoi9v.png

The bullet is fireing from the nose of the ship and the ship is rotating to the right in that picture. Notice how it is totally off from the crosshair. So, from my understanding, if I can get the crosshair to move to the correct positions I can then perform the ray test we have talked about and go from there with the bullet directions, crosshair "light up" etc.

I was a little thrown off because at first I thought you were suggesting to move the crosshair position with the ray. Thanks for the clarifications. :)

Oh, and when you say the projection frustum would that be the same thing as my projection matrix?

EDIT: And I know the bullet's direction issue will be fixed with the ray, but if you take a look at the picture the ship is facing at an angle which is away from the crosshair, this is of course because of the chase camera. What I'm trying to say is that the ship is at such an angle that it doesn't look right with the crosshair, but if the bullets are going to fire towards the crosshair reguardless should I not even worry about moving the crosshair?

#6 -XM-   Members   -  Reputation: 159

Like
0Likes
Like

Posted 30 January 2011 - 03:46 PM

You know what, I don't know why I was so dead set on moving the crosshair.... what you said will work great without that!

Thanks a lot for your help, I will report back later this week with my results! :D

#7 Buckeye   Members   -  Reputation: 1189

Like
0Likes
Like

Posted 30 January 2011 - 03:59 PM

Ok, so the 3D ray will be cast from the 2D Crosshair's position. And to get the 3D coordinates I will "project', and to get 2D coordinates from 3D I will "unproject". This is making a lot more sense!

Sounds like you have the right idea, but, actually, you have the terms backwards. The screen is the projection. What's on the screen in 2D is "projected" from the 3D world. For picking, you start out with screen coordinates (projection space). So, to convert 2D to 3D coords, you unproject them. To convert 3D to 2D coords, you project them.

Maybe to help you remember which way is which: you start out with 3D coordinates for your world. Those are put through the projection matrix to view them in 2D.
Please don't PM me with questions. If you have a question, ask it here in the forums to benefit all!

#8 -XM-   Members   -  Reputation: 159

Like
0Likes
Like

Posted 05 February 2011 - 02:33 PM

Hey again Buckeye, I've implemented the code but am having some problems. Let me post my code and maybe you can spot a flaw:

EDIT: Removed code blocks, couldn't get them working right. Uploaded text file below, hopefully that is easier!

The enemyPostion vector was added because without it the enemy ship would begin changing positions all over the place when there was an intersection. (No idea what that's about!) The intersections are way off though, not sure where I went wrong but I'm guessing it's something simple I'm missing. I accidently was subtracting the HUD's direction and enemy's direction to get the new bullet's direction, which actually seemed to be working better than how I have it now for some reason.... :blink: I just changed it to their positions, which I believe is the correct formula based on your previous posts!

#9 -XM-   Members   -  Reputation: 159

Like
0Likes
Like

Posted 05 February 2011 - 02:38 PM

EDIT: Problem solved!



#10 Buckeye   Members   -  Reputation: 1189

Like
0Likes
Like

Posted 05 February 2011 - 03:45 PM

You have some code and some things "are way off" - you have a 2.5k file and ask someone to spot the flaw. Uh.. no thanks, for me, anyway.

I'd suggest doing things the other way 'round. You do some trouble-shooting and when you think you know where something may be going wrong, describe (in technical terms) what's happening and post some code.



Please don't PM me with questions. If you have a question, ask it here in the forums to benefit all!

#11 -XM-   Members   -  Reputation: 159

Like
0Likes
Like

Posted 05 February 2011 - 04:12 PM

You have some code and some things "are way off" - you have a 2.5k file and ask someone to spot the flaw. Uh.. no thanks, for me, anyway.

I'd suggest doing things the other way 'round. You do some trouble-shooting and when you think you know where something may be going wrong, describe (in technical terms) what's happening and post some code.


Well, I just figured that it would be an easy to spot error in the formulas I was using, which would result in the whacky things I'm seeing on screen. haha but I will definitely see what I can come up with!




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS