How can I make bullets in a first person shooter look like they come from the gun, but actually come from the eyes of the character? The problem is that since the camera (the character's eyes) are in a different position than the gun, bullet animations coming from the gun won't end up at the crosshairs. This guy manages to do it, and it's more obvious at 5:17 when the bot is shooting at him. This also happens in CS:GO

I was thinking that maybe the final destination of the bullet is calculated, and then the path is traced backwards to the gun from there, but it's just a guess.

  • \$\begingroup\$ Offset to guns position? Find the delta between camera and gun and add it to bullet for its initial position? \$\endgroup\$ – ChaoSXDemon Aug 27 '17 at 20:31

The reason that bullets coming from the gun don't work with the cross hair is because the cross hair represents where the bullet would go at an infinite distance.

You can't make the bullet look like it comes from the gun but actually come from the eyes without causing some problems. Specifically, where the bullet looks like it's going and where it hits won't be the same place.

The Problem

Here's a set of illustrations that show how/why I say this...

Lower gun aim

First, this is a representation of a player shooting from the hip. The red dot represents where the cross hair aim point. The horizontal green line is the view from eye to aim point (through cross hair). The red line coming from the gun is the actual bullet travel line.

enter image description here

Here is the same setup if the shooter is holding the gun up (iron sights). This is what's happening in the example you reference in the video at 5:17.

Now let's go back to the first case, but add a target that's in front of the player, and fairly close.

enter image description here

You can see now how where the cross hair looks like it's targeting and where the shot hits isn't the same. And that's a problem, because it might actually mean a miss if the hit boxes are more complex, or if you are rendering a hit decal at the impact point. Either the player shoots at what looks like a perfect target and misses, or the player shoots and hits, but the hit indicator isn't where they shot.

But of course if they are holding the gun up to their eyes (iron sights), it's just fine...

enter image description here

The Solution

First, here's the problem we want to solve. We want to hit the spot that the cross hair is on, like this...

enter image description here

The first thing you need to do is calculate where the point is that your eye is on the target. In other words, calculate where the line drawn from eye to aim spot (cross hair) would hit.

Once you have this point, there are two things you should do.

First, when you draw the streak of the bullet, draw it from the tip of the gun to this newly calculated point...

enter image description here

It's not super clear in my illustrations, but the problem is though your gun isn't quite pointing the same way as the shot. And the closer the target is to you, the worse it will be. So the second thing to do is rotate the first person gun model up a bit so it's pointing at the impact point, like this...

enter image description here

And now, everything is all good!

It might look a little bit off if the target were literally right in front of the player - like if they were face into a wall. You can actually fix this by having the player lift the gun up more as the target gets closer, so the rotation is less.

Alternate Solution If the gun has a laser sight, then you will always be calculating that point where the laser (coming from the gun) illuminates the target. When the player shoots, the bullet hits where the laser sight is. It is maybe a little disconcerting that the cross hair and the laser illumination dot aren't in the same spot, but it does help a bit.


You just need to use basic geometry.

If you know the distance to the target and you know the distance between your character's eyes and, for example, weapon's muzzle, you simply apply Pytagorean Theorem and get the distance from the two points (muzzle and target).

Then you get direction vector doing

Vec3 direction = (targetPosition - muzzlePosition).normalized()

Now you can spawn a bullet in the position of the muzzle with that direction vector.

You can calculate whether bullet would hit or not by raycasting from eye's position and how much time bullet would need to get from muzzle to target by using the formula

Time = distance ÷ speed

Having that time you can play around with bullet spawning, special effects, sound, etc.

Hope it helps. Update the question and comment if there's anything else or unclear.


Your Answer

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