Catch System For a Football Game?

  1. What do you want to achieve? Keep it simple and clear!
    I want to create a catch system where if a football is in the air when a player clicks, the player’s arms follow the ball, and after 3 seconds return to normal. This should be seen on everyone screen although only affect the player that clicked. This mechanic can be seen in games such as Football Fusion, Mossed, as well as Legendary Football and many other football games.

  2. What is the issue? Include screenshots / videos if possible!
    If I do this in a local script then the player’s arms move only for the local player, although I want it to show for everyone. If I detect the player’s click in a local script then fire a remote event to a server script (with debounce) changing the local player’s arms, then only one person can click at a time. If I do the same thing without debounce then for some reason everyone in the game will have their arms moved slightly upwards (if you need to see an example of this i can provide one).

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    ive tried messing with debounce but besides that I cannot figure out a new system.

I am new to scripting so if something is blaringly wrong with the scripts I ask that you’re patient.

This Is the local click detection script

local UIS = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Click = ReplicatedStorage.Clicked
local Player = game.Players.LocalPlayer
local mouse = Player:GetMouse()
local debounce = false


UIS.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
		if not debounce then debounce = true
			if debounce == true then
				Click:FireServer(Player)
				debounce = false
			end
		end
	end
end)

This is the Server Script to change the player’s arms.

local arm1, arm2
local weld1, weld2
local torso 
local FB
local Debounce = false
local Click = game.ReplicatedStorage:WaitForChild("Clicked")

Click.OnServerEvent:Connect(function(Player)
	if not Debounce then Debounce = true 
		if Debounce == true then
			local Lplayer = Player
			FB = game.Workspace:WaitForChild("Football")
			local char = Lplayer.Character
			torso = char:WaitForChild("Torso") 
			arm1 = char:WaitForChild("Left Arm")
			arm2 = char:WaitForChild("Right Arm")
			torso:WaitForChild("Left Shoulder").Part0 = nil
			torso:WaitForChild("Right Shoulder").Part0 = nil

			weld1 = Instance.new("Weld", torso) 
			weld1.C0 = CFrame.new(-1.5,.5,0)
			weld1.Part0 = torso
			weld1.Part1 = arm1

			weld2 = Instance.new("Weld", torso) 
			weld2.C0 = CFrame.new(1.5,.5,0)
			weld2.Part0 = torso
			weld2.Part1 = arm2

			local start = tick()

			while true do 
				if tick() - start >= 2 then break end
				game.ReplicatedStorage.ClickAnimating:Fire()
				wait()
				local offset = CFrame.new(0,0,-0.5)*CFrame.Angles(math.pi/2,0,0)
				local p0c0 = torso.CFrame*weld1.C0

				weld1.C1 = (CFrame.new(p0c0.p, FB.Position)*offset):inverse()*p0c0
				local p0c0 = torso.CFrame*weld2.C0
				weld2.C1 = (CFrame.new(p0c0.p, FB.Position)*offset):inverse()*p0c0 
			end

			while true do 
				wait()
				if torso:FindFirstChildWhichIsA("Weld") == nil then
					break
				else
					torso:FindFirstChildWhichIsA("Weld"):Destroy()
				end
			end

			local m = Instance.new("Motor6D")
			m.Parent = torso
			m.Name = "Left Shoulder"
			m.Part0 = torso
			m.Part1 = arm1
			m.C0 = CFrame.new(-1, 0.5, 0, -0, -0, -1, 0, 1, 0, 1, 0, 0)
			m.C1 = CFrame.new(0.5, 0.5, 0, -0, -0, -1, 0, 1, 0, 1, 0, 0)
			m = Instance.new("Motor6D")
			m.Parent = torso
			m.Name = "Right Shoulder"
			m.Part0 = torso
			m.Part1 = arm2
			m.C0 = CFrame.new(1, 0.5, 0, 0, 0, 1, 0, 1, 0, -1, -0, -0)
			m.C1 = CFrame.new(-0.5, 0.5, 0, 0, 0, 1, 0, 1, 0, -1, -0, -0)
			Debounce = false
		end
	end
end)
1 Like

If the debounce is the problem, you can change the debounce, converting the ‘debounce’ simple boolean value in a dictionary (this in the Server Script); your code would look like this:

local arm1, arm2
local weld1, weld2
local torso 
local FB
local Debounce = {}
local Click = game.ReplicatedStorage:WaitForChild("Clicked")

Click.OnServerEvent:Connect(function(Player)
	if not Debounce[player.Name] then Debounce[Player.Name] = true
		if Debounce[Player.Name] == true then
			local Lplayer = Player
			FB = game.Workspace:WaitForChild("Football")
			local char = Lplayer.Character
			torso = char:WaitForChild("Torso") 
			arm1 = char:WaitForChild("Left Arm")
			arm2 = char:WaitForChild("Right Arm")
			torso:WaitForChild("Left Shoulder").Part0 = nil
			torso:WaitForChild("Right Shoulder").Part0 = nil

			weld1 = Instance.new("Weld", torso) 
			weld1.C0 = CFrame.new(-1.5,.5,0)
			weld1.Part0 = torso
			weld1.Part1 = arm1

			weld2 = Instance.new("Weld", torso) 
			weld2.C0 = CFrame.new(1.5,.5,0)
			weld2.Part0 = torso
			weld2.Part1 = arm2

			local start = tick()

			while true do 
				if tick() - start >= 2 then break end
				game.ReplicatedStorage.ClickAnimating:Fire()
				wait()
				local offset = CFrame.new(0,0,-0.5)*CFrame.Angles(math.pi/2,0,0)
				local p0c0 = torso.CFrame*weld1.C0

				weld1.C1 = (CFrame.new(p0c0.p, FB.Position)*offset):inverse()*p0c0
				local p0c0 = torso.CFrame*weld2.C0
				weld2.C1 = (CFrame.new(p0c0.p, FB.Position)*offset):inverse()*p0c0 
			end

			while true do 
				wait()
				if torso:FindFirstChildWhichIsA("Weld") == nil then
					break
				else
					torso:FindFirstChildWhichIsA("Weld"):Destroy()
				end
			end

			local m = Instance.new("Motor6D")
			m.Parent = torso
			m.Name = "Left Shoulder"
			m.Part0 = torso
			m.Part1 = arm1
			m.C0 = CFrame.new(-1, 0.5, 0, -0, -0, -1, 0, 1, 0, 1, 0, 0)
			m.C1 = CFrame.new(0.5, 0.5, 0, -0, -0, -1, 0, 1, 0, 1, 0, 0)
			m = Instance.new("Motor6D")
			m.Parent = torso
			m.Name = "Right Shoulder"
			m.Part0 = torso
			m.Part1 = arm2
			m.C0 = CFrame.new(1, 0.5, 0, 0, 0, 1, 0, 1, 0, -1, -0, -0)
			m.C1 = CFrame.new(-0.5, 0.5, 0, 0, 0, 1, 0, 1, 0, -1, -0, -0)
			Debounce[Player.Name] = false
		end
	end
end)

--and in this form the debounce only will only affect each player that makes a server request, --not every game players.

--If you still have a problems with this, I can find other solutions to this.
1 Like

Hey! Firstly I just wanted to thank you. Being able to script is definitely a hope of mine and you’re helping to make it possible. Secondly that does make it more consistent with the debounce but I’m still having 2 problems with the script if you could help out. Firstly if someone else clicks while you’re clicking then it cancels your arms following the ball and you just get stuck wherever the ball was last. Secondly I don’t fully understand why this is happening but when someone clicks the other players have a chance, without doing anything, to have their arms raised slightly up.

This is a video of the other bugs!

1 Like

Probably you may create an event that fire a signal in the precisse moment; then, you can create a code that stop the players arm movements when the signal be sended. This may fix the second bug, but I still thinking about fix the first bug. And I have a dude, what is ‘ClickAnimating’ event used for, in the server script?

2 Likes

The ClickAnimating event tells the football script that the player’s arms are extended then the football can be caught.

1 Like

you may use a other boolean value, to control this animation, but, how does the script know which player to interact with?

1 Like

Would the bool value not change everytime anyone clicked bc the script runs for everyone? (Thats why im using remote events). Also the football script just says that if the player’s arms are following the ball and the ball hits the person then the player can catch it doesnt matter which players arms are following the ball. The local script detects which player clicks and sends that player to the server script to be manipulated(arms following the football etc…). Thats how both scripts now which player to interact with.

1 Like

But the ‘ClickAnimating’ (in the while loop of the server script) event fires a signal to other side, without any parameter

1 Like

I figured out the solution after like 3 weeks… by putting the remote event and server script into the starter character as well as the click detection then each player’s server script can work independently instead of having to do it all in one script!!!

3 Likes