Issue with VectorForce Causing Continuous Magnus Effect After Landing

In the past two days, I’ve been trying to achieve the Magnus effect for my soccer game. When I finally managed to get it working, I ran into problems caused by the structure of my own code.
Basically, I’m using a VectorForce in a loop to create a nice curve, but the issue is that I don’t really know how to implement it so that the ball doesn’t keep curving after it lands or something like that.
I’ve tried using the built-in physics friction, but it somehow doesn’t work as expected. I also experimented with some damping, but it doesn’t behave the way I want it to.

(Code is a mess because its intented for tests!)

local RepStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Debris = game:GetService("Debris")

local part: Part = script.Parent

local _coefficent = .04

local Balls = {}

local cd = false

local _angle = math.rad(35)
local _power = 150

local _curveDir = 1
local _curveStrength = math.clamp(_power / 50, 0, 3.2)

local _velocity = Vector3.new(-math.cos(_angle), math.sin(_angle), 0) * _power


part.Touched:Connect(function(Part: Part)
	local Player: Player = game.Players:GetPlayerFromCharacter(Part.Parent)
	if not Player then end
	if cd then return end
	task.delay(1,function()
		cd = false
	end)
	cd = true
	
	local Ball = RepStorage.Ball:Clone()
	
	Ball.Parent = workspace
	Ball:PivotTo(Part.CFrame + Vector3.new(-5, 0, 0))
	
	Ball.PrimaryPart.AssemblyLinearVelocity = _velocity
	table.insert(Balls, Ball)
	task.delay(3, function()
		table.remove(Balls, table.find(Balls, Ball))
		Ball:Destroy()
	end)
end)

RunService.Heartbeat:Connect(function(Delta: number)
	for _, Ball in pairs(Balls) do
		local p: Part = Ball.PrimaryPart
		if not p or not p.Parent then continue end
		local vf = p.Parent:FindFirstChildOfClass("VectorForce")
		if not vf then continue end
			
		local LinearVel = p.AssemblyLinearVelocity
		local Speed = LinearVel.Magnitude
		
		
		local CurveDirection = LinearVel:Cross(Vector3.new(0, -workspace.Gravity, 0)).Unit * _curveDir	 
		local Force = CurveDirection * _curveStrength * Speed

		vf.Force = Force
		
	end
end)
1 Like

i think its just because of the vectorforce, its active the entire lifetime of the ball and i just dont have a good experience with roblox’s physics instances…
i believe using runservice for physics is just a lot more reliable and consistent