Need help making my ball curve system

Hello, I’m making a blade ball remake and have been stuck on the curving system. Specifically applying the curve to the ball. I already have the camera’s direction just I don’t know how to apply it correctly. I have a LinearVelocity with MaxForce set to inf and that works fine but once I start adding curves to the linearvelocity like how blade ball does it starts to get more complicated and just very buggy.

I’ve tried using a VectorForce but found that the LinearVelocity overides the VectorForce, I’ve tried using ball:ApplyImpulse() same issue.

Heres a snipet of my code that contains the velocity calculations, etc :

local targetPos = targetCharacter.HumanoidRootPart.Position
local direction = (targetPos - ball.Position).Unit
local adjustedY = math.max(direction.Y, (minY - ball.Position.Y) / (targetPos - ball.Position).Magnitude)
local clampedDirection = Vector3.new(direction.X, adjustedY, direction.Z).Unit
FollowVelocity.VectorVelocity = clampedDirection * currentSpeed

if (ball.Position - targetPos).Magnitude <= workspace:GetAttribute("PARRY_RANGE") and targetCharacter:GetAttribute("Parrying") == true then
	targetCharacter:SetAttribute("Parrying", false)
	BlockingSystem:FireClient(targetPlayer, "Blocked")
	local nextTarget = getClosestTarget(targetCharacter)
	if nextTarget then
		ball:SetAttribute("Target", nextTarget.Name)
	else
		pickRandomTarget(ball)
	end
	local lookValue = targetCharacter:FindFirstChild("Look")
	if lookValue and lookValue:IsA("CFrameValue") then
		local lookDirection = lookValue.Value.LookVector.Unit
		
	end
end
3 Likes

Honestly, i thought blade ball’s curves were done with a Bezier Curve. Did you try looking into that? I believe Bezier Curves use lerp to move the ball as well.

Edit: It looks like there is a module out there so you don’t have to deal with all the mathematics, here is a link to the Github and Dev Forum.

1 Like

Appreciate it, I will look into that. Thank you!

You’re welcome if you ever need more help you can ask or look at the examples provided in the Github as well. Good Luck!

What I have come across is, the system just seems to easy for it to be all of these calculations. There has to be another way

There really aren’t that many calculations, if you want it to look nice using curves like this then it’s pretty necessary.

okay, i’ve tried the bezier curves but it’s not like how blade ball does it, for me when i curve the ball it follows that curve that whole way until it reaches the target. and thats not what i want, im trying to achieve blade balls curving system

I’m not entirely sure how blade ball makes the ball curve, but I have an idea on what you can do.

My assumption is that the ball curves based on the orientation of the player hitting it and the position of the target player.

You could make a position that is around 5 studs in the humanoid’s look direction and lerp that position to then be the position of the targeted player while also creating a lerp for the ball to be in that position being lerped.

I have found a different way that is actually pretty close to how blade ball has theres just only issue is, the ball can’t curve backwards meaning I’m still doing something different to blade balls way. I know it’s not a bezier curve system because even while the ball is in the curving state, it follows the target. The way blade ball does their’s seems like it just pushes the ball into that direction and due to the vectorvelocity constantly being updated it causes a curve like effect. But i’m not entirely sure. Anyways here’s my code so far.

local extraVelocity = Vector3.zero
local decayRate = 8
local curveStrength = 2
local curveStartVelocity = nil
local curveDirection = nil
local curveTime = 0

function StartCurveImpulse(curveDir)
	extraVelocity = curveDir.Unit * currentSpeed * curveStrength
end

RunService.Heartbeat:Connect(function(dt)
	local targetName = ball:GetAttribute("Target")
	local target = workspace:FindFirstChild(targetName)
	if target then
		local direction = (target.Position - ball.Position).Unit
		if curveDirection then
			curveTime += dt
			local alpha = math.clamp(curveTime, 0, 1)
			extraVelocity = curveStartVelocity:Lerp(curveDirection, alpha)
			if alpha >= 1 then
				curveDirection = nil
			end
		end
		local velocity = direction * currentSpeed + extraVelocity
		FollowVelocity.VectorVelocity = velocity
		extraVelocity = extraVelocity:Lerp(Vector3.zero, math.clamp(decayRate * dt, 0, 1))
		if (ball.Position - target.Position).Magnitude <= 8.5 then
			local currentDir = (target.Position - ball.Position).Unit
			local faceDir = target.CFrame.LookVector
			local curveDir = (faceDir - currentDir).Unit
			StartCurveImpulse(curveDir)

			local newTargetName = (targetName == "1") and "2" or "1"
			local newTarget = workspace:FindFirstChild(newTargetName)
			if newTarget then
				ball:SetAttribute("Target", newTargetName)
			end
		end
	end
end)

(Don’t mind the simple swapping of the target and how i’m using parts, I’ve just been testing my system out)