This tutorial explains to you the structure of weapons on ROBLOX and why they work.
This section is a short description of how Tools work in the current version of Roblox. This may be useful to anyone who wants to create their own tools and doesn't care that any such tool may be short-lived due to the rapid development that is occurring in this area.
In a multi-player game, scripts can run in two places: on the client, or on the server. This is not a detail that can be ignored. Making a working tool requires orchestration of both client and server side scripts.
On the Server
On the Client
In any single player mode (solo visit or edit), the client and server are the same machine. As a rule of thumb, if your tool works in multi-player, it will work in solo mode. The converse is not always true.
The structure of a weapon looks something like this.
The tool is the big thing at the top. It goes into people's backpacks and shows up in their screen. Tools have scripts, parts, and meshes that direct what the tool does. The only thing you really need to change in the tool is the name and the Grip properties if you're trying to change how the player grips the weapon, or if you're going to be fancy you can edit the weapon icon too.
The handle is the part that contains the mesh. Meshes can't be put into the game except under a part that defines its general shape (called the bounding box). The handle is the part that has a mesh in it that shows what the weapon looks like. Each weapon has its own mesh that it uses. Usually, if you want to make a new weapon, you should copy another existing weapon and change the script only so that you don't have to copy the mesh URLs and GripPos on the tool over. You can change the kind of shape that the mesh is by going under its properties and changing the MeshType or MeshId.
The weapon script is usually called something related to the weapon name, such as "Server Launcher" for the Rocket Launcher and "Slingshot" for the slingshot. It dictates what the weapon does when its fired.
The projectile script is attached to the projectile and handles what the projectile does when it flies out of the weapon. Usually it just handles what happens when it hits something.
The Local Gui is a LocalScript that deals with cursors on the client. It changes the cursor to a target when you switch to a weapon and adds the "reloading" text onto the cursor after firing. Usually there is nothing that needs to be changed in this script except for the reload time.
Audio can be uploaded to ROBLOX to bring new sounds to your game.
Here's a step by step process of what happens when you select and use the rocket launcher. The rocket launcher tree looks like this:
|Select the rocket from your weapons.|| Local Gui:
This adds a listener that changes the cursor to a target cursor. The listener waits for "Equipped" and then goes to the "onEquippedLocal" function.
mouse.Icon = "rbxasset://textures\\GunCursor.png"
This code changes the mouse icon.
|Click on a target.|| Local Gui:
The onButton1Down function has a Debounce system that keeps it from repeatedly activating.
mouse.Icon = "rbxasset://textures\\GunWaitCursor.png" wait(12) mouse.Icon = "rbxasset://textures\\GunCursor.png"
Changes the cursor to "reloading," waits until the weapon is done reloading (12 seconds) and then changes the cursor back to the regular one. Server Launcher: The script at the top makes the rocket but it doesn't fire it yet.
This causes "onActivated" to run when the script.Parent, or the Rocket Launcher, is run. onActivated uses Debounce as well.
local targetPos = humanoid.TargetPoint fire(targetPos)
This gets what the target is and then calls the fire function that will actually shoot the rocket. I won't go into what the fire function actually does, but the key things are:
local missile = Rocket:clone() missile.RocketScript.Disabled = false missile.Parent = game.Workspace
This makes a new missile from the Rocket at the top, activates its script (the projectile script) and puts it into the game.
|Rocket flies out and makes a whooshing noise.|| RocketScript:
This will play the sound that the rocket makes when it flies.
This causes the rocket to keep flying forward without falling due to gravity.
Rocket hits target, explodes, and blows up a person.
connection = shaft.Touched:connect(blow)
This causes the rocket to blow up when it touches something by calling the blow function.
explosion = Instance.new("Explosion") explosion.Position = shaft.Position explosion.Parent = game.Workspace
This makes the explosion.
Weapons are available in most Roblox maps. They can be either copied, or created. The easiest way to make weapons is to modify a previously made BrickBattle weapon. This tutorial will explain how to create your very own weapons.
When the weapon is selected, the HopperBin object activates the "Selected" event. To check when the weapon is selected (change cursor, etc.), use this code: script.Parent.Selected:connect(Function)
When the mouse is clicked, the mouse activates the "Button1Down" event.To check for clicks, use this code: mouse.Button1Down:connect(Function)
While some weapons are propelled in the direction of the mouse, such as the Superball, others are created at the mouse, walls, for example, or are sent to the point clicked on, such as Rocket. The position clicked on is a CFrame, accessed by mouse.Hit
If the weapon does damage, then the humanoid needs to be "skill" so kills can be recorded. To do this, two functions are available. They are tagHumanoid and unTagHumandoid
function tagHumanoid(humanoid) -- todo: make tag expire local tag = script.Parent:FindFirstChild("creator") -- Where "creator" is an ObjectValue placed in the script's parent. Its value is set to "game.Players.LocalPlayer" by the script that makes it. if tag ~= nil then local new_tag = tag:Clone() new_tag.Parent = humanoid end end
Before un-tagging the humanoid, the game must be given a chance to record the kill. To do this, a wait of two seconds is reasonable.
function untagHumanoid(humanoid) if humanoid ~= nil then local tag = humanoid:findFirstChild("creator") if tag ~= nil then tag.Parent = nil end end end
Weapons can also have more than one piece on them. You have to write a script to keep the pieces together. Here are the instructions for making a weld script for weapons with more than one piece.
local w1 = Instance.new("Weld") w1.Parent = script.Parent.Handle w1.Part0 = w1.Parent w1.Part1 = script.Parent.Handle2 w1.C1 = CFrame.new(X, Y, Z)
But in some cases you may want to have your brick at a certain angle. To do this you must input on the last line.
w1.C1 = CFrame.Angles(X, Y, Z) * CFrame.new(X, Y, Z)
And after that you must put w2, w3, w4, w5, etc. You must also put Handle and Handle2, Handle3, etc.
Weapons can be given icons. These are shown in the weapon selection bar. If no icon is selected, the name of the HopperBin object is displayed.
Weapons often have a specific type of cursor. The cursor is an important stylistic choice. The creator of a weapon can choose a cursor to finish to style of the weapon. To change the cursor, the creator must change the mouse.Icon property. mouse.Icon = "Texture Path"
The list of official cursor texture paths:
First, make your weapon. Make it however you want it to look like after you have made it. Make sure that the part that you'll hold is named "Handle", and everything else a different name other than Handle. You can add a SpecialMesh to it as well, to make it look better. What type of mesh you use doesn't matter. Later on, you'll need to fine-tune the weapon. When you just start out, the weapon may look very strange.
The script consists of mainly the Weld Script which can be found in Free Models, using the Equipped event. A Weld is an object that keeps your tool together. (The parts don't necessarily need to be touching each other in order to be welded.)
This is your basic Weld.
local w1 = Instance.new("Weld") w1.Parent = script.Parent.Handle -- The main Handle. w1.Part0 = w1.Parent w1.Part1 = script.Parent.PARTNAME -- Change this to your second part's name. w1.C1 = CFrame.Angles(0, 0, 0) * CFrame.new(0, 0, 0)
You can add more welds to it, too. Just make sure you change the name of the Local Weld first. (Instead of w1, change it to w2 or so on.)
For a second weld, do this:
local w1 = Instance.new("Weld") w1.Parent = script.Parent.Handle -- This is the original Handle. w1.Part0 = w1.Parent w1.Part1 = script.Parent.PARTNAME1 -- Change PARTNAME to your second part's name. w1.C1 = CFrame.Angles(0, 0, 0) * CFrame.new(0, 0, 0) local w2 = Instance.new("Weld") w2.Parent = script.Parent.Handle w2.Part0 = w1.Parent w2.Part1 = script.Parent.PARTNAME2 -- Change to the third part's name. w2.C1 = CFrame.Angles(0, 0, 0) * CFrame.new(0, 0, 0)
And so on. Just change PARTNAME to your second tool part's name.
Here's where the time and work actually have to be put in. You'll need to fine-tune the angles. Maybe even down to the decimals.
You will need to change the X,Y,Z axis' to change how the tool looks. If you need help finding out which one moves which one, use Anaminus' Rotate Tool. Just press the corresponding key to move the axis. Click a brick to apply it.
The basic script above makes the weapon have multiple parts, but it won't work. It needs to know when to apply it. So, add:
function onEquipped() end script.Parent.Equipped:connect(onEquipped)
So now our script looks like this.
function onEquipped() local w1 = Instance.new("Weld") w1.Parent = script.Parent.Handle -- This is the original Handle. w1.Part0 = w1.Parent w1.Part1 = script.Parent.PARTNAME -- Change PARTNAME to your second part's name. w1.C1 = CFrame.Angles(0, 0, 0) * CFrame.new(0, 0, 0) local w2 = Instance.new("Weld") w2.Parent = script.Parent.Handle w2.Part0 = w1.Parent w2.Part1 = script.Parent.PARTNAME -- Change to the third part's name. w2.C1 = CFrame.Angles(0, 0, 0) * CFrame.new(0, 0, 0) end script.Parent.Equipped:connect(onEquipped)
In order to drop it and allow it to stay together, add:
function onUnequipped() end script.Parent.Unequipped:connect(onUnequipped)
Line in. Now it makes it droppable. Put the weld script between it so it makes the weld(s) again AFTER it gets dropped.
So now the script looks like this:
function Weldnow() local w1 = Instance.new("Weld") w1.Parent = script.Parent.Handle -- This is the original Handle. w1.Part0 = w1.Parent w1.Part1 = script.Parent.PARTNAME -- Change PARTNAME to your second part's name. w1.C1 = CFrame.Angles(0, 0, 0) * CFrame.new(0, 0, 0) local w2 = Instance.new("Weld") w2.Parent = script.Parent.Handle w2.Part0 = w1.Parent w2.Part1 = script.Parent.PARTNAME -- Change this to the third part's name. w2.C1 = CFrame.Angles(0, 0, 0) * CFrame.new(0, 0, 0) end script.Parent.Equipped:connect(Weldnow) script.Parent.Unequipped:connect(Weldnow)
Change the script to make the tool look like what you imagined it. What can get frustrating is the fact that the X,Y,Z factors can go into the negatives, giving you even more variables! If you do everything correctly, your weapon will look very nice.
Here's a diagram of what your basic sword tool should look like.
[-]Tool ...Handle ...Part ...Part ...Weld Script ...SwordScript ...LocalGUI
Here's what your basic gun could look like.
[-]Tool ...Handle ...Part ...Part ...Weld Script ...GunScript ...ProjectileScript ...LocalGUI
Remember to make new welds for each and every part! If not, your tool will fall apart.
print 'Hello World!'
In order for this button to function properly, the weapon you want to give to players must be in the game's Lighting Directory.
script.Parent.Touched:connect(function(part) p = game.Players:GetPlayerFromCharacter(part.Parent) if p == nil then return end gun = game.ServerStorage.WEAPONNAMEHERE:clone() --Change WEAPONNAMEHERE to the name of the weapon if p.Backpack:FindFirstChild(gun.Name) ~= nil then return end gun.Parent = p.Backpack end)
An example of what the changed line would look like for, e.g., a rocket launcher would be:
gun = game.ServerStorage.LinkedRocketLauncher:clone()
The name of the weapon might not be spelled correctly in the script.
The weapon might not be in the ServerStorage directory.
A weapon with a SpecialMesh object in it (often named "Mesh").
Here's a chart of what each axis is.
X = Horizontal, or left and right. Y = Vertical, or up and down. Z = Depth, or diagonal.
Changing the color is actualy quite simple.
Now you have a weapon with a more exciting color other than the original color(s).
You can also change the vertex color of the mesh and that way keep the texture but have a different color. Keep in mind that the first number means blue, second means green and third means red. Having all of them the same will mean that you are having the basic colors.