Announcement

Collapse
No announcement yet.

Line tracing VS Projectile bullets (for bullet drop)

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Line tracing VS Projectile bullets (for bullet drop)

    I made a post earlier asking about how to implement projectile based shooting with bullet drop (https://forums.unrealengine.com/development-discussion/blueprint-visual-scripting/1525645-how-do-i-implement-projectile-based-fps-shooting-the-right-way) but after I posted it I started to wonder if you could simulate bullet drop with line tracing since projectile based shooting is more performance heavy. But how much more performance heavy is it compared to line tracing? Is it worth the performance sacrifice (I plan to use full-auto weapons)?

    I heard a rumor that projectile bullets can't detect collisions/hits if their velocity is too high. Is that true? I don't want my shooting system to be unreliable/inconsistent. Is there a way to solve this?

    So far I have 3 different methods for implementing bullet drop:
    1. Shoot a straight line trace and then calculate the how far down from the hit point the ACTUAL hit point needs to be when taking bullet drop into account. I calculate this downwards vector with the help of the distance of the line trace and an artificial "bullet speed" value. After that I fire a second line trace which will be the actual bullet hit and this line trace ends in the calculated bullet drop hit point. Looks something like this: https://forum.unity.com/attachments/...38-png.171212/
    2. Create a line trace arc by using multiple short line traces (not sure how to do that exactly yet).
    3. Just use projectiles and let the physics do it's job.

    Is there a difference in performance between Method 2 and 3? What are the pros and cons of each method and why?

    Here I go rambling again... sorry. Bottom line is I want to know the pros and cons of simulating bullet drop with line traces vs projectiles and know which method is most common among FPS games with bullet drop. Sorry for sounding like a broken record considering I've already posted a similar question.

    Let's discuss!

    #2
    Depending if you want to make totally custom implementation, use projectile movement or a mix of the two depends pretty heavily how many projectiles there can exists at any given point. Less than 50 you should be perfectly fine using projectile movement component.
    Anything over 100 projectile actors starts eating performance depending how many other actors there is active.
    Before linetracing you want to find where the new location would be and trace to that point. Then it works wonderfully.

    Currently I have a completely custom ballistics code which can handle up to 6000 projectiles with realistic drag, penetration and ricochets so it's just up for the setup what you really need.

    Comment


      #3
      Originally posted by IhanaMies View Post
      Depending if you want to make totally custom implementation, use projectile movement or a mix of the two depends pretty heavily how many projectiles there can exists at any given point. Less than 50 you should be perfectly fine using projectile movement component.
      Anything over 100 projectile actors starts eating performance depending how many other actors there is active.
      Before linetracing you want to find where the new location would be and trace to that point. Then it works wonderfully.

      Currently I have a completely custom ballistics code which can handle up to 6000 projectiles with realistic drag, penetration and ricochets so it's just up for the setup what you really need.
      But is the second method that I listed heavier or lighter than the third method (projectiles) in terms of performance? Also, does your custom ballistics code use the third method or the second?

      EDIT: I discovered this node: https://api.unrealengine.com/INT/Blu...yp-/index.html that basically simulates bullet drop (predicts projectile path) for you automatically. It seems to good too be true. Is there a downside to using this node as a solution? Is it heavy on performance?
      Last edited by Schytheron; 09-11-2018, 04:41 PM.

      Comment


        #4
        That is pretty interesting - in looking at source it uses "(Velocity Verlet method)" to integrate.

        In terms of performance - it does a line trace for every step (based on the frequency).

        while (CurrentTime < MaxSimTime)
        {
        ...
        bObjectHit = World->SweepSingleByObjectType(ObjectTraceHit, TraceStart, TraceEnd, FQuat::Identity, ObjQueryParams, FCollisionShape::MakeSphere(ProjectileRadius), QueryParams);
        https://www.casualdistractiongames.com

        Comment


          #5
          Originally posted by Schytheron View Post
          But is the second method that I listed heavier or lighter than the third method (projectiles) in terms of performance? Also, does your custom ballistics code use the third method or the second?
          Heavier for sure. I'm using the first method, kinda. I calculate protrusion and drop first, then trace to that point. So far I haven't had to substep.

          Originally posted by Schytheron View Post
          EDIT: I discovered this node: https://api.unrealengine.com/INT/Blu...yp-/index.html that basically simulates bullet drop (predicts projectile path) for you automatically. It seems to good too be true. Is there a downside to using this node as a solution? Is it heavy on performance?
          Can't tell. I haven't used that note myself. Best way to find out is by testing and comparing!

          Comment


            #6
            Originally posted by OptimisticMonkey View Post
            That is pretty interesting - in looking at source it uses "(Velocity Verlet method)" to integrate.

            In terms of performance - it does a line trace for every step (based on the frequency).

            while (CurrentTime < MaxSimTime)
            {
            ...
            bObjectHit = World->SweepSingleByObjectType(ObjectTraceHit, TraceStart, TraceEnd, FQuat::Identity, ObjQueryParams, FCollisionShape::MakeSphere(ProjectileRadius), QueryParams);
            So are you saying that is basically doing the same thing as Method 2 that I listed? Or at least similar in performance.

            Btw, what is a good way to find the C++ function equivalent of a Blueprint node? I have been trying to use Google and Unreals C++ API but I can't find documentation on the C++ function of the "Predict Projectile Path" node

            Comment


              #7
              Originally posted by IhanaMies View Post
              Heavier for sure. I'm using the first method, kinda. I calculate protrusion and drop first, then trace to that point. So far I haven't had to substep.
              I have heard people say that projectile movement is lighter on performance compared to line tracing an arc but I just don't understand how that is possible. I mean when you shoot a projectile you are doing physics calculations on it every frame + for fast moving projectiles you still have to do a lot of line tracing because fast projectiles can fly through objects between frames + you are spawning and destroying actors very quickly when shooting.

              How is that less demanding than simply doing a bunch of line traces in an arc? I mean as far as I know line tracing is pretty cheap on performance.

              Don't take it the wrong way. I am not saying you're wrong. I am just interested in an explanation because it makes no sense to me.

              EDIT: How accurate is your method (method 1)? I have a feeling that the first method isn't as accurate as the others considering that a real bullet doesn't fly in a straight line with constant speed. The trace should be curved. Is the inaccuracy noticeable or have you encountered any problems with using that method (I am assuming that the first method is the lightest out of all of them)?
              Last edited by Schytheron; 09-12-2018, 07:46 AM.

              Comment


                #8
                Originally posted by Schytheron View Post

                How is that less demanding than simply doing a bunch of line traces in an arc? I mean as far as I know line tracing is pretty cheap on performance.
                Don't take it the wrong way. I am not saying you're wrong. I am just interested in an explanation because it makes no sense to me.
                So I have custom struct which defines the projectile (since what it really is is just a point in space) holding velocity, location, rotation and so on.
                On tick I calculate how far it can travel and use the as a linetrace end point. So just one linetrace per projectile per tick.

                Originally posted by Schytheron View Post

                EDIT: How accurate is your method (method 1)? I have a feeling that the first method isn't as accurate as the others considering that a real bullet doesn't fly in a straight line with constant speed. The trace should be curved. Is the inaccuracy noticeable or have you encountered any problems with using that method (I am assuming that the first method is the lightest out of all of them)?
                It is very accurate. I've had no problems detecting any kind of hits.

                Comment


                  #9
                  Originally posted by IhanaMies View Post
                  So I have custom struct which defines the projectile (since what it really is is just a point in space) holding velocity, location, rotation and so on.
                  On tick I calculate how far it can travel and use the as a linetrace end point. So just one linetrace per projectile per tick.
                  Sounds to me like you are describing method 2 here. This would create a line trace arc in the end right? I might have described Method 3 poorly. In Method 3 I meant that you would spawn the projectile as a literal BP actor that has the "ProjectileMovement" component attached to it (like how the FPS template does it). So you would let the physics handle all of the calculations.

                  In psuedo code your method would look something like this (per tick):
                  1. Do straight line trace with X distance (where X is the distance the bullet would have traveled in one frame with its current velocity).
                  2. bulletPos = traceEndPos
                  3. velocity += (0,0,-982)*DeltaTime
                  4. Do new line trace. TraceStart = bulletPos. TraceEnd = bulletPos+velocity*DeltaTime
                  5. bulletPos = NewTraceEndPos
                  6. Repeat step 3-4 (if the line trace doesn't hit anything)
                  Have I understood this correctly?


                  Comment


                    #10
                    Easiest way to search source is to simply create c++ project. (Make sure to check Engine Source option in the Options menu from the launcher - use yellow drop down button on installed engine button)

                    UE creates a Visual Studio Solution Workspace for your game that includes the entire engine as sub-project in that solution.

                    After waiting an eternity for indexing, you can use visual studio to browse workspace. You can even right-click in BP editor and choose Go To Definition or double-click node. If it is c++ based it will open visual studio.

                    Another option is to download engine from github - or even search it on github.
                    https://www.casualdistractiongames.com

                    Comment


                      #11
                      Originally posted by OptimisticMonkey View Post
                      Easiest way to search source is to simply create c++ project. (Make sure to check Engine Source option in the Options menu from the launcher - use yellow drop down button on installed engine button)

                      UE creates a Visual Studio Solution Workspace for your game that includes the entire engine as sub-project in that solution.

                      After waiting an eternity for indexing, you can use visual studio to browse workspace. You can even right-click in BP editor and choose Go To Definition or double-click node. If it is c++ based it will open visual studio.

                      Another option is to download engine from github - or even search it on github.
                      Thanks man! That's really helpful.

                      Comment


                        #12
                        Originally posted by Schytheron View Post

                        Sounds to me like you are describing method 2 here. This would create a line trace arc in the end right? I might have described Method 3 poorly. In Method 3 I meant that you would spawn the projectile as a literal BP actor that has the "ProjectileMovement" component attached to it (like how the FPS template does it). So you would let the physics handle all of the calculations.

                        In psuedo code your method would look something like this (per tick):
                        1. Do straight line trace with X distance (where X is the distance the bullet would have traveled in one frame with its current velocity).
                        2. bulletPos = traceEndPos
                        3. velocity += (0,0,-982)*DeltaTime
                        4. Do new line trace. TraceStart = bulletPos. TraceEnd = bulletPos+velocity*DeltaTime
                        5. bulletPos = NewTraceEndPos
                        6. Repeat step 3-4 (if the line trace doesn't hit anything)
                        Have I understood this correctly?

                        More like this:
                        1. TickTravelDistance = velocity*DeltaTime
                        2. Line trace. TraceStart = bulletPos. TraceEnd = bulletPos+TickTravelDistance-Gravity
                        3. bulletPos = NewTraceEndPos
                        4. No repeats.
                        To clarify. No repeats needed since Tick function is the repeater :P
                        Last edited by IhanaMies; 09-12-2018, 10:47 AM.

                        Comment


                          #13
                          Originally posted by IhanaMies View Post

                          More like this:
                          1. TickTravelDistance = velocity*DeltaTime
                          2. Line trace. TraceStart = bulletPos. TraceEnd = bulletPos+TickTravelDistance-Gravity
                          3. bulletPos = NewTraceEndPos
                          4. No repeats.
                          To clarify. No repeats needed since Tick function is the repeater :P
                          Yeah yeah of course. My bad. What I meant by step 6 was that you repeat it in the next tick. Should have made that clearer.

                          I think you forgot to update the velocity value in your solution. Shouldn't it be like this?:
                          1. TickTravelDistance = velocity*DeltaTime
                          2. velocity = velocity - gravity
                          3. Line trace. TraceStart = bulletPos. TraceEnd = bulletPos+TickTravelDistance
                          4. bulletPos = NewTraceEndPos
                          5. No repeats.

                          Comment


                            #14
                            Originally posted by OptimisticMonkey View Post
                            Easiest way to search source is to simply create c++ project. (Make sure to check Engine Source option in the Options menu from the launcher - use yellow drop down button on installed engine button)

                            UE creates a Visual Studio Solution Workspace for your game that includes the entire engine as sub-project in that solution.

                            After waiting an eternity for indexing, you can use visual studio to browse workspace. You can even right-click in BP editor and choose Go To Definition or double-click node. If it is c++ based it will open visual studio.

                            Another option is to download engine from github - or even search it on github.
                            This is strange. I tried making a new C++ project, made a dummy blueprint, opened it and added a node. When I right click on the node and click on "Goto definition" nothing happens. A little window pops up in the bottom right corner that says "Reading C++ Symbols" and then nothing happens. I open my Visual Studio window and it hasn't opened up any .h or .cpp files.

                            Is this normal?

                            Comment

                            Working...
                            X