Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

What is the best way to make a throwable tool?

This is my attempt:

local tool = script.Parent
local ball = tool.Handle:Clone()

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

local mouse = player:GetMouse()

tool.Activated:Connect(function()
	local position = character.Head.Position
	local velocity = Vector3.new(mouse.X, mouse.y, mouse.z)
	
	ball.Parent = game.Workspace
	ball.Position = position
	ball.Velocity = velocity * 1000	
end)

Please help, thanks.

2 comments

0

can you describe your problem please?

0

you could use lerp

1 answer

there are. more than a few things wrong with this

for one, mouse.X and mouse.Y describe the mouse's position on the player's screen, not in the world—for that you'd use mouse.Hit

second, you should spawn the ball on the server, or else other players won't be able to see it

third, you shouldn't spawn the tool inside the player's head, but a bit in front of it, so that the physics engine doesn't go all crazy and stupid and dumb

fourth, you should use HumanoidRootPart for anything related to character positioning. it's more reliable and less likely to be changed by roblox

fifth, velocity being at 1000 is just. way too high

sixth, the velocity should be constant—if you throw from really far away, it shouldn't go faster than if you just threw it right next to yourself

seventh, the velocity should be calculated using mouse position relative to the character's position, or else it'll go in the wrong direction

and eighth, you should clone the tool every time it's thrown, or else if the player throws it multiple times the old one will just disappear (or it'll error, if it fell into the void)

-- local script, for sending the mouse position to the server
local tool = script.Parent

local player = game.Players.LocalPlayer
local character = player.Character -- if the tool is equipped then logically, the player must have a character, so there's no point to wait for it to be added
local mouse = player:GetMouse()

tool.Activated:Connect(function()
	tool.Throw:FireServer(mouse.Hit.p)
end)



-- server script
local tool = script.Parent
local character = tool.Parent

tool.Throw.OnServerEvent:Connect(function(player, mousePos) 
	local startPos = (character.HumanoidRootPart.CFrame * CFrame.new(0, 0, -1)).p -- put the starting position a bit in front of the character
	local velocity = (mousePos - startPos).Unit * 50 -- .Unit normalizes the vector (aka gives you a vector with the same direction, but with a magnitude of 1), so that the velocity is constant whether you throw it from far away or super close

	local ball = tool.Handle:Clone()
	ball.Position = startPos
	ball.Velocity = velocity
	ball.Parent = workspace
end)

you need to put a RemoteEvent in the tool, since the client has to send the mouse position to the server

it doesn't have to be named Throw, but you should name it something descriptive

2 comments

0

Sorry, but it says the HumanoidRootPart isn't a valid member of Workspace. I am hoping for your response. Thank you very much!

0

did you put the server script in StarterCharacterScripts

This discussion is preserved as it was. New answers, comments, and votes are closed.