Need help with making a ball system

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    A ball system for a soccer game

  2. What is the issue? Include screenshots / videos if possible!
    I cant figure out how to make it work.

here is what i want:

  1. What solutions have you tried so far? Did you look for solutions on the Creator Hub?

so much I cant figure it out

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local PhysicsService = game:GetService("PhysicsService")

local Events = ReplicatedStorage:WaitForChild("Events")
local remoteKick = Events:WaitForChild("KickEvent")
local WeldBall = Events:WaitForChild("WeldBall")

local ball = script.Parent

local BALL_GROUP = "Ball"
local PLAYER_GROUP = "Player"

pcall(function() PhysicsService:RegisterCollisionGroup(BALL_GROUP) end)
pcall(function() PhysicsService:RegisterCollisionGroup(PLAYER_GROUP) end)

PhysicsService:CollisionGroupSetCollidable(BALL_GROUP, PLAYER_GROUP, false)

ball.CollisionGroup = BALL_GROUP
if ball:FindFirstChild("SoccerBall") then
	ball.SoccerBall.CollisionGroup = BALL_GROUP
end

local kickForce = 3.25
local upwardForce = 60
local trajectoryMultiplier = 1
local ballDrag = 2.5
local kickUpForce = 0.17
local kickPowerMin = 1
local kickPowerMax = 70
local kickPowerDiff = kickPowerMax - kickPowerMin
local curveForce = 90
local curveDelay = 0.08

local dragBodyForce = ball:FindFirstChildOfClass("BodyForce") or Instance.new("BodyForce")
dragBodyForce.Parent = ball

local weldedToPlayer = {}
local currentOwner = nil
local weld

local function removeWeld()
	if weld then
		weld:Destroy()
		weld = nil
		ball.Parent = workspace
	end
end

local function stopSpinning()
	ball.AssemblyAngularVelocity = Vector3.new(0, 0, 0)
	for _, child in ipairs(ball:GetChildren()) do
		if child:IsA("BodyGyro") or child:IsA("BodyAngularVelocity") then
			child:Destroy()
		end
	end
end

local function getXDirectionSign(direction)
	if direction.X < 0 then
		return -1
	elseif direction.X > 0 then
		return 1
	else
		return 0
	end
end

local function applyCurveWithDelay(baseDirection, curveValue)
	task.delay(curveDelay, function()
		if ball then
			local dirSign = getXDirectionSign(baseDirection)
			local curve = Vector3.new(curveValue * dirSign, 0, 0)
			ball.AssemblyLinearVelocity += curve
		end
	end)
end

local function applyDrag()
	local velocity = ball.AssemblyLinearVelocity
	local dragForceValue = velocity * -ballDrag
	dragBodyForce.Force = dragForceValue + Vector3.new(0, -workspace.Gravity * ball.AssemblyMass, 0)
end

local function hasBall(player)
	local atrib = player:GetAttribute("HasBall")
	return atrib
end

local function isNearBall(player, ball, radius)
	local character = player.Character
	if not character then return false end
	local rootPart = character:FindFirstChild("HumanoidRootPart")
	if not rootPart then return false end
	return (rootPart.Position - ball.Position).Magnitude <= radius
end

local function assignCollisionGroup(character)
	for _, part in ipairs(character:GetDescendants()) do
		if part:IsA("BasePart") then
			part.CollisionGroup = PLAYER_GROUP
		end
	end
end

Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		task.wait(0.1)
		assignCollisionGroup(character)
	end)
end)

local function weldBallFunc(player)
	if hasBall(player) then return end
	if not isNearBall(player, ball, 12) then return end
	if currentOwner and Players:IsAncestorOf(currentOwner) then
		currentOwner:SetAttribute("HasBall", false)
	end
	currentOwner = player
	player:SetAttribute("HasBall", true)
	local character = player.Character
	if not character then return false end
	local rootPart = character:FindFirstChild("HumanoidRootPart")
	if not rootPart then return false end
	ball.Parent = character
	ball:SetNetworkOwner(player)
	ball.Massless = true
	ball.CanTouch = false
	ball.CanCollide = false
	ball.CollisionGroup = BALL_GROUP
	if weld then weld:Destroy() end
	weld = Instance.new("Motor6D")
	weld.Name = "BallMotor"
	weld.Part0 = rootPart
	weld.Part1 = ball
	weld.Parent = ball
	weld.C0 = CFrame.new(1, -2, -2.6)
	weldedToPlayer[ball] = player.UserId
end

remoteKick.OnServerEvent:Connect(function(player, cameraDirection, powerValue)
	local speedX = 0.9
	if not weldedToPlayer[ball] or weldedToPlayer[ball] ~= player.UserId then
		return
	end
	removeWeld()
	player:SetAttribute("HasBall", false)
	ball.CanTouch = false
	local character = player.Character
	local rootpart = character and character:FindFirstChild("HumanoidRootPart")
	local humanoid = character and character:FindFirstChild("Humanoid")
	if (rootpart.Position - ball.Position).Magnitude < 5 then
		local kickBodyForce = Instance.new("BodyForce")
		kickBodyForce.Parent = ball
		local kickDirection = cameraDirection.Unit
		kickBodyForce.Force = (kickDirection + Vector3.new(0, kickUpForce, 0)) *
			(kickPowerMin + (kickPowerDiff * powerValue)) * 90 * speedX
		game.Debris:AddItem(kickBodyForce, 0.05)
	end
	local movement = humanoid.MoveDirection
	ball.AssemblyLinearVelocity = ((cameraDirection.Unit * kickForce * (powerValue or 1) + Vector3.new(0, upwardForce, 0)) * trajectoryMultiplier) * speedX
	ball.CollisionGroup = BALL_GROUP
	ball.Massless = false
	ball.CanCollide = true
	stopSpinning()
	applyCurveWithDelay(cameraDirection, curveForce)
	task.wait(0.3)
	ball.CanTouch = true
end)

WeldBall.OnServerEvent:Connect(weldBallFunc)

RunService.Heartbeat:Connect(function()
	if ball.Parent == workspace then
		applyDrag()
	else
		dragBodyForce.Force = Vector3.new(0,0,0)
	end
end)

RunService.Stepped:Connect(function()
	if weld and ball.Parent == workspace then
		local character = weld.Part1 and weld.Part1.Parent
		if not (character and character:FindFirstChild("Humanoid")) then
			local player = Players:GetPlayerFromCharacter(character)
			if player then
				player:SetAttribute("HasBall", false)
				removeWeld()
				ball.Massless = false
				ball.CanCollide = true
				ball.CollisionGroup = BALL_GROUP
			end
		end
	else
		stopSpinning()
	end
end)

no one is first of all gonna spoonfeed you, second of all no one is gonna try your code, so ur just better off sending video of what you have right now so we can help you, else stick with what you have

1 Like

Your problem is vague. What exactly is not working or meeting your expectations? What are the errors you have encountered? Giving us a vauge idea of what you’re trying to achieve is not going to help you to achieve your goal. As @ChiDj123 has said:

and the guideliness of this category:

Please be more specific about what you are trying to achieve here, the problems you are currently facing and the methods/solutions you have tried.