I have a quite good understanding of Roblox Lua but I have always struggled with making weapon scripts. I am talking about the scripts that are not tools but have abilities and when you click certain keys it does things. Are there any plugins or similar things on Studio that can help me with this?
How to make alright weapons scripts on Roblox Studio? Plugins or similar things.
2 answers
(almost) EVERYTHING ABOUT HOW TO MAKE WEAPONS
Listen, first off, don't get mad at me, but there is no better way to make weapons than using tools. At first I tried to make non-tool weapons, but it turned out disastrous and inefficient. (there will be a mini tutorial for non-tool weapons at the very bottom anyway.)
So I have a few tips and snippets of code that will probably help you on your tool-creation journey. Remember if this does help you, please mark it as the answer. Thanks!
So first off, how to format a tool. Create a tool, and create a MeshPart/Part inside of it named "Handle". Easy enough. Then, add in a LocalScript (this can be named whatever).
So you asked how you can make tools function when you can click or press keys. Here's a snippet of code that I think will improve your understanding:
(all code taken from the Roblox developer website and modified for understanding)
local tool = script.Parent
local player = game:GetService("Players").LocalPlayer
tool.Equipped:connect(function() --This function fires whenever the player equips the tool. It will stop when it is unequipped.
print("Tool equipped!")
end)
tool.Unequipped:Connect(function() --This function fires when the player unequipped the tool.
print("The tool was unequipped")
end)
You'll notice how I suggested remote events in the following code block. That's because all tools will only fire on the client side. (Now, I'm not sure if you can use a tool with a Server Script, but hey, something to try out in the future).
local tool = script.Parent
local player = game:GetService("Players").LocalPlayer
tool.Equipped:connect(function(mouse)
print("Tool equipped!")
mouse.Button1Down:connect(function() --Yay, check when the mouse is pressed :''D
print("Mouse pressed!")
--Fire whatever remote events, raycasts, etc
end)
end)
Great! Now keypress.
local tool = script.Parent local player = game:GetService("Players").LocalPlayer
tool.Equipped:connect(function(mouse)
print("Tool equipped!")
local mouse = player:GetMouse()
mouse.KeyDown:connect(function(key) --Detect if the player presses a key.
if key == "e" then --You can choose what key they are required to press.
print("Pressed e")
end
end)
end)
Now, I'm short on sleep. Sorry if any of these don't work. Oh, and also. Animations! Create an animation using the built-in animation plugin, (you may have to change the animation priority), export, and then copy the id, create an Animation instance in your tool, paste in the id and add this into your script.
local anim = player.Character.Humanoid:LoadAnimation(script.Parent.Animation) --make sure to change this if you named your animation instance something else.
anim:Play() --Start the animation. You can also use :Stop(), and I think resume and pause.
The below localscript that goes in startergui will turn the player's torso to the mouse. It has easy to modify variables which is useful. This is useful for weapons, tool or non-tool, that need a bit of polish. Nobody knows who this is originally scripted by lol, but thanks to OhHeyItsCory for upgrading it. Go follow the epic dude. (I didn't write it).
--[[
[Head/Waist Follow Mouse/Camera Script.]
[Works with both R6 and R15, lets you turn your character's head and waist towards your mouse/camera.]
[Scripted by (Unknown), upgraded by OhHeyItsCory.]
[I'm not sure who made the original script and the person I found it from definitely didn't make it.]
[If you find the original creator, please let me know so I can properly credit them <3]
[Anyways, here's a list of what I've added.]
[Waist rotation. (Previously, only the head turned.)]
[Tweening. (Basically, animating the rotation instead of instantly turning.)]
[Full body rotation. (If set to true, rotates the entire body towards the mouse.)]
[Specific rotation limits. (The original script used one variable to set the limits of both horizontal and vertical rotation, now there's variables for both limits!)]
--]]
wait()
--[Pre-Funcs]:
local Ang = CFrame.Angles --[Storing these as variables so I dont have to type them out.]
local aSin = math.asin
local aTan = math.atan
--[Constants]:
local Cam = game.Workspace.CurrentCamera
local Plr = game.Players.LocalPlayer
local Mouse = Plr:GetMouse()
local Body = Plr.Character or Plr.CharacterAdded:wait()
local Head = Body:WaitForChild("Head")
local Hum = Body:WaitForChild("Humanoid")
local Core = Body:WaitForChild("HumanoidRootPart")
local IsR6 = (Hum.RigType.Value==0) --[Checking if the player is using R15 or R6.]
local Trso = (IsR6 and Body:WaitForChild("Torso")) or Body:WaitForChild("UpperTorso")
local Neck = (IsR6 and Trso:WaitForChild("Neck")) or Head:WaitForChild("Neck") --[Once we know the Rig, we know what to find.]
local Waist = (not IsR6 and Trso:WaitForChild("Waist")) --[R6 doesn't have a waist joint, unfortunately.]
--[[
[Whether rotation follows the camera or the mouse.]
[Useful with tools if true, but camera tracking runs smoother.]
--]]
local MseGuide = false
--[[
[Whether the whole character turns to face the mouse.]
[If set to true, MseGuide will be set to true and both HeadHorFactor and BodyHorFactor will be set to 0]
--]]
local TurnCharacterToMouse = true
--[[
[Horizontal and Vertical limits for head and body tracking.]
[Setting to 0 negates tracking, setting to 1 is normal tracking, and setting to anything higher than 1 goes past real life head/body rotation capabilities.]
--]]
local HeadHorFactor = 1
local HeadVertFactor = 0.8
local BodyHorFactor = 0.5
local BodyVertFactor = 0.8
--[[
[How fast the body rotates.]
[Setting to 0 negates tracking, and setting to 1 is instant rotation. 0.5 is a nice in-between that works with MseGuide on or off.]
[Setting this any higher than 1 causes weird glitchy shaking occasionally.]
--]]
local UpdateSpeed = 0.8
local NeckOrgnC0 = Neck.C0 --[Get the base C0 to manipulate off of.]
local WaistOrgnC0 = (not IsR6 and Waist.C0) --[Get the base C0 to manipulate off of.]
--[Setup]:
Neck.MaxVelocity = 1/3
-- Activation]:
if TurnCharacterToMouse == true then
MseGuide = true
HeadHorFactor = 0
BodyHorFactor = 0
end
game:GetService("RunService").RenderStepped:Connect(function()
local CamCF = Cam.CoordinateFrame
if ((IsR6 and Body["Torso"]) or Body["UpperTorso"])~=nil and Body["Head"]~=nil then --[Check for the Torso and Head...]
local TrsoLV = Trso.CFrame.lookVector
local HdPos = Head.CFrame.p
if IsR6 and Neck or Neck and Waist then --[Make sure the Neck still exists.]
if Cam.CameraSubject:IsDescendantOf(Body) or Cam.CameraSubject:IsDescendantOf(Plr) then
local Dist = nil;
local Diff = nil;
if not MseGuide then --[If not tracking the Mouse then get the Camera.]
Dist = (Head.CFrame.p-CamCF.p).magnitude
Diff = Head.CFrame.Y-CamCF.Y
if not IsR6 then --[R6 and R15 Neck rotation C0s are different; R15: X axis inverted and Z is now the Y.]
Neck.C0 = Neck.C0:lerp(NeckOrgnC0*Ang((aSin(Diff/Dist)*HeadVertFactor), -(((HdPos-CamCF.p).Unit):Cross(TrsoLV)).Y*HeadHorFactor, 0), UpdateSpeed/2)
Waist.C0 = Waist.C0:lerp(WaistOrgnC0*Ang((aSin(Diff/Dist)*BodyVertFactor), -(((HdPos-CamCF.p).Unit):Cross(TrsoLV)).Y*BodyHorFactor, 0), UpdateSpeed/2)
else --[R15s actually have the properly oriented Neck CFrame.]
Neck.C0 = Neck.C0:lerp(NeckOrgnC0*Ang(-(aSin(Diff/Dist)*HeadVertFactor), 0, -(((HdPos-CamCF.p).Unit):Cross(TrsoLV)).Y*HeadHorFactor),UpdateSpeed/2)
end
else
local Point = Mouse.Hit.p
Dist = (Head.CFrame.p-Point).magnitude
Diff = Head.CFrame.Y-Point.Y
if not IsR6 then
Neck.C0 = Neck.C0:lerp(NeckOrgnC0*Ang(-(aTan(Diff/Dist)*HeadVertFactor), (((HdPos-Point).Unit):Cross(TrsoLV)).Y*HeadHorFactor, 0), UpdateSpeed/2)
Waist.C0 = Waist.C0:lerp(WaistOrgnC0*Ang(-(aTan(Diff/Dist)*BodyVertFactor), (((HdPos-Point).Unit):Cross(TrsoLV)).Y*BodyHorFactor, 0), UpdateSpeed/2)
else
Neck.C0 = Neck.C0:lerp(NeckOrgnC0*Ang((aTan(Diff/Dist)*HeadVertFactor), 0, (((HdPos-Point).Unit):Cross(TrsoLV)).Y*HeadHorFactor), UpdateSpeed/2)
end
end
end
end
end
if TurnCharacterToMouse == true then
Hum.AutoRotate = false
Core.CFrame = Core.CFrame:lerp(CFrame.new(Core.Position, Vector3.new(Mouse.Hit.p.x, Core.Position.Y, Mouse.Hit.p.z)), UpdateSpeed / 2)
else
Hum.AutoRotate = true
end
end)
A good plugin that helps you change the grip of tools better! Props to him! vv
Alright, fine, non-tool weapons. What you want to do is put the weapon model in startercharacterscripts (all welded together to one part if there are multiple parts using weld constraints which are simple; part1 and part0), and create a localscript in the model. In the localscript you'll want to create a Instance.new("WeldConstraint") and then set the properties to the part that everything is welded to. Use the same functions from above to get click and get key press. It is hard to modify how it is being held correctly, you will have to do some math. Another reason why I strongly recommend tools!
I am sorry if this was not what you were looking for. I hope this helps you. This took me like half an hour. If it is not what you are looking for, please reply so I can help! But if it does help, you're welcome, enjoy! :D
-ProqrammedGreen
3 comments
-1 for using deprecated terms (:connect, .KeyDown), and for unnecessarily posting free models
Thanks!
Honestly though, it was a massive help.
Regarding server scripts in tools, you should consider utilizing both local and server scripts in your tools (one of each), and fire remotes for anything that can be handled server-side to prevent any potential exploiting/cheating.
Per the following page: https://developer.roblox.com/en-us/articles/intro-to-player-tools
" but most tools will require both a server script and a local script (LocalScript) where each takes care of certain aspects of the tool’s behavior. "
This discussion is preserved as it was. New answers, comments, and votes are closed.

1 comment
working on a quite big answer...