Projectile shot calculations

Let me explain it to you:

This website here demonstrates finding the math.cos and math.sin of an angle.

as you can see, the math.sin() represents the y increase if you moved in a 2-dimensional direction of theta (the angle) and the same for math.cos. Now, notice of the radius of that circle is ALWAYS 1. Since we know that 1 times any number is always going to be that number, if we just multiply the vx and vy values by speed you’ll increase the size of that circle, and move farther.

These are just simple trigonomic functions. Understanding math.sin() and math.cos() is crucial to any spatial related programming.

Now, all we have to do to implement gravity, is over time, change that angle of movement. There are two ways you can do this, first, the method I used by just subtracting of off the vx and vy, or two, subtracting of the ORIGINAL angle, and from there finding the math.cos() and math.sin() of that angle.

Example:

if (math.pi/2) < angle and angle < (3*math.pi/2) then
  angle += math.pi /180 -- one degree
else if (math.pi/2) > angle or (3*math.pi.2) < angle then
  angle -= math.pi/180 -- one degree
end

What this script does, is checks if the current moving angle is greater than 90 degrees and less than 270 degrees (moving down), then it adds a degree to the movement of the angle. Else, if it’s less than 90 degrees, OR greater than 270 degrees, it subtracts a degree from the angle.

1 Like

The projectile (in this case the Part) when I shoot, it appears, possibly it is setting an unwanted position

function fire(angle, distancearc, g)
	local vx = math.sin(angle)
	local vy = math.cos(angle)
	local part = Instance.new("Part")
	part.Anchored = true
	part.Size = Vector3.new(5,5,5)

	local speed = 3 -- let's say three for now.

	while distancearc > 0 do
		distancearc -= 1
		part.Position += Vector3.new(vx * speed,0,0)
		part.Position += Vector3.new(0,vy * speed,0)

		vx -= (1-g)*vx*2
		vy -= (1-g)*vy*2
		print(part.Position)
		wait(0.14)
	end
end

I’ll take a look at that when I’m done. thank you very much for the explanation

This code wasn’t mean’t to handle 3 dimensional gravitation pull.

I suggest creating your own formula like this one, but for your script, since I don’t know how your script is setup.

Oh, this is going to be impossible for me, because I don’t know anything about it :smiling_face_with_tear:
Thank you anyway

function fire(angle, distancearc, g)
	local vx = math.sin(angle)
	local vy = math.cos(angle)
	local part = Instance.new("Part")
	part.Anchored = true
	part.Size = Vector3.new(5,5,5)

	local speed = 3 -- let's say three for now.

	while distancearc > 0 do
		distancearc -= 1
		part.Position += Vector3.new(vx,vy,0)

                if (math.pi/2) < angle and angle < (3*math.pi/2) then
                  angle += math.pi /180 -- one degree
                else if (math.pi/2) > angle or (3*math.pi.2) < angle then
                  angle -= math.pi/180 -- one degree
                end

		vx -= math.cos(angle) * speed
		vy -= math.sin(angle) * speed

		wait(0.14)
	end
end

Consider using this instead :slight_smile:

1 Like

is this in a 2d space?
I don’t know, if it is, I tested it and it was a little wrong xd

yes, this is for 2d.

I can’t currently think of way to do the same thing but for 3d but i’m pretty sure it’s the same thing.

And yes it’ll be a little wrong because it won’t be moving on the z-axis :confused:

2 Likes

oh ok, last thing. What is this calculation called? I’ll try to move to 3D as my “great skills”, and I’ll see your explanation in Reply above.

and small mistake here I think:
image
math.pi.2

Ooh goodie a question I can answer.

A very easy function I used is here

function getPredictedPosition(targetPosition: Vector3, targetVelocity: Vector3, projectileSpeed: Number, shooterPosition: Vector3, shooterVelocity: Vector3, gravity: Number)
	local distance = (targetPosition - shooterPosition).Magnitude

	local p = targetPosition - shooterPosition
	local v = targetVelocity - shooterVelocity
	local a = Vector3.new() -- Placeholder

	local timeTaken = (distance / projectileSpeed)
	
	if gravity > 0 then
		local timeTaken = projectileSpeed/gravity+math.sqrt(2*distance/gravity+projectileSpeed^2/gravity^2)
	end

	local goalX = targetPosition.X + v.X*timeTaken + 0.5 * a.X * timeTaken^2
	local goalY = targetPosition.Y + v.Y*timeTaken + 0.5 * a.Y * timeTaken^2
	local goalZ = targetPosition.Z + v.Z*timeTaken + 0.5 * a.Z * timeTaken^2
	
	return Vector3.new(goalX, goalY, goalZ)
end

I used this when creating archers for my line warefare rts.

This video has a good explanation.

Really you can use the SUVAT equations or Calculus to solve this. (I prefer the calculus so that I don’t have to memorise 100 different formulas lol)

If you only want to get the angle. Then simply you can solve for 2d the hieght of the target relative to the shooter and the distance would be x. Then you can simple use atan2(X and Z) to find the “floor” angle

7 Likes

omg, that’s it, thanks!

thanks also to:

@Den_vers
@RatiusRat
@BurningEuphoria
Thank you for taking the time to help me!

1 Like

Hey uh… is that your code? Or did you happen to take the source code from some Unity gamedev page?