What's wrong with my Bezier formula?

Hello, I’m trying to make a cannon, but my bezier function isn’t working. Whenever, I start the function nothing seems to be happening, and there is no part inside workspace. I’m pretty sure that the part flings into the void or something. Can anyone help me please?

Script:

local CannonEvent = game:GetService("ReplicatedStorage"):WaitForChild("Events"):FindFirstChild("Tools"):FindFirstChild("CannonEvent")

function lerp(a,b,t)
	return a + (b - a) * t
end

function quadraticBezier(a,b,c,t)
	local point1 = lerp(a,b,t)
	local point2 = lerp(b,c,t)
	local calculatedPoint = lerp(point1,point2,t)

	return calculatedPoint
end

CannonEvent.OnServerEvent:Connect(function(player,Base,Barrel,startPos)
	local endPos = Barrel.CFrame.LookVector * 25
	local midPos = (startPos-endPos)/2 + Vector3.new(0,30,0)

	local CannonBall = Instance.new("Part")
	CannonBall.CanCollide = false
	CannonBall.Position = startPos
	CannonBall.Size = Vector3.new(5,5,5)
	CannonBall.Parent = workspace

	CannonBall.Position = quadraticBezier(startPos,midPos,endPos,5)
end)

Thank you.

you aren’t using lerp correctly so the cannonball spawns into the world but falls through the map and despawns

1 Like

Ah yes that’s what I thought, so how should I lerp correctly? I think I know how, but I’m not sure.
I updated the script:

CannonBall.CFrame:Lerp(quadraticBezier(startPos,midPos,endPos,5))

but now I got this error:

Argument 3 missing or nil

I know I shouldn’t bump this post, but I still need help!

Little disclaimer, this is adapted from a bezier formula I used for UI, so some of the values are in Vector2 and you will need to convert it to Vector3. Should be pretty self explanatory code though, and made some changes to make it compatibles with what you wrote. (it probably wont work out of the box, also I haven’t ran this code so no idea if there are errors)

Lmk if you have any questions

--Services
local RunService : RunService = game:GetService("RunService")

local Settings : {
    BEZIER_ARC_STEEPNESS : number,
    SPEED_LOWER_BOUND : number,
} = {
    BEZIER_ARC_STEEPNESS = 1.5, --Steepness of the pivot arc for the bezier curve. the higher the number, the more the part will "swing" open
	SPEED_LOWER_BOUND = 100,
}

local function generateBezierCurve(cannonBall : Part, x : number, currentPivot : number, coinOrigin : Vector2, coinDestination : Vector2)
    local bezierCurve : Vector2 = math.pow((1 - x), 2) * coinOrigin + Settings.BEZIER_ARC_STEEPNESS * x * (1 - x) * currentPivot + math.pow(x, 2) * coinDestination
    cannonBall.Position = UDim2.fromOffset(bezierCurve.X, bezierCurve.Y)

    return
end

CannonEvent.OnServerEvent:Connect(function(player,Base,Barrel,startPos)
	local endPos = Barrel.CFrame.LookVector * 25

	local CannonBall = Instance.new("Part")
	CannonBall.CanCollide = false
	CannonBall.Position = startPos
	CannonBall.Size = Vector3.new(5,5,5)

	task.spawn(function()
		local currentPivot = Vector2.new(startPos.X, startPos.Y)
		local animationConnection : RBXScriptConnection = nil
		local xValue : number = 0
		local curveSpeed : number = 100
		local origin : Vector3 = startPos
		local destination : Vector3 = endPos
		CannonBall.Parent = workspace

		animationConnection = RunService.Heartbeat:Connect(function(step)
			xValue += step * curveSpeed
			generateBezierCurve(CannonBall, xValue, currentPivot, origin, destination)
			if xValue >= 1 then
				CannonBall:Destroy()
				animationConnection:Disconnect()
			end
		end)
	end)
end)
1 Like

Works perfectly thank you!!!

1 Like

I know that the post has been marked as solved, but your issue is basically, you are inputting a number above 1, and so when you use the bezier method that you used, you need to use a number between 0 and 1.

Also thanks for using my tutorial :happy4:
If you want me to explain how to apply it in your case, please do say

1 Like

Thank you! Also your tutorial was really good and helped out a lot! Honestly without it I would so confused lol.

Aww thanks, I’m thinking about creating a bezier module :eyes:

1 Like