You can write your topic however you want, but you need to answer these questions:
-
What do you want to achieve? Keep it simple and clear!
A ball system for a soccer game -
What is the issue? Include screenshots / videos if possible!
I cant figure out how to make it work.
here is what i want:
- 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)