Im trying to make a item that has a realistic throw when you click while holding it.
I know stuff like Body Velocities/the property for velocity would work best, but the hardest part (for me) is making it where you click.
for example:
If you changed the body velocity to
Vector3.new(20,0,0)
it would fling it just in one direction.
I dont want that, and i want it to go wherever you click.
how would i do that?
(keep in mind it would still kind of need to look like a throw and have a decent/ customizable speed)
if I’m understanding correctly you want to like, throw the item you’re holding from the character’s position to your mouse position right? The first way I can think of doing that is using Mouse Hit’s CFrame position and the character’s humanoidrootpart position to get vector3 that gives you the direction, and using that for the velocity.
Yeah i want the item to be thrown from the characters position. The script is not a local script and im assuming this only works in local scripts right?
yeah mouse.Hit only works for localscripts, but thats not a roadblock, it just means you have to use a remote event to send the value from the client to the server
this is missing the player object whose client belongs to, so in between the parenthesis you need to put the player object. since you’re using the .Activated event I’m guessing you’re using a tool for this?. if this is the case, then you must get the player from the character that is holding that tool, so:
this is why its outputting (argument 1 missing) error.
now this is all good and all, but you are doing everything backwards. youre trying to trigger the event to the client so the client can handle the throwing direction? it should be the opposite. The goal of using a remote event was so you could send the value of the mouse.Hit position from the localscript to the script on the tool. give me a few mins and ill give you a code example
create a LocalScript inside of StarterPlayerScripts and copy this code into it
local userInputService = game:GetService("UserInputService")
local raycastParams = RaycastParams.new()
userInputService.InputBegan:connect(function(input, processed)
if processed == true then return end
if input.UserInputState ~= Enum.UserInputState.Begin then return end
if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
-- Cast a ray to find out where the player clicked
local position = userInputService:GetMouseLocation()
local ray = workspace.CurrentCamera:ViewportPointToRay(position.X, position.Y)
local raycastResult = workspace:Raycast(ray.Origin, ray.Direction * 1000, raycastParams)
if raycastResult == nil then return end
-- ratio effects the throw curve higher values will make the part stay lower and move faster lower values will make the part go higher and move slower
local ratio = 2
-- Character PrimaryPart
local primaryPart = game.Players.LocalPlayer.Character.PrimaryPart
-- this is the position the part will start
local startPosition = primaryPart.Position + primaryPart.CFrame.LookVector * 5
-- the direction from the start position to the click position
local direction = raycastResult.Position - startPosition
-- calculate the force we must apply to the part so it can reach its destination
local force = direction * ratio + Vector3.new(0, game.Workspace.Gravity * 0.5 / ratio, 0)
-- create a part
local part = Instance.new("Part")
part.Size = Vector3.new(1, 1, 1)
part.Position = startPosition
part.Parent = workspace
-- set the parts force
part.AssemblyLinearVelocity = force
end)
Here, this is what i got working, I figured using a RemoteFunction instead of a RemoteEvent was better since all you really need is to call the hit value.
LocalScript:
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local rfunc = script.Parent:WaitForChild('RemoteFunction')
rfunc.OnClientInvoke = function() --when the function is invoked/called
print('invoked')
return mouse.Hit.Position --return the value of mouse.hit
end
Script:
local tool = script.Parent
local part = tool.Handle
local rfunc = tool:WaitForChild('RemoteFunction')
local ratio = 2 --5uphi's ratio thing is very smart
local debounce = false --debounce so it cant be spam clicked
tool.Activated:Connect(function()
if debounce then return end
debounce = true
local player = game.Players:GetPlayerFromCharacter(tool.Parent)
local mousepos = rfunc:InvokeClient(player)
local direction = (mousepos - tool.Parent.PrimaryPart.Position)
--borrowed this from 5uphi lol
local force = direction * ratio + Vector3.new(0, game.Workspace.Gravity * 0.5 / ratio, 0)
tool.Parent = workspace
part.AssemblyLinearVelocity = force
debounce = false
end)
5uphi’s method works just fine however it only runs locally, and im guessing you want something on a script, and like a tool that can be thrown
seems like its failing to identify the primary part in this line
local direction = (mousepos - tool.Parent.PrimaryPart.Position)
which is weird, It shouldn’t have that behaviour, perhaps you put the script inside of something? that makes it so the tool’s parent is no longer the player’s character? in any case, replacing it with this should work
local direction = (mousepos - player.Character.PrimaryPart.Position)
heres the file of my tool in case it still doesnt work, since it works fine here tool.rbxm (4.5 KB)