Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

I need help about bullet drop.

Discussion in 'Scripting' started by Dolke, Aug 8, 2018.

  1. Dolke

    Dolke

    Joined:
    Dec 16, 2016
    Posts:
    39
    Hello all :)

    I started making gun,and shooting just for testing and to learn unity and programming more, but I have one problem.

    I wanted to make a bullet drop for my gun,and I wanted to make it like little parabola,and bullet (object) needs to go like that parabola (Like parabola is some kind of imagined line and bullet follows that line).
     
  2. Scabbage

    Scabbage

    Joined:
    Dec 11, 2014
    Posts:
    268
    Since it's a predefined and simple path, a rigidbody with continuous collision would probably be overkill. Starting from some point and velocity, the parabola can be computed like so:
    Code (csharp):
    1.  // Returns an array of points following a parabolic trajectory
    2. public static Vector3[] BulletTrajectory (int iterations, Vector3 startPoint, Vector3 velocity, float timeStep)
    3. {
    4.     Vector3[] points = new Vector3[iterations];
    5.     points[0] = startPoint;
    6.     for(int ii = 1; ii < points.Length; ii++)
    7.     {
    8.         points[ii] = points[ii-1] + velocity * timestep;
    9.         velocity.y -= 9.81f * timestep; // simulate gravitational acceleration
    10.     }
    11.     return points;
    12. }
    If you want collision you will need to loop through the points from the start and use Physics.Raycast to the next point. You could also create a modified raycast function like this:
    Code (csharp):
    1.  // Returns true if bullet hit something, and gives the raycasthit info if so
    2.     public static bool BulletRaycast (Vector3 startPoint, Vector3 velocity, out RaycastHit hit, int iterations = 100, float timeStep = 0.01f)
    3.     {
    4.         for(int ii = 1; ii < iterations; ii++)
    5.         {
    6.             Debug.DrawLine (startPoint, startPoint + velocity * timeStep);
    7.             startPoint += velocity * timeStep;
    8.             // Detect collision
    9.             if(Physics.Raycast(startPoint, velocity, out hit, velocity.magnitude * timeStep))
    10.             {
    11.                 return true;
    12.             }
    13.             velocity.y -= 9.81f * timeStep; // simulate gravitational acceleration
    14.         }
    15.         hit = new RaycastHit ();
    16.         return false;
    17.     }
    That can be used just like Physics.Raycast, but it will have a curved parabolic trajectory instead of a straight line. Hopefully that helps you get started.
     
  3. Dolke

    Dolke

    Joined:
    Dec 16, 2016
    Posts:
    39
    Im sorry but I do not understand the code very well.

    Could you explain to me a little bit,and how I can use it ?
     
  4. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Just from a quick read of the code.... The first one just returns an array of points you could use to draw a parabola and deal with those points however you like in your own code.

    The second one is implemented similarly to the first, but does a raycast from each point toward the next point, and returns true if the bullet hit something, with "hit" giving information of what the bullet struck. This is the one that is more likely to be just dropped in your code and used as is, while the first is the best if you're going to implement your own logic around how to detect bullet impacts or if you want to create some special effect along the bullet path.

    In both you would adjust iterations, timeStep, and velocity to control how many points you want in the parabola, how fast you want the bullet to drop, and what direction and speed you want the bullet to be moving.
     
  5. PVisser

    PVisser

    Joined:
    Apr 24, 2014
    Posts:
    61
    Wouldn't the simplest solution be to just like.. add gravity to it (the bullet rigidbody)? I assume you have the firing and speed of the bullets already set up so add a bit of gravity and it should get a 'natural' bullet drop effect right?

    *oops just read the parabola thing so never mind my advice.
     
    Last edited: Aug 9, 2018
  6. Scabbage

    Scabbage

    Joined:
    Dec 11, 2014
    Posts:
    268
    Joe was pretty spot on. Both take a start position, which is where the bullet starts, as well as a velocity, which is the initial speed and direction of the bullet.

    The second method will raycast along a parabolic trajectory until it hits something. If it does, the method returns true and information about that hit will be stored in the "hit" parameter.

    changing the timeStep variable in that example code will cause the points to be more/less accurate to a true parabola, and the iterations parameter is the maximum number of steps that the method can simulate if the bullet never hits anything.

    A rigidbody will follow a parabolic trajectory if it has 0 drag, but a small rigidbody travelling very fast requires a more expensive continuous collision mode enabled, otherwise it can clip through thin colliders. (the "bullet through paper problem"). Personally I use raycasting because it's way cheaper and you can customise it more.
     
  7. Dolke

    Dolke

    Joined:
    Dec 16, 2016
    Posts:
    39
    Im sorry but Im so stupid.

    How can I use "BulletTrajectory" function to move bullet object,with transform or somehow different?

    And can this function be used,or somehow manipulated to make zeroing for rifle?
     
  8. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    The BulletTrajectory function just gives you an array of points, so if you wanted to move a bullet object along that path over time you would place the bullet at the first point, and use any of the movement methods to move in the direction of the next point. (In the simplest form, use transform.lookat to point the bullet at the next point and then transform.translate forward or add forward velocity to a rigidbody. When the bullet gets close to the target point you switch to the next point in the array).

    BulletTrajectory doesn't include hit detection though, so you'd either want to move along that path slow enough to use the cheapest form of physics collision detection, or move fast enough along the path that another object is unlikely to obstruct the path so you could use a result from BulletRaycast to mark the impact. If you want to move too fast for cheap collision detection but slow enough that an initial result from BulletRaycast can't be trusted to not be obstructed by another object by the time the bullet gets there, then you'll want to come up with a solution where you are raycasting ahead of the bullet as it travels down the parabola instead of doing all your raycasting when initially firing the bullet.

    You should easily be able to use the BulletRaycast function to show instantly where a bullet would be predicted to impact for something like adjusting zero. You could mark that visually using the collision info in "hit" to get the specific location of the impact.