Help creating a Grab and Throw script

Howdy, this is my first topic in the developer forum. If I put this in the wrong category please guide me to the right one.

  1. What do you want to achieve? Keep it simple and clear!

I am making a 2.5D game and I want to make a part you can Grab and Throw, I want it to throw using UserInputService and go to the direction the player is facing

  1. What is the issue? Include screenshots / videos if possible!

I have already made the grabbing system using WeldConstraint, but I’m stuck in the throwing system.

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

I have tried looking for solutions everywhere. But they don’t seem to work.

This is my localscript located inside StarterGUI:

local apple = workspace.parts["1-5"]:WaitForChild("Apple")
local prompt = apple.ProximityPrompt
local UIS = game:GetService("UserInputService")
local animation = script:WaitForChild("Animation")
local grabbing

prompt.Triggered:Connect(function(player)---- when they press the prompt they grab the part.
	grabbing = true
	local char = player.Character or player.CharacterAdded:Wait()
	local hum = char:WaitForChild("Humanoid")
	local AnimTrack = hum:LoadAnimation(animation)
	local weld = Instance.new("WeldConstraint")
	weld.Parent = char
	weld.Part0 = apple
	weld.Part1 = char.HumanoidRootPart
	apple.Position = char.HumanoidRootPart.Position + Vector3.new(-2, 0, 0)
	UIS.InputBegan:Connect(function(input, gpe)---- I want it so if they press the "F" key it throws the part in the direction the character is facing.
		if gpe then end
		if grabbing == true and input.KeyCode == Enum.KeyCode.F then
--------- What should I add here to throw the part forward?
			grabbing = false
			apple.Parent = workspace 
			weld:Destroy() 
			AnimTrack:Play()
			wait(0.2)
			AnimTrack:Stop()
		end
	end)
end)

Any help is appreciated.

2 Likes

Let’s try a little template:


Create a Tool inside Workspace, with a regular part being the handle. Then, create a script inside that tool, and the rest of the work will be done by me;

Also, make sure the CanBeDropped property is set to false, inside the tool.

local tool = script.Parent
local handle = tool.Handle

local throwing = false

local throwSpeed = 100

tool.Activated:Connect(function()
    
    if throwing == true then return end
    throwing = true
    
    local player = game.Players:FindFirstChild(tool.Parent.Parent.Name) or game.Players:GetPlayerFromCharacter(tool.Parent)
    
    local cframe = handle.CFrame
    tool.Parent = workspace
    handle.CFrame = cframe
    
    handle:SetNetworkOwner(nil)
    
    handle.BodyLinearVelocity = player.Character.HumanoidRootPart.CFrame.LookVector * throwSpeed
    
    task.wait(0.5)
    throwing = false
    
end)

Let me know if it works or not, and I’ll be happy to help.

1 Like

I have created the tool and named a normal part “Handle” and put a server script inside the tool. I can pick it up fine, but I cannot throw it. It gives me this error

image

1 Like
local cframe = handle.CFrame

Can you put a print(handle) before this line, because it’s apparently indexing nil.

1 Like

image
Like this? I have tried it but it still gives the same error.

1 Like

Does anything print from the script, though?

1 Like

yes, it does, but it prints “nil”

1 Like

Can you replace line 2 in the script with this:

local handle = tool.Handle
1 Like

It got rid of the error, but now there’s this error

1 Like

My bad, it’s AssemblyLinearVelocity. Replace the line with this:

handle.AssemblyLinearVelocity = player.Character.HumanoidRootPart.CFrame.LookVector * throwSpeed
1 Like

There are no more errors anymore, but I still can’t throw the part.

1 Like

Does the part drop when you try throwing it?

1 Like

Nope, it does not drop I still hold it whenever I activate the tool.

1 Like

Do you even know if the Parent property gets changed?

1 Like

The parent property gets changed when I pick it up, it’s parent becomes the character. But, when I activate it the parent doesn’t change, it’s still the character.

1 Like

I have fixed it, I just had to move the “tool.Parent” above the “Local cframe”. But, another question is how do I make it throw the part when a key is pressed? Instead of LeftClicking the tool to activate it.

This would require a client script, alongside a remote event, if you want to detect a key press.


Also your fix just gave the script a millisecond more time to set the CFrame. You can just add a delay. Update your script to this:

local tool = script.Parent
local handle = tool.Handle

local throwing = false

local throwSpeed = 100

tool.Activated:Connect(function()
    
    if throwing == true then return end
    throwing = true
    
    local player = game.Players:FindFirstChild(tool.Parent.Parent.Name) or game.Players:GetPlayerFromCharacter(tool.Parent)
    
    local cframe = handle.CFrame
    tool.Parent = workspace
    task.wait()
    handle.CFrame = cframe
    
    handle:SetNetworkOwner(nil)
    
    handle.BodyLinearVelocity = player.Character.HumanoidRootPart.CFrame.LookVector * throwSpeed
    
    task.wait(0.5)
    throwing = false
    
end)

How would I go about doing that? Sorry, I don’t know much about remote events.

Alright then, create a remote event inside the tool, don’t name it. Then create a local script inside the tool aswell.

The client script:

local UIS = game:GetService("UserInputService")

local tool = script.Parent
local handle = tool.Handle

local remote = tool.RemoteEvent

local keyCode = "E" --Change what key to press

UIS.InputBegan:Connect(function(input,gameProcessed)
    
    if (not gameProcessed) or UIS:GetFocusedTextBox() then return end
    
    if input.KeyCode == Enum.KeyCode[keyCode] then
        remote:FireServer()
    end
    
end)

…and the server:

local tool = script.Parent
local handle = tool.Handle

local remote = tool.RemoteEvent

local throwing = false

local throwSpeed = 100 --Change the throwing speed of the ball

remote.OnServerEvent:Connect(function(player)
    
    if throwing == true then return end
    throwing = true
    
    local cframe = handle.CFrame
    tool.Parent = workspace
    handle.CFrame = cframe
    
    handle:SetNetworkOwner(nil)
    
    handle.BodyLinearVelocity = player.Character.HumanoidRootPart.CFrame.LookVector * throwSpeed
    
    task.wait(0.5)
    throwing = false
    
end)

See if any errors occur.

1 Like

No errors, but it doesn’t work. The tool doesn’t get thrown.