Transcription
Hey, thanks for stopping by! In this episode of my Roblox Advanced scripting tutorial series, I'm going to be talking about tools. Now, I think you pretty much know what tools are. Almost every single Roblox game you can think of has tools in some sort of way. They're basically items for players to be able to equip from their backpack or their inventory and use them. So, things like weapons or tools or any other sort of something that's equipable that players can use to further progress through the game that they're playing. And that's what we're about to be creating in this episode. But before we do, there's going to be some things we need to understand first.
All right, let's think about this for a minute. So, I just hit play test here in Roblox Studio, and there's going to be a few things I want you to know about before we start creating tools. So, on the right side, if we open up Explorer, we can see everything that's contained inside of the Explorer. But one thing in particular is our own character, because obviously, when when the player joins the game, there's going to be a clone of the player's character from the website and be put into the workspace, because, you know, that's how we can um actually see ourselves inside of the game. If we open this up, we can actually see that there's a whole bunch of stuff that make up our character. We have shirts, pants, uh, we have uh, a bunch of accessories. Uh, I can actually take some of these accessories off, like my glasses, for instance. I just like deleted that. Now you can see my glasses are gone. So, everything here basically makes up uh, my character inside the workspace. We also have certain body parts, we have scripts, and a bunch of other stuff that makes up our player character inside of the game.
But not only that, there's another thing. If we go, if we uh, scroll down a little bit, um, we can actually see that there's a folder called Players. Uh, if we open up Players, we can actually see that there is a player instance that basically has the same name as the, as my character up here, Brawl Battle. Uh, this is the character inside of the workspace, but, but this is the player, the player instance. And if we open this up, we can see that there's four things here: there's Backpack, StarterGear, PlayerGui, and PlayerScripts. We're mostly going to be focused on these two here, uh, for this episode: Backpack and StarterGear. So, in essence, there's two things that happen when a player joins the game. One is that their character gets copied and put into the workspace. Whenever our player joins the game, the second thing is that a player instance is created and put inside of the Players, uh, folder inside of the game with a bunch of other stuff. So, this is something I wanted you to be aware of when we start creating tools.
All right, now that we understand that, let's create a tool. But you might ask, where do we create this tool? Do we create it in Workspace? Do we create it in Players? No, we actually create it inside of a, another folder inside of the game called StarterPack. And essentially, what StarterPack is, is that this is the default backpack of, ideally filled with tools, uh, where when the player joins the game, uh, and it doesn't matter which player it is, because all players will share the same StarterPack. And so, any tools that are put inside of the StarterPack will be put inside of the player's backpack in the game, no matter what. Whether they join the game for the first time, or whether they reset their character, these tools that are in the StarterPack will be copied over to the player's backpack. And this is how it's going to be for the entirety of the game. So, we're going to create a tool by clicking on the plus sign next to StarterPack, and you can see that there is a Tool right here. So, let's click that, and now we've created our first tool instance placed inside of the StarterPack.
So, if we look at our tool and, uh, we like, hit test and hit Play. Now that we're in the game, we can see that down here, the tool is shown. If we click on it, uh, nothing exactly happens because we didn't make the tool do anything yet. It's just an empty tool instance. But if we go on the right side with our player and, um, look into our backpack, we can actually see that our tool is displayed inside of here, as, as expected, because everything that's inside of the StarterPack from Roblox Studio, uh, like this tool, it gets copied over to every single player's backpack. And that's basically where the tool lies.
But now, let's look at some properties for the tools. The first thing we'll look at is ToolTip, and this is essentially a text that displays, uh, on top of the, um, on top of the tool whenever you hover over the item, uh, giving you like a little bit of information about it. I will show you what I mean, but for right now, let's just select this and let's put in something. Let's give it a description by saying, "This is a tool." So, now that we have that in there, I'll show you what it looks like inside of the game after a little bit. But let's look into another property called TextureID. So, if you notice when we were playing the game, um, our tool was displayed at the bottom of the screen down here, uh, but all it showed was the text "Tool," which was the name of the tool. Um, but what if we wanted to show an image instead of the name of the tool? This is where TextureID comes in.
Now, you might ask, how do we actually get a TextureID and where do we get images from? So, that is going to be through the Toolbox, uh, which can be accessed from up here. When you click View and then there should be a Toolbox right over here. If we click that, we can actually see that we have a huge marketplace catalog filled with user-generated content that's been uploaded to the Roblox website, in which you can actually take some of these and put it inside of your game. Now, I would generally advise not using the Toolbox because, um, a lot of these things have backdoor scripts that can like, you know, hack your game or modify the game to something that you don't want, all kinds of security issues, which is why I would generally advise not to use the Toolbox. But for the sake of this tutorial, we are going to use it. Okay.
But now, in order to get our TextureID, we need an ID from an image. And to get an image, we click on this dropdown here and we click on Images. So, this gives us a whole bunch of images to work with, uh, that's been uploaded to by the Roblox community. So, if we just take one of these, um, let's take this, let's take this super, super happy face, for instance. We're going to right-click it and then we're going to click on Copy Asset ID. And then on the right side, on our TextureID, let's select this, let's right-click, and then we'll say Paste. And then we'll hit Enter. So, essentially, we got the ID of the image and we've now put it onto here in the TextureID. So, we should be able to see in our game. If we go to Test and we go to Play, we should see these two changes with the ToolTip and also the TextureID.
So, the first thing you notice, if we join in, is that, uh, our tool now doesn't display, uh, the name of the tool anymore, but instead our image, because we gave the TextureID an ID of the image. If we hover over it, we can actually see that it displays a text on top of it saying, "This is a tool." This was our ToolTip that we provided, uh, for the tools. So, those are two pretty cool things. If we equip and unequip it, nothing still happens because we didn't, you know, actually make it do anything yet.
Now, let's create a Handle so that we can actually show that the player is holding something whenever they equip the tool. So, if we go to our Model tab, hit Parts, so that we create a new part inside of the Workspace. Uh, there's going to be two very important things we need to do. The first thing is, if we click on the part and then go down here into the properties, make sure that Anchored is set to false, so that it's turned off. Um, the reason for this is because we don't want the part to be stuck in place whenever, uh, the game is running. We want it to be affected by gravity. Um, and then the second thing we have to do is rename this part to a very specific name. We're going to, uh, click on this and then we're going to name it Handle with a capital H.
And now, what we'll do is, we will take this part, we will drag it into our tool here, here inside of our StarterPack. And basically, what we're doing is, we're telling Roblox that this is now a part that we want to display on the player's hand whenever the tool is equipped. Let's equip our tool. So, down here, let's, uh, click on it. We should see that we now have the part, which we called Handle, uh, that was set as a child to the tool, is now equipped for us. Uh, and, and so basically, our hand is stuck out, um, whenever our tool is equipped, and we see the part, like, very clearly. We unequip it, and then the part is gone. If we equip it again, we can see it. If we unequip it, it's gone.
Now, let's actually see what happens in the Explorer whenever we equip and unequip the tool. So, I'm going to, uh, open up the Workspace and Players. Let's open up our player, uh, and our Backpack as well, and let's open up our character. Remember when I said that our character in the Workspace makes up what we actually see in the Workspace? We can see that when, when we don't have the tool equipped, it's in, inside of our player's backpack here. But if we equip it, we can actually see that the tool moved from our backpack into our own character. The tool is now part of our character. If we unequip it, we can actually see that the tool moved back into her backpack. So, that's a really interesting thing to note about.
Here's two more properties to know about. If we scroll down a little bit, we can see that there's a Scale property and a CanBeDropped property. The Scale property basically just sets the size of the tool itself, um, specifically the Handle. Um, if we just change this to, let's say, uh, 1.5, then it increases the scale of the tool. Uh, we can change it to two, we can even make it smaller than the default by saying 0.5. So, that's like a little neat thing to know about. Another property is CanBeDropped, and this is basically a check to see whether the player can actually get rid of this item from their backpack. And, uh, on PC or, uh, desktop or computer or whatever, um, the key to actually dropping an item is the Backspace button. So, if we have it equipped and, uh, we press Backspace, we can actually see that the part is now located inside of the Workspace and is not a child to my character anymore. But if I pick it back up, it goes back into my character. Now, if I quickly go to the tool and uncheck CanBeDropped, and make sure we're not selecting Tool inside the, um, Workspace, inside of the Workspace, so like down here, uh, if we try pressing Backspace now, it does not work. And that's because we set CanBeDropped to false. These are two additional properties that I'm just going to throw out there.
Now, let's actually script our tool. On our tool, we're going to, uh, click on the plus sign and then we're going to create a Script. Now, remember, it's important to note the difference between Script and LocalScript. Uh, I made a video talking about LocalScripts, uh, but for the purposes of this tutorial, we're going to use a Script so that it'll be replicated to all players. I generally would not advise doing this unless, uh, there is clear communication between the server and the client, but we're not going to go over that in this episode. So, we've just created a script inside of a tool. Let's delete this code here and, uh, let's first make reference to the tool. So, we're going to say, local tool = script.Parent.
And so, in this episode, I'm going to be going over four events that I think are going to be pretty useful for tools. Uh, the first one is going to be Equipped. So, we'll say tool.Equipped, and, uh, we're going to say :Connect(function() we're going to hit Enter. Uh, and first thing we'll do is, we'll make a print statement. We'll say, print("This tool has been equipped.") So, we've just created our first event, and this will basically run every time the player equips the tool.
So, now let's do the same thing, but this time, time we'll unequip it. So, we'll drop two lines down here and then we'll say, tool.Unequipped:Connect(function() we're basically just going to do the exact same thing here. Print("This tool has been unequipped.")
Now, let's go to the game, hit Test, hit Play, you know, the usual. So, make sure you have your Output down here, uh, so that we can actually see the change happening. When we equip the tool, we can see that the Output has printed "This tool has been equipped." And if we unequip it, we can see that "This tool has been unequipped." And so, we can just continuously do this every time we equip and unequip the tool. So, we basically did exactly what we wanted it to do.
All right, but now there's two more events that we'll be going over, and that's going to be Activated and Deactivated. So, Activated is basically an event that triggers whenever the player clicks on the left mouse button of their mouse, if they're playing on PC. Uh, but I believe in other devices, it's, uh, tapping the screen if on mobile, and I think it's Right Trigger on Xbox, if I'm not mistaken. So, basically, whenever you interact with the tool after equipping it. So, we'll say, tool.Activated:Connect(function() and then do the same thing here with the syntax. We will say, print("Tool has been activated.") And so, we will also do the same thing down here when it becomes deactivated. So, Deactivating is basically when you let go of the activation, uh, button, whichever one it was, whether that was the left mouse button, Right Trigger, or tapping on the screen. Uh, so, we'll say, tool.Deactivated:Connect(function() and then we will say, print("Tool has been deactivated.")
So, now we have our four events here. Let's go into the game and then test it. So, first thing we're going to do is equip it. We'll see that the tool's been equipped. Now, let's try activating it. So, I'm on PC, so the button to activate it is going to be the left mouse button. So, if I hold, uh, my left mouse button, we can see that it printed out saying, "The tool has been activated." But if I let go of my mouse, then it will activate the deactivation. "Tool has been deactivated." If I just click, we can see that it very quickly activated and deactivated because Activated happens whenever you actually press down on the key, but then Deactivated happens when you let go.
There's actually two more properties here in the Behavior category called ManualActivationOnly and RequiresHandle. So, RequiresHandle is basically like, okay, we have a, we have a tool, but we don't need it to have a Handle when we want to use this tool. So, uh, if we right-click our tool and then duplicate it, uh, and we open up this one, let's also rename this to Tool2 so that we don't get confused with it. Let's actually delete this Handle. Um, so now we have a tool that doesn't have a Handle, meaning when our player equips this tool, nothing will show, uh, as like a physical object when the player equips a tool. Um, but we can still activate it and, uh, you know, run the script without having an actual Handle. So, we can actually disable this, and if we go into the game, we should still be able to activate it. So, I believe it's going to be our second tool. As you can see, uh, our player does not hold out his hand to something because we deleted the Handle, but we can still see that the script is still working just fine without the Handle. So, that's like one useful thing to know about for that.
And then the other property is ManualActivationOnly. So, if we activate this, like if we said it's true, that means that whenever we equip the tool, we cannot activate it automatically when we, um, when our player decides to do it by like, uh, left mouse clicking or right triggering or, uh, tapping on the screen. We can only have activation happen through script. So, I'll show you an example of how this would actually work. So, if we go to our Tool2 and then click on the script, let's delete this one so that it's a little easier to read. Let's make it so that as soon as we equip the tool, let's activate the Activated event here. So, we're going to drop a line here from Equipped and we're going to say, tool:Activate(). So, this basically artificially simulates, um, what would happen if the player clicks, um, and activates the tool because we don't want it to happen automatically. This is going to happen manually. So, as soon as we equip the tool, it's going to automatically activate it without the player actually doing it because now the player cannot activate it on its own. So, if we equip our second tool, we can see that the tool's been equipped, and, uh, the Activated event has also been triggered because as soon as we equipped our tool, it set off the Activated event on its own. And if I try to activate the tool, it's not going to work. Instead, all it's going to do is trigger the Deactivated one because, because that property inside of our tool was specifically designed for activation, not deactivation.
There's actually one final thing I forgot to mention, and that is StarterGear. Essentially, StarterGear is basically the StarterPack, but if it was specific to an individual player. So, some players could spawn in every time they reset their character with a certain set of tools, uh, that is only specific to that player, or maybe if someone is in a specific team, they will spawn into the game with specific tools that other teams or other players cannot start out with. And let me show you how this is done really quickly. So, if I, uh, select my tool on the StarterPack and I right-click and duplicate it, let's call this Tool2, and I'm actually going to get rid of the TextureID so that we can see the difference between Tool1 and Tool2. I'm going to drag this into ReplicatedStorage. And now, let's play the game.
So, now I'm in the game, as you can see. Uh, I've opened up my player, so that StarterGear is over here. And if I open up ReplicatedStorage, my Tool2 should be here as well. Here's something that's really important to know about, though. Inside of the Test ribbon, I'm going to click on the current, uh, window that we're in. I'm going to click it so that we can go to the server instead. If I open up the Players, my player with its StarterGear, and I go to ReplicatedStorage with Tool2, I'm going to drag this into StarterGear. So, now, for the first time, I join into the game with my one and only tool right here that's in my, uh, backpack. But if I actually reset my character, then something really interesting will happen. So, once I reset my character, I'm now going to have two tools down here as a starter, rather than one, because Tool2 was very specifically put inside of my player's StarterGear. So, now whenever I reset my character, I'm not only going to start off with Tool1, but also Tool2. And, uh, if I go back into the server and quickly delete StarterGear, go back into my own client and I reset my character, then I should no longer be able to spawn in with my second tool alongside my first one. So, that is another very interesting thing to know about. It's very useful if you want specific players to have specific tools, or people in specific teams to have specific tools. And of course, if you want to do this through script, then all you have to do is just set the parent of the tool not only to their backpack, but also to their StarterGear. So, the next time the player resets their character, they're going to have their new tool.
Okay, now let's put it all together. And in this last section of the video, I'm actually going to make this a challenge that you can try if you want, or you can follow what I do. There's going to be a few requirements. The five requirements that I have for you are: First, play a sound when the tool is equipped. And if you don't know how to play a sound, then that's okay, the step doesn't really matter all too much. The next requirement is to create a Boolean to check if the player is holding down activation and change it appropriately. The third requirement is use tool:ScaleTo with an argument of whatever numbers in there to upscale and downscale the tool when clicking. So, this is a special function for tools that allows you to upscale and downscale a tool, and I want you to use that whenever a player clicks and lets go. Next, I want you to use a while loop to constantly change the Handle's color until the player lets go. And then finally, the last requirement is, I want you to create PlayerStats with an IntValue called Clicks that increments every time the player clicks with the tool.
All right, so these are your challenges. You can pause the video to try this out on your own first, and then come back here. But we're still going to go through this together. Okay, so on the right side, I'm actually going to delete the second tool so that it's not confusing whenever we actually test the game. So, now we only have one tool. And the first thing I'm going to do is make sure that every player has PlayerStats, because that's the fifth requirement for this. So, on our ServerScriptService, we're going to hit the plus sign and then we're going to insert a new script. We're going to call the script PlayerAdded. Okay, we'll delete this and then we will do a PlayerAdded event by saying, game.Players.PlayerAdded:Connect(function(player) and in these arguments, we're going to pass in a player.
So, now we're going to create a folder called LeaderStats. We're going to say, local leaderStats = Instance.new("Folder") because we're creating, uh, a new folder. Uh, we're going to set the leaderStats as parent to the player, and then we're going to give it the name. leaderStats.Name = "leaderStats" and make sure this is in lowercase. And now we're going to add our Clicks value. So, we're going to say, local clicks = Instance.new("IntValue") and the parent for clicks is going to be inside of the leaderStats, and the clicks, uh, in value's name will be simply "Clicks". So, now whenever we play the game, we should be able to have a LeaderStats folder with the value Clicks in there. We're going to be using this to record how many clicks the player clicks on the tool.
Okay, so now that that's done, let's open up our tool's script, and the first thing we're going to do is play a sound whenever the tool is equipped for the first time. So, if we go back to our Toolbox, uh, we are inside of the Images section, but if we click this dropdown, we can actually see that there's a section for Audio as well. If we click, click on that, uh, Roblox has provided us, uh, a huge library of sound effects that we can put into our game. So, much like, uh, the images, we can insert this audio and then we can play it directly inside of our game. Okay, let's actually see if this, uh, audio sounds good to us. Okay, I think that's pretty good. Uh, so we're going to take the sound effect into our game by first selecting our tool and we're going to click the Insert button. This should have brought in, uh, the audio as a Sound instance inside of our tool. So, we're actually going to rename this to simply "Static" so that it'll just be easier for us to use in our script. And we're going to first make reference to our Handle inside of our script by saying, local handle = tool.Handle. And then we will make reference to our new sound that we added in. So, we'll say, local static = tool.Static.
So, now down here, uh, under our print statement for Equipped, we're going to play that sound by saying, static:Play() with the open and close parentheses. So, this is a function used by, uh, Roblox's, uh, Sound instances to be able to actually play the sound that's playing, um, so that, you know, when we equip the tool, it should play the sound, which is what we wanted to do. Uh, we will test this out, uh, after we've finished implementing everything.
So, the next thing was to create a Boolean to check if the player is holding down activation and change it appropriately. So, up here, we're actually going to create the variable, um, saying, local isHolding = false. This is going to be the variable we're going to use to check whether the player is holding, um, the, the tool or not, and by default, we're going to say false. And now, what we're going to do is, when the tool is Activated, we will set the value of isHolding to true. And, you know, when when the player lets go, we're going to set isHolding to, uh, back to false again. So, down here, we'll say, isHolding = true. And then once the player lets go, we're going to set isHolding back to false.
Our third requirement says to use tool:ScaleTo to upscale and downscale the tool when clicking. So, that's another thing we're going to do. We're going to drop a line here in Activation, and we're going to change the scale of the tool by saying, tool:ScaleTo(2). And then in these parentheses, we're going to give it a number. So, by default, the number is one, but we'll say two when it's activated. And so, down here, we're going to say, tool:ScaleTo(1) once, uh, we, once we let go of the actual thing. So, that's pretty cool.
And our last requirement is to use a while loop to constantly change the Handle's color randomly until the player lets go. So, how we're going to do that is, after we scale the tool, uh, we're going to, we're going to make a while loop. We're going to say, while and we want this to happen only when, uh, isHolding is set to true, because as soon as we let go, that's when isHolding is going to be set back to false. So, we're only going to have this loop occur when the player is currently holding the tool. So, we'll say, while isHolding do, so like, while isHolding is set to true, then we will do whatever is inside of our while loop. And what we will do is change the Handle's color to a random color. Uh, so we're going to say, handle.Color, we're not going to use BrickColor, we're going to use regular Color equals, and if you remember how to set a Color property, um, there's three ways of doing it, but the, the most familiar method that I know is using Color3.fromRGB() and then we want this to be a random color. Keep in mind, we're not just picking any color, but it's going to be random every single time. So, we're going to have to use math.random statements for each of the red, green, and blue values. So, we will say, math.random(0, 255), and then we're going to do the same thing for green and blue as well. So, we're going to say, math.random(0, 255), and then math.random(0, 255) yet again. So, it's going to pick a random color every single time.
And one important thing to remember is to add in a, um, a wait statement here, otherwise it's going to continuously, uh, run this line of code and it's going to crash, uh, Roblox Studio. So, we have to say, task.wait(), and then, uh, we can have this wait statement be something pretty small, like 0.2 or something. We can also create like a static variable up here by saying, local waitTime = 0.2, and then we could just throw in the waitTime inside of here. You don't have to do this, but, um, it does make the code look nicer when you do do that.
And now, the last thing we need to do is increment the player's clicks by one whenever the player actually does click. Now, here's a problem. We're using a Script, and we cannot access the current player's LeaderStats because this script does not specify, like, your player specifically. So, there is a workaround for that using RemoteEvents, but I haven't gotten to that yet, so I don't expect you to know that for right now. So, we're just going to hardcode this statement just for the sake of this tutorial. And what I mean by hardcode is, we're going to get, um, our literal player that's inside of the game. So, this will not work in a regular Roblox game, so I'm just going to put that out there. But essentially, what we're going to do is, we're going to say, game.Players, and we're going to try to find our, uh, our player's name because for each player, it's going to be different. So, we're going to say, :FindFirstChild() and then inside of here, we're going to put in the name of the player. Now, for me, uh, it's Brawl Battle, but for you, it's probably a different, uh, profile name. So, I would suggest changing this to yours, and then we're going to say, .leaderStats.Clicks, and then, remember, Clicks is an IntValue, but we, but we want to change the Value property of that IntValue, so we're going to say, .Value, and we're going to increment by one by saying, += 1. So, this is how you do it, and I think, uh, this is basically our entire script.
So, let's go into the game, hit Test, and hit Play so that we can see, um, our new tool that we just created for the first time. All right, so I'm in the game. If we equip the tool, um, we can actually see that our tool is pretty normal. But if we hold down our button, we can actually see that, uh, the scale of the tool, uh, changed, and also the color is of the Handle is randomly being picked every single time, uh, the loop is iterating every 0.2 seconds. If we let go, then the part goes back to, um, scale size one, and we get a click as well because the, the loop was finished so that the script could like increment the click for us. So, if we do it again, um, it's just going to do the same thing. It'll keep picking a random color for this part and, uh, keep the scale of the part to two. But then, as soon as we let go, it goes back to normal, and our clicks, uh, increment. So, we could just keep doing this for as many times as we want. It's like, kind of stupid, but I mean, it, it's still pretty cool to do. So, that was basically your challenge for this, uh, for this video. If, uh, you were able to do it, then congratulations.
So, that's the basics of tools. I've gone over the general aspects of tools, but tools are definitely going to be something you will use as a Roblox game developer for your games. Almost any Roblox game you can think of will have tools in some sort of way, and there's so many different ways of implementing tools inside of your Roblox game. This is just one of the more basic rundowns of actually creating tools and using them inside of your Roblox game. I hope you, uh, learned something new from this episode, and if you have, you can leave a comment telling me, um, like, if you find my scripting tutorials to be helpful. Uh, and also leaving a like would be very appreciative too. But that's pretty much going to be it for this episode. Join my Discord, link is in the description, and I will see you in the next episode. Take care.