I’m trying to make it so that when the user presses Q, they drop their tool on the surface that their mouse is on. I know that this will require UIS and most likely Raycasting, but I have a hard time understanding raycasting so I’m looking for a bit of help. As a bonus, it would be nice if I could limit how far the user can drop the tool
I know it’s not good to make a post without starting code, but I’m really unsure how to start with this, so any help is appreciated.
I guess as pseudo-code/guidance you could do something like:
Player presses Q then reparent their tool to the workspace
The tool’s handle position is then moved to the mouse.hit.position
To make a range limit on dropping, you could use Magnitude to get the distance between the player and the mouse position.
Then if its beyond range then return.
local __MAGNITUDE = (__CHARACTER.HumanoidRootPart.Position - __MOUSE.hit.Position).Magnintude
-- GetDistanceFromCharacter() Could work too but i'm not sure..
Im not so sure but you might need to use a remote event for this.
-- client
if keycode == Enum.Keycode.Q then -- if key pressed on the keyboard is Q then..
dropEvent:FireServer(mouse.Hit.Position, tool) -- Fire a remote event containing the mousepos and the tool.
end
-- server
dropEvent.OnServerEvent:Connect(function(plr, mousePos, tool)
if not tool:IsA("Tool") then return end
if not tool:FindFirstChild("Handle") then return end
local distance = player:DistanceFromCharacter(mousePos)
if distance > limit then return end -- Checking if the distance is over the limit
tool.Handle.Position = mousePos -- Changing the handle's position to mousepos
tool.Parent = workspace -- Reparenting the tool
end)
hope this helps Added some new stuff
mark this as a solution if it worked.
Yes you do need an remote event to achieve this.
But to be more secure you should check the tool on the server instead of sending it to the server.
Since they could send something that is not a tool and change the position of the wrong thing.
And turns out you don’t need to use magnitude as with the player argument in the server event, you can just use player:DistanceFromCharater(mousePos)
Ok, so I’m setting this up now, and just wanna make sure I get everything right. 1st, how would I define the mouse.Hit.Position in the Client script? 2nd, for the Server script, would I just use the players service for the player:DistanceFromCharacter? Last, how would I make this apply to all tools globally, because I noticed in the Client script, it has you specify a tool?
-- Client
if keycode == Enum.Keycode.Q then
dropEvent:FireServer(mouse.Hit.Position)
end
-- Server
dropEvent.OnServerEvent:Connect(function(plr, mousePos)
local limit = 100 -- You can change it to your liking.
for _, tool in ipairs(plr.Backpack:GetChildren()) do
if tool:FindFirstChild("Handle") then
local handle = tool.Handle
local distance = plr:DistanceFromCharacter(mousePos)
if distance > limit then continue end
tool.Handle.Position = mousePos
tool.Parent = workspace
end
end
end)
Ok, so I may just be missing something, but I set up print functions to confirm if this works. It prints when the even is fired in the Client, and prints when it is received in the Server, but it doesn’t actually drop the sword. There’s no errors, and no underlines. I added all the necessary variables as well (I think). Sorry about this.
You need zero raycasting for this, unless you want to prevent a player from dropping a tool through an impassable surface (such as a wall or terrain).
When the player clicks, set a variable to the mouse’s position like:
local mouseClickPosition = Mouse.Target.Position
Then, you just remove the tool from the player’s Character and put it into workspace, and then set its position to mouseClickPosition.
Optional step: if you want it so that a player can only drop the tool within a certain distance, you need to use .Magnitude to check how far the tool is from mouseClickPosition. You can do this like:
local maxRange = 30 -- 30 is just an example. put any number here, it is the maximum range in Studs.
if (tool.Position - mouseClickPosition).Magnitude < maxRange then
--> Congratulations! mouseClickPosition is within 30 studs of the tool!
--> Remove tool from player's inventory and move it to mouseClickPosition.
else
--> Oh no, you clicked more than 30 studs away from your character! This is illegal!!!
print("Clicked outside max range, player cannot drop tool from this far away.")
end
So I was trying to make it so the tool you have equipped would be the one that’s dropped. I tried putting a Bool value in the tool, and when the tool is equipped, the value is set to true. When the tool is unequipped, the value is set to false.
local dropEvent = game.ReplicatedStorage.dropEvent
dropEvent.OnServerEvent:Connect(function(plr, mousePos, tool)
local limit = 10 -- You can change it to your liking.
for _, tool in ipairs(plr.Backpack:GetChildren()) do
if tool:GetDescendants("Equipped").Value == true then
if tool:FindFirstChild("Handle") then
local handle = tool.Handle
local distance = plr:DistanceFromCharacter(mousePos)
if distance > limit then continue end
tool.Parent = workspace
tool.Handle.Position = mousePos + Vector3.new(0,1,0)
end
end
end
end)
I added the line under the start of the loop, and there are no errors, but it doesn’t seem to be working. Is there something wrong?