I need help with some math work

function FX:RangedVisualCreate(HRP, EnemyPosition, Class, Combo)
	local Table = FX:GetRanged(Class, Combo)
	local Start = HRP.CFrame * Table["Start"]
	local Finish = EnemyPosition
	local Middle = (Start + Finish)/2 + Table["Middle"]
	local Bullet = ReplicatedStorage.Bullet:Clone()
	Bullet.Parent = workspace
	
	task.defer(function()
		for i = 1, 50 do
			local t = i/50
			local NewPosition = quad(Start, Middle, Finish, t)
			Bullet.Position = NewPosition
			task.wait(0.01)
		end
		
		task.wait(2)
		
		Bullet:Destroy()
	end)
end

How would I make the projectile speed change? Currently, if Iā€™m far away from the target then the projectile will appear to be faster. When Iā€™m close then the projectile becomes really slow.

But both arrive at the same times anyways. I want it to reach the goal at different times depending on how close you are to the target. If youā€™re near, then it would obviously hit/reach the target faster than shooting at the target from afar.

in the task.wait() term, reduce the number

It canā€™t be less than that. Roblox has a limit to waiting, which is around 1/30th of a second.

maybe in the for loop, change the value from 50 to a lower number like 20

Yeah, I think thatā€™s correct. So this:

function FX:RangedVisualCreate(HRP, EnemyPosition, Class, Combo)
	local Table = FX:GetRanged(Class, Combo)
	local Start = HRP.CFrame * Table["Start"]
	local Finish = EnemyPosition
	local Middle = (Start + Finish)/2 + Table["Middle"]
	local Bullet = ReplicatedStorage.Bullet:Clone()
	Bullet.Parent = workspace
	
	task.defer(function()
		for i = 1, 25 do
			local t = i/25
			local NewPosition = quad(Start, Middle, Finish, t)
			Bullet.Position = NewPosition
			task.wait(0.01)
		end
		
		task.wait(2)
		
		Bullet:Destroy()
	end)
end

Should do it in half the time? I think the closer you are to the player, it gets slower, so maybe make the number smaller the closer you are?

Yeah try that. Send the result in a video

I donā€™t have access to my computer right now, itā€™s just a guess.

1 Like

task.wait() can go lower then 1/30th of a second btw

I thought that wasnā€™t true? It has a limit to the simulation rate, which is usually 30-50 ā€œframesā€ per second.

Id recommend one of two options:
Use a for loop and calculate the time to wait, which isnt the best because of robloxs limitations on how short a wait can be
Or
Use a while loop or something else like that and calculate how much t has to move given some time interval

If you wanted to go with the first option, you could roughly guess a change in time based on the distance and a desired speed, using a formula like:

wait(total_distance/speed * 1/50)

But again this could very easily pass below 1/30th of a second

Alternatively, I would recommend replacing the whole for loop with something along the lines of:

--top of script
local rs = game:GetService("RunService")

--inside your defer thingy
local speed = 5
local t = 0
while t <= 1 do
    local dt = rs.Heartbeat:Wait() --this could get a teeny tiny bit laggy, so you could replace this with a wait time then wait(dt) in the line below
    t = t + (speed * dt)/total_distance
    --do all the fancy quadratic stuff
end

Now keep in mind total_distance is just the straight shot distance between start and finish, if you want a more accurate approximation of the arc length
You can use this formula in place of total_distance in both the time-based and t-based approaches

This is fairly complex and its really not necessary, just if you want ultra precision
Heres the formula:

function arsinh(x)
    return math.log(x + math.sqrt(x^2+1))
end
function corrected_distance(d, h) --d = magnitude from start to finish; h = height of arc
    local part1 = d^2 * arsinh(4 * h * 1/d)/(8 * h)
    local part2 = math.sqrt(16 * h^2 + d^2)/2
    return part1 + part2
end

--you can just call corrected_distance with total_distance and your height value
local corr_dist = corrected_distance(total_distance)
--use corr_dist in the formulas instead of total_distance

well wait() has a limit of 1/30

task.wait() could be as low as 1/60
Heartbeat:Wait() = task.wait()

when I say they are equal, I mean those should wait the same amount if you donā€™t put in any arguments into task.wait()

OK, all theory. Easy enough to translate into a number.

If you want to shoot a distance of 20 studs in one second (60 Heartbeats), you need to move 1/3 stud per heartbeat. Lets start there. That seems pretty fast. And yes, I recommend using some RunService that is tied to rendering.

Now, if the person is 50 studs away, you want the speed to be the same, and the travel time to be 50/20 = 2.5 seconds. Total frames 60*2.5 = 150 travelling at a speed 1/3 stud per heartbeat. 3 frames per stud.

The distance is the x value (what you call t), but the for loop is variable based on the Magnitude of the shot.

local magnitude = (Start - Finish).Magnitude
for i = 1, magnitude*3 do

ā† where 3 is the speed of 3 frames per stud. This is how you adjust speed. The lower this number, the faster the bullet.

1 Like