I made it to where if you go by a soccer ball and you touch the hitbox it’ll stick to the player but i don’t really know how to check if the player is still there when it’s welded to them in case they disconnect or reset due to being stuck.
local PS = game:GetService("PhysicsService")
local RS = game:GetService("RunService")
local Players = game:GetService("Players")
local Player = Players.PlayerAdded:Wait()
local Character = Player.Character or Player.CharacterAdded:Wait()
local HRP = Character:FindFirstChild("HumanoidRootPart")
local RP = game:GetService("ReplicatedStorage")
local Ball = script.Parent
local BallHitBox = Ball.BallHitBox
local WeldToPlayer = Ball.WeldToPlayer
local Owner = nil
BallHitBox.Touched:Connect(function()
if Owner ~= nil then return end
for i,v in pairs(BallHitBox:GetTouchingParts()) do
if v:IsDescendantOf(Character) then
if not HRP then return end
Owner = Player.Name
Ball:SetNetworkOwner(Player)
Ball.Massless = true
Ball.CanCollide = false
WeldToPlayer.Part0 = HRP
WeldToPlayer.C0 = CFrame.new(0,-2.5,-2)
end
end
end)
You could try listening to the Destroying event of the player’s HRP.
e.g:
local PS = game:GetService("PhysicsService")
local RS = game:GetService("RunService")
local Players = game:GetService("Players")
local Player = Players.PlayerAdded:Wait()
local Character = Player.Character or Player.CharacterAdded:Wait()
local HRP = Character:FindFirstChild("HumanoidRootPart")
local RP = game:GetService("ReplicatedStorage")
local Ball = script.Parent
local BallHitBox = Ball.BallHitBox
local WeldToPlayer = Ball.WeldToPlayer
local Owner = nil
local RemoveConn = nil
BallHitBox.Touched:Connect(function()
if Owner ~= nil then return end
for i,v in pairs(BallHitBox:GetTouchingParts()) do
if v:IsDescendantOf(Character) then
if not HRP then return end
if RemoveConn then RemoveConn:Disconnect() end -- prevent memory leaks
Owner = Player.Name
Ball:SetNetworkOwner(Player)
Ball.Massless = true
Ball.CanCollide = false
WeldToPlayer.Part0 = HRP
WeldToPlayer.C0 = CFrame.new(0,-2.5,-2)
RemoveConn = HRP.Destroying:Once(function()
-- Whatever processing you want here
Ball.CanCollide = true
Ball.Massless = false
end)
end
end
end)
If you want to detect when the player leaves or when they reset then you should probably just use the player leave and join events. This is something that could work:
local PS = game:GetService("PhysicsService")
local RS = game:GetService("RunService")
local Players = game:GetService("Players")
local Player = Players.PlayerAdded:Wait()
local Character = Player.Character or Player.CharacterAdded:Wait()
local HRP = Character:FindFirstChild("HumanoidRootPart")
local RP = game:GetService("ReplicatedStorage")
local Ball = script.Parent
local BallHitBox = Ball.BallHitBox
local WeldToPlayer = Ball.WeldToPlayer
local Owner = nil
BallHitBox.Touched:Connect(function()
if Owner ~= nil then return end
for i,v in pairs(BallHitBox:GetTouchingParts()) do
if v:IsDescendantOf(Character) then
if not HRP then return end
Owner = Player.Name
Ball:SetNetworkOwner(Player)
Ball.Massless = true
Ball.CanCollide = false
WeldToPlayer.Part0 = HRP
WeldToPlayer.C0 = CFrame.new(0,-2.5,-2)
end
end
end)
local function ResetOwnership(PossibleOwner:Player)
if not PossibleOwner or PossibleOwner.Name ~= Owner then return end
--Do ball reset stuff here
end
Players.PlayerAdded:Connect(function(player: Player)
player.CharacterAppearanceLoaded:Connect(function(character: Model)
local Humanoid = character:FindFirstChildOfClass("Humanoid")
Humanoid.Died:Once(function()
ResetOwnership(player)
end)
end)
end)
Players.PlayerRemoving:Connect(ResetOwnership)
@SeargentAUS It’s probably not a good idea to use the destroying event of the player’s HRP because after the player resets, their dead body parts may lie there for a couple of seconds before getting destroyed. This might also cause weird behaviour with the ball anchored on them, so you want it to be immediate
Didn’t seem to work it still falls through the floor whenever they reset. the only one that works is when they leave
local Players = game:GetService("Players")
local Player = Players.PlayerAdded:Wait()
local Character = Player.Character or Player.CharacterAdded:Wait()
local HRP = Character:WaitForChild("HumanoidRootPart")
local RP = game:GetService("ReplicatedStorage")
local Ball = script.Parent
local WeldToPlayer = nil
local Owner = nil
local function HasBall(Player)
local Attribute = Player:GetAttribute("HasBall")
return Attribute == true
end
local function GetDistance(Part1, Part2)
local GrabDistance = (Part1.Position - Part2.Position).Magnitude
return GrabDistance
end
local function ResetOwnerShip(PossibleOwner: Player)
if not PossibleOwner or PossibleOwner.Name ~= Owner then return end
Owner = nil
if PossibleOwner then
PossibleOwner:SetAttribute("HasBall", false)
end
if WeldToPlayer then
WeldToPlayer:Destroy()
WeldToPlayer = nil
end
Ball:SetNetworkOwner(nil)
Ball.Massless = false
Ball.CanCollide = true
Ball.CFrame = Ball.CFrame * CFrame.new(0,5,5)
end
task.spawn(function()
while true do
task.wait(0.2)
for i,v in pairs(Players:GetPlayers()) do
if Owner ~= nil then return end
if GetDistance(Ball, HRP) <= 8 then
Owner = Player.Name
Player:SetAttribute("HasBall", true)
Ball:SetNetworkOwner(Player)
Ball.Massless = true
Ball.CanCollide = false
if WeldToPlayer then
WeldToPlayer:Destroy()
end
WeldToPlayer = Instance.new("Motor6D",Ball)
WeldToPlayer.Name = "BallMotor"
WeldToPlayer.Part0 = HRP
WeldToPlayer.Part1 = Ball
WeldToPlayer.C0 = CFrame.new(0,-2.5,-2)
end
end
end
end)
Players.PlayerAdded:Connect(function(player: Player)
Player.CharacterAppearanceLoaded:Connect(function(Character)
local Humanoid = Character:WaitForChild("Humanoid")
Humanoid.Died:Connect(function()
ResetOwnerShip(player)
end)
end)
end)
Players.PlayerRemoving:Connect(ResetOwnerShip)
I also tried to change up the code since i noticed that whenever another player joins they can’t get the ball only the first one who joined can
Is the ball actually CanCollide true?
If not and it’s not welded to the player then it’ll just fall through the baseplate.
A simple colour change of the ball when it’s CanCollide true (green) or false (red) would give you a visual indication.
Try adding a print statement in the reset function to make sure it’s working properly… When the players humanoid dies, the event fires then it calls the function so it should be working. Also, why are you getting your player, player character, and HRP on the top of your script?
Used printing it works but it still doesn’t change can collide to true. Also to answer your question i forgot to get rid of that after i changed out the code to instead have it to where the ball will wield to the player after a certain distance instead of touching the hitbox since it wasn’t really consistent.
I just figured it out. I feel like an idiot right now. The problem was the fact that whenever the player died they could still get the ball so it kept on welding to them until they disappeared
local Players = game:GetService("Players")
local Ball = script.Parent
local WeldToPlayer = nil
local Owner = nil
local function HasBall(Baller: Player)
local Attribute = Baller:GetAttribute("HasBall")
return Attribute == true
end
local function GetDistance(Part1, Part2)
local GrabDistance = (Part1.Position - Part2.Position).Magnitude
return GrabDistance
end
local function ResetOwnerShip(PossibleOwner: Player)
if not PossibleOwner or PossibleOwner.Name ~= Owner then return
else
print("It works", Owner, WeldToPlayer)
Ball.Massless = false
Ball.CanCollide = true
Ball.CFrame = Ball.CFrame * CFrame.new(0,-2.5,-2)
Ball:SetNetworkOwner(nil)
Owner = nil
if WeldToPlayer then
WeldToPlayer:Destroy()
WeldToPlayer = nil
end
if PossibleOwner then
PossibleOwner:SetAttribute("HasBall", false)
end
end
end
task.spawn(function()
while true do
task.wait(0.1)
for i,v in pairs(Players:GetPlayers()) do
if v:IsA("Player") then
local VC = v.Character or v.CharacterAdded:Wait()
local VHRP = VC:FindFirstChild("HumanoidRootPart")
if VC:FindFirstChildOfClass("Humanoid").Health == 0 then continue end
if Owner ~= nil then continue end
if GetDistance(Ball, VHRP) <= 10 then
Owner = v.Name
v:SetAttribute("HasBall", true)
Ball:SetNetworkOwner(v)
Ball.Massless = true
Ball.CanCollide = false
if WeldToPlayer then
WeldToPlayer:Destroy()
end
WeldToPlayer = Instance.new("Motor6D",Ball)
WeldToPlayer.Name = "BallMotor"
WeldToPlayer.Part0 = VHRP
WeldToPlayer.Part1 = Ball
WeldToPlayer.C0 = CFrame.new(0,-2.5,-2)
end
end
end
end
end)
Players.PlayerAdded:Connect(function(player: Player)
player.CharacterAppearanceLoaded:Connect(function(character: Model)
local Humanoid = character:FindFirstChildOfClass("Humanoid")
Humanoid.Died:Once(function()
ResetOwnerShip(player)
end)
end)
end)
Players.PlayerRemoving:Connect(ResetOwnerShip)
It’s solved but there’s little comments I’ll make…
You don’t really need this check because you’re looping through a table of players
Don’t do this because you want to only consider players who have fully loaded in. Also, if a player is taking time loading their character it’ll yield your code