TDK,
About shooting bullets, I only use raycasting as "the bullet". That is, unless the object needs to be seen, like a grenade thrown or some other bulky weapon form.
Since bullets fired from a pistol or other highspeed weapon, move so fast, there is no need to see them. Therefore, no need to use an object in its place. Also, in the size of any game arena, to the extent of largescale outside environments, you could say that a buller virtually reaches its destination, once shot, in the next frame of the game. However, this timing is easily adjustable, by the distance you set a raycast to check in one frame.
I am not sure if you have used any type of raycasting or not, but I will try to simply explain. There are technically only three major necessities in raycasting. A start point, an end point(bullet travel distance) and the angle the bullet is traveling. You can literally name a casted ray, a vector. That, several points are checked on this line, from its start to its end, the distance between each point checked, defined by the programmer and how accurate he wishes the check to be. The more accurate though, the more processing power needed, unfortunately.
In Psuedo order, when the user presses the "fire" button, first a few values should be recorded. The player's position, angle(for an fps, two angles would need to be recorded of two axies), and the distance the bullet can ultimately travel. In the example below, I simply record only one angle, the y axis angle, only enabling the bullet to fly on a horizontal plain.
Example:
if mouseclick() = 1 and weaponready = 1
bulletxpos# = playerxpos#
bulletypos# = playerypos#
bulletzpos# = playerzpos#
bulletyangle# = playeryangle#
REM << this variable is used to place a time gap in between each bullet shot
weaponready = 0
endif
Now we have recorded all the necessary values to create the raycasting. If one can move an object in 3D space, using newvalues or cos and sin, then he can also create a casted ray. Raycasting is literally like moving an object from one point to the other, at step values, from a beginning point to a specified ending point. However, with only using coordinate values and not an object(unless necessary for collision checking), and all in one program loop. The movement is completed some finite loop, which is nested inside the program loop. Therefore, every point can be checked for collision in the blink of an eye.
Now, to check specified points(evenly spaced points) from start to finnish on this line. Let us say we will use the code above, and the bullet can travel 200 units max. Therefore, 0 is our start point, and 200 is our end unit. The last position checked by the ray will be 200 units away from the player, in the direction recorded. In the example below, we use an accuracy of 1 unit space gap checking. Therefore, the distance of the check will be incremented by one every raycast loop.
Example:
if weaponready = 0
repeat
inc checkdistance
inc bulletxpos#,cos(bulletyangle#) * checkdistance
inc bulletypos#,sin(bulletyangle#) * checkdistance
REM << the line below represents the checking for the current point with any other objects
checkcollision(bulletxpos#,bulletzpos#)
REM << raycasting loop will end when the very last point on the line is checked
until checkdistance = 200
endif
This is the very basics, that you might already know. However, when I have some more time, I will go into more detail. Getting into the subjects of delay in firing, rapid fire, single fire, sounds, ammo decrementing, etc. Hope this will get you somewhere for now.

+NanoBrain+