Search Unity

How do you do your fps gun-firing scripts?

Discussion in 'Scripting' started by Sargon_of_Akkad, Apr 4, 2011.

  1. Sargon_of_Akkad

    Sargon_of_Akkad

    Joined:
    Jan 16, 2011
    Posts:
    147
    Greetings all

    I'm having a conundrum with an fps firing script - instantiating the bullets works well, adding force to shoot them forward acts well and OnCollisionEnter acts...okay. But I can't help but feel I'm not doing it as well as possible.

    It seems that the collision detection in Unity is a bit lackluster. Is it a better idea to use raycasts for gunfire instead of flinging objects around? It'd probably work better for multiplayer, wouldn't it? What do you all think?
     
  2. 2dfxman1

    2dfxman1

    Joined:
    Oct 6, 2010
    Posts:
    1,065
    Use raycast, not real bullets.
     
  3. MADmarine

    MADmarine

    Joined:
    Aug 31, 2010
    Posts:
    627
    If you're firing bullets or high velocity projectiles I would definitely use ray-casting (if the projectile is pretty big perhaps sphere casting), collision detection can suffer from a lot of issues when things are moving so fast, not to mention it's kind of wasteful in this kind of situation. You can pretty much assume that unless you're firing over really long distances, a bullet is going to go where you're aiming your crosshair and it's going to do it near enough instantly, so a ray-cast makes more sense.
     
    Last edited: Apr 4, 2011
  4. Sargon_of_Akkad

    Sargon_of_Akkad

    Joined:
    Jan 16, 2011
    Posts:
    147
    I've been leaning towards this of late given how unreliable Unity's collision detection has been in my testing - thanks for the advice all!
     
  5. Satoh

    Satoh

    Joined:
    Feb 17, 2011
    Posts:
    56
    "Unreliable" is a bit incorrect. When you "move" an object from point A toward point G, it does not necessarily pass through B, C, D, E, or F.

    Objects in games do not actually "travel" but rather, they teleport to points in between then start and end point. The faster it needs to move, the less in-between points the object will teleport to. For instance, if your speed is 1, your object will pass through A, B, C, D, E, and stop at F. If the speed is 2, it will only pass through A, C, E, and stop at F. A computer cannot efficiently calculate all of the data of the object being at every point between A and G within the amount of time you need it to, so instead, it only takes snapshots of where the object would be along the path, at the time the game is updated next.

    Cartoons are a perfect example of this. In order for a man to move his arm from his hip to his head over exactly one second, the artist must draw (depending on desired frame-rate) 24-30 pictures of the arm being in different places, rather than the infinite number of places that the eye can't even see, in between the hip and the head.

    The game engine is the same way, it only calculates the data from certain points along the path.

    To get right to the point, the object collision doesn't always register because the object itself may not have actually collided at all, due to the point of collision being between the points where the object actually passed through on it's way toward whatever point it was moving to.

    Does that make sense?
     
  6. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,071
    Either way, the issue is easily solved with the DontGoThroughThings script on the wiki. I have very little issues with performance with 8-10 units shooting 10 rounds per second with rigidbody projectiles with tracer trailrenderers and sparks emitting upon collision, and the collisions appear to be 100% accurate. I'm still thinking of switching to raycasting just because the performance hit from adding rigidbodies does not scale linearly, and I'm not sure how much I'd like to expand the game.

    The only reason I still stick with them is because I love tracers, and I can't come up with a solution for tracers with raycasting that I like.

    I tried raycasting to get the hit point, instantiating an empty gameobject with my tracer trailrenderer and lerping it to the hit point and destroying it when it gets there, then emitting the hit particles at the point, but it gets weird when you're shooting a moving target (the raycast hit the enemy, but the enemy moved before the tracer got to the hit point, so blood spurts of of thin air).