Help: Effect of Gravity on Raycast Projectiles

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.

public class Bullet : MonoBehaviour {

	public float velocity = 300.0f;
	public float maxDist = 10000.0f;
	public bool showTrail = true;
	public GameObject hitDecal;
	
	private float _wallDisplacement = 0.001f;
	private RaycastHit hit;
	private Vector3 startPosition;	
	private Vector3 endPosition;
	private Vector3 direction;
	private float distance;
	private float distTraveled;
	private float gravity = 9.8f;
	private float y = 0.0f;
	
	void Start ()
	{
		startPosition = transform.position;
		distTraveled = 0.0f;
	}
	
	void FixedUpdate ()
	{
		if (distTraveled <= maxDist)
		{
			direction = transform.TransformDirection(new Vector3(0, y * Time.deltaTime, 1));
			distance = velocity * Time.fixedDeltaTime;
			
			if (Physics.Raycast(startPosition, direction, out hit, distance))
			{	
				if (hitDecal  hit.transform.tag == "levelParts") {
					Instantiate(hitDecal, hit.point + (hit.normal * _wallDisplacement), Quaternion.LookRotation(hit.normal));
					Destroy (gameObject);
				}
			}
			y -= gravity * Time.deltaTime;
			endPosition = startPosition + direction * distance;
			
			if (showTrail)
				Debug.DrawLine(startPosition, endPosition, Color.green, 3.0f);
			
			distTraveled += Vector3.Distance(startPosition, endPosition);
			startPosition = endPosition;
		}
		else
			Destroy (gameObject);
	}
}

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.

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.

Can’t you just calculate the bezier curve of the bullet and than raycast from start to the right end point? Here is some information about how bezier works: Curves and Splines, a Unity C# Tutorial

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);

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.

Belatedly I realize: Infini_Games nekro’d this from 2012 - why?

1 Like