Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Help: Effect of Gravity on Raycast Projectiles

Discussion in 'Scripting' started by ChinoNino, Sep 18, 2012.

  1. ChinoNino

    ChinoNino

    Joined:
    Jul 22, 2012
    Posts:
    8
    Can someone tell me if I'm implementing the gravity correctly. I have written a bullet script that uses multiple raycasts to simulate the trajectory where I change the direction of the raycast after a certain distance has been traveled. The problem I'm having is I am unsure if the way I simulate gravity is done correctly. Sorry if this might seem amateurish I'm quiet new to Unity.

    Code (csharp):
    1. public class Bullet : MonoBehaviour {
    2.  
    3.     public float velocity = 300.0f;
    4.     public float maxDist = 10000.0f;
    5.     public bool showTrail = true;
    6.     public GameObject hitDecal;
    7.    
    8.     private float _wallDisplacement = 0.001f;
    9.     private RaycastHit hit;
    10.     private Vector3 startPosition; 
    11.     private Vector3 endPosition;
    12.     private Vector3 direction;
    13.     private float distance;
    14.     private float distTraveled;
    15.     private float gravity = 9.8f;
    16.     private float y = 0.0f;
    17.    
    18.     void Start ()
    19.     {
    20.         startPosition = transform.position;
    21.         distTraveled = 0.0f;
    22.     }
    23.    
    24.     void FixedUpdate ()
    25.     {
    26.         if (distTraveled <= maxDist)
    27.         {
    28.             direction = transform.TransformDirection(new Vector3(0, y * Time.deltaTime, 1));
    29.             distance = velocity * Time.fixedDeltaTime;
    30.            
    31.             if (Physics.Raycast(startPosition, direction, out hit, distance))
    32.             {  
    33.                 if (hitDecal  hit.transform.tag == "levelParts") {
    34.                     Instantiate(hitDecal, hit.point + (hit.normal * _wallDisplacement), Quaternion.LookRotation(hit.normal));
    35.                     Destroy (gameObject);
    36.                 }
    37.             }
    38.             y -= gravity * Time.deltaTime;
    39.             endPosition = startPosition + direction * distance;
    40.            
    41.             if (showTrail)
    42.                 Debug.DrawLine(startPosition, endPosition, Color.green, 3.0f);
    43.            
    44.             distTraveled += Vector3.Distance(startPosition, endPosition);
    45.             startPosition = endPosition;
    46.         }
    47.         else
    48.             Destroy (gameObject);
    49.     }
    50. }
     
  2. ChrisBannoura

    ChrisBannoura

    Joined:
    Feb 19, 2018
    Posts:
    21
    When you shoot a raycast, it instantly travels from point A to point B. It takes 1 frame and you cant stop or change it. My opinion is, you cant do it. It's just not possible.
     
  3. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    I'm not sure if Inifini_Games correctly interpreted your question, as you are using the 'distance' Parameter to Limit the raycast and that is a coorect way to see if the bullet hits something in the intervening space.

    Your code looks correct except for the way you calculate the downward pull. Gravity accelerates constantly, increasing the downward velocity (you currently apply a constant velocity to y), while Forward velocity remains the same (you may even go fancy and decrease forward velocity to simulate drag).

    So, the forward velocity is constant, while the downward velocity should start with 0 and then increase constantly by gravity * Time.deltaTime.
     
  4. WheresMommy

    WheresMommy

    Joined:
    Oct 4, 2012
    Posts:
    890
  5. dontdiedevelop

    dontdiedevelop

    Joined:
    Sep 18, 2018
    Posts:
    68
    just calculate gravity to distance and add it to end position's y

    something like this;
    float offset = distance * mass * gravity;
    endPosition = endPosition + (Vector3.down * offset);
     
  6. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    What? Why mass? What are you calculating?

    Downward velocity will increase each Update:
    myDownwardVelocity += gravity * Time.deltaTime;

    Now change y
    y -= myDownwardVelocity * Time.deltaTime;

    This is all based on

    1) distance = time * velocity // usually constant velocity, but can be used in short distances for Approximation when used with constant acceleration, provided the time slice is small enough. I thinkt that was how they discovered Integral calculus...

    2) velocity = time * acceleration // constant acceleration, for downward Speed, which uses 1) to calculate the y deflection downwards for this time slice. Approximation.

    Note: the correct formula for distance on constant acceleration is dist = accel * time * time / 2, but IIRC that's only true when we start with speed = 0. Apologies, but it's been over 30 years since I left high school, getting rusty.

    There's no mass involved unless you are looking into Impulses or force.
     
    Last edited: May 7, 2019
  7. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    Belatedly I realize: Infini_Games nekro'd this from 2012 - why?
     
    WheresMommy likes this.