Hey everyone, hope you are having a great day. I’ve seen a couple of tutorials teaching beginners how to script , and I decided to make my own tutorial aswell. So, lets get started!
First, let’s understand the very basics - printing
Print()
Print is a very basic function, which all it does is to output provided parameters into the Output
.
Examples:
print("Hello there:)") -- would print "Hello there:)"
print("hi:)") -- would print "hi:)"
print(2-5) -- would print -3
--NOTICE:
print("2-5") --WOULD NOT print -3, but "2-5".
--reason: when you're using double " , it indicates/resembles as a string.
--Since it's a string, it won't compute the value[unlike the prior one].
print(true) -- would print true
print(game.Workspace.Baseplate.Name) -- would print "Baseplate"
a = 25
print(a-5) -- would print 20
so, now that we know what Print
does, lets move onto Variables
.
Variables
Variables are names[strings] that can hold a value / values. They’re mainly useful to shorten time and work efficiently and smart.
Notice that functions
can be defined as variables aswell!
Types
1.nil [meaning doesn’t exist.
2.Numbers[such as 0,0.1,0.5,0.9,1,2,5,10,…].
3.Strings - words [such as “hi”, “hello” ,“world”].
4.Booleans [can be either true or false].
5.Tables [ arrays and dictionaries] - contain bunch of variables.
6.Enums.[Organized list of items, for e.g: list of Materials].
Examples
local MY_STRING = "My number is :"
local MY_NUMBER = 10
local MY_FUNCTION = function()
print(MY_STRING,MY_NUMBER) -- Would print : "My number is : 10"
local Num1,Num2,Num3 = 1,2,3
print(Num3-Num1,Num2-Num1,Num1-Num1) --Would print : 2 1 0
--Local means it's a local variable that can work under area its declared, for e.g:
--In this example,you can see 2 exact same variables 'x'. However, since they are both local,
--the one inside the function, would only work for the code wrapped in this function
local x = 5
function printNum()
local x = 10
print(x)
end
printNum() -- would print 10
print(x) -- would print 5
--global variables can be used anywhere, any time:
y= 5
function printNum2()
print(y)
end
printNum2() -- would print 5
print(y) -- would print 5
Well done! You now know how to use Variables
! That’s great!
Let’s move onto our next exciting part! - Functions
!
Functions
Functions are values which perform a defined task and receives thread control when called.[Meaning, it outputs results accordingly to what it’s been defined to do].Examples:
local function printWords(Word) --inside, you could put `Parameters`.
print(Word)
end
printWords("Hey there!") -- would print "Hey there!"
local function AddNumbers(num1,num2)
local sum = num1 + num2
print(sum)
end
print(AddNumbers(1,5)) -- would print 6[1+5]
--Returning [sending data back, in order to use it again]
local function MathOperation(x)
print(math.sqrt(x))
return x
end
local call = MathOperation(25) -- would print 5
print(call/5) -- would print 5
So far, doing really great! Don’t give up, we’re almost finished!
Server/Client
As you might know, every game that’s been created has 2 sides , The Server
[where all the stuff get output and conducted into the game], and The Client
[the player who plays the game].
In Roblox, there is a way to communicate these 2 , and that is - Remotes
.
Using Remotes
, will help the Client communicates the Server, and so vice versa.
Let’s say I wanted to print something [on the client], once I’ve pressed on any key on my keyboard.
So, we’d use a LocalScript
for that, right?
Correct. However, doing so, will only output the result to the Client
, and not to the Server
.
[This is the place to explain why using Remotes
is important: As you might know, exploiters are not a new trend. They have always been there. Some of them can destroy your game within minutes, or even seconds.[As long as you’re using LocalScript
's to handle the main/important stuff in your game.
Using a remote, [which will do and output your stuff from the client, on the server - is safer. Doing so, would make it harder for exploiters to change scripts and cheat in your game.]
So, what would we do?
Let’s say we have this LocalScript
in the client:
local UIS = game:GetService("UserInputService")
local RS = game:GetService("ReplicatedStorage")
local Remote = RS:WaitForChild("Remote")
UIS.InputBegan:Connect(function(KEY)
if KEY.KeyCode == Enum.KeyCode.Delete then
Remote:FireServer()
end
end)
We now need to handle / hold this on the server aswell, otherwise, why have we fired it for?
Let’s have this Script
on the server :
game.ReplicatedStorage.Remote.OnServerEvent:Connect(function(Player) --first parameter is always the place
if Player then
print(Player.Name.."has pressed on the 'Delete' button!")
end
end)
As you can see, it works! Not only does it print on the client, but also on the server!
Good job ! You now know how to communicate between The Server
and The Client
If statements
If statements
, more known as Conditional Structures
are mainly useful when you want to check for some conditions/actions and do certain actions to each of them.
Examples:
myNum = 11
if myNum % 5 == 0 then
print("my number can be divided by 5!")
else
print("Yikes")
end
local myString = "world"
local keyWord = string.lower("wor")
if string.match(myString,keyWord) then
print("found wor")
else
print("nope")
end
--using elseif
local myKey = 25
if math.sqrt(myKey) == 5 then
print(5)
elseif math.sqrt(myKey) > 5 then
print("larger")
elseif math.sqrt(myKey) < 5 then
print("smaller")
end
Woah! Do you realize how much have you learned yet?
We’re almost done ! I promise!
Loops
Loops let you execute/run/output code several times. There are some different loops to know about , on Roblox .
For Loops
--For Loop
--Lets you run a code for how many times you've set it.
--format : for number = x,y,z do (StartValue,EndValue,Increment)
--INCREMENT
for k = 0,10,0.5 do
print(k)
task.wait(.1)
end
for i = 1,10 do
print(i)
task.wait(.2)
end
--DECREMENT
for t = 10,0,-1 do
print(t)
task.wait(.3)
end
While Loops
--While Loops
--runs forever,when something is true or false.
--MUST have a delay.
local time = 10
while time > 0 do
print(time)
task.wait()
time -= 1
end
local myVar = true
while myVar do
print("running")
task.wait(1)
end
Repeat
Will run/repeat itself, until a certain condition has occurred.
--repeat
local myNum = 10
repeat
print(myNum)
myNum -= 1
task.wait(1)
until myNum == 0
print("Finished!")
Woah! That’s insane! Last thing and we’re done - I PROMISE!
Tables
Can store/contain multiple variables at once, presented as {}
Arrays
A list, contains ordered values, for e.g: Players’ ID’s.
local ARRAY = {1,2,"STRING",Color3.fromRGB(85, 170, 127)}
print(ARRAY[3]) --> "STRING"
print(ARRAY["STRING"]) --> nil
Dictionaries
Extentions of Arrays
. Unlike arrays
, a dictionary stores sets values formatted in this way ‘key-value’, for e.g : Item Name = "Sword.
--table
local dictionary = {Item1 = "Sword",Item2 = "Basketball"}
print(dictionary[1]) --> nil
print(dictionary["Item1"]) --> "Sword"
in pairs and ipairs - loops
Both are functions that are based on for loop
, and are used when using an array
or a dictionary
. They help us go through each of the parts in our table.[pairs
useful when working with dictionaries
, while ipairs
useful when working with arrays
.]
In Pairs
local dictionary = {
["Spongbob"] = "Yellow";
["Patrick"] = "Pink";
}
for index,value in pairs(dictionary) do
print(index,value)
--patrick pink
--spongbob yellow
end
Ipairs
local Players = {"Player1","Player2","Player3"}
for _,Player in ipairs(Players) do
print(Player)
--Player1
--Player2
--Player3
end
Woah! You’ve finished all this? You’re a legend! Good job!
String functions
In luau, there are several useful functions when we use/combine or work with strings, some of them are very useful. Let’s understand some of them:
string.len()
Simply returns the length
of our string. Example:
local Word = "Hello"
print(Word:len()) -- same as print(string.len(Word)), both will give 5
string.rep()
Simply will repeat
getting the provided string, for n
times [ n needs to be a provided number].
Example:
local Word = "Hello"
print(Word:rep(4)) -- same as print(string.rep(Word,4))-- both will print HelloHelloHelloHello
string.gsub()
Simply replaces a value by a given value. Example:
local Word = "Hello Guys!"
local replace = Word:gsub("Hello","Sup")
print(replace) -- Sup Guys!
string.sub()
Returns the value, but starting at a
and ends at b
. a
's ‘index’ is 1. Example:
local Word = "Hello Guys!"
print(Word:sub(5)) -- o Guys!
print(Word:sub(-5)) -- Guys!
print(Word:sub(-2)) -- s!
Here is what happens when providing negative number in sub,
We can see our last character in the string is !
, thus - when we use negative, what it does is a ‘reverse’ process. Meaning, it’ll start from the last character backwards.
TweenService
What is Tween?
A method/way to interpolate properties of instances. Including animating and adding some cool effects, there are some important points to notice:
TweenService
Can it be inserted through `instance.new()` ?
No.
Can tween same properties at once?
No. You’ll need to make a new tween for each of them.[Otherwise, only the last one would be implemented].
Does it work with strings?
No, it works only with the following types:
(number,bool,CFrame,Rect,Color3,Vector2,Vector3,Udim,Udim2,Vector2int16,EnumItem]
Unique Functions
Create()
TweenService:Create()
is the
function to create tweens, example:
local TweenService = game:GetService("TweenService")
local Part = game.Workspace.Cube
local TweenInfo = TweenInfo.new(
2,--[Time]
Enum.EasingStyle.Linear,--[EasingStyle]
Enum.EasingDirection.Out,--[EasingDirection]
-1,--[repeats,when its less than 0, it'll repeat indefinitely]
true,--[reverse]
0 --[delay]
)
--In this case, it'd increase its size until it reaches the provided size, and change its color until it reaches the provided color3.
local Tween = TweenService:Create(Part,TweenInfo,{Size = Vector3.new(50,50,50),Color = Color3.fromRGB(0, 0, 0)})
task.wait(3)
Tween:Play()
Play()
Using this function, will begin the tweening.[ works as long as there’s no other tween occurring at the moment].
Pause()
It’d stop the tweening, and if we use Play()
to resume, it’d play it from the point is paused.
Cancel()
Pauses/Stops the tween, resets the provided variables[ if resumed, the properites would still interpolate towards their goal].
Events
Completed
Fires when the Tweening has been completed.
Example:
local TS = game:GetService("TweenService")
local display = script.Parent
local open = display.Parent.Open
local close = display.Parent.Close
local isOpen = false
script.Parent.ClickDetector.MouseClick:Connect(function()
if isOpen == false then
local t = TS:Create(display, TweenInfo.new(1), {CFrame = open.CFrame})
t:Play()
t.Completed:Wait(2)
print("OPENED!")
isOpen = true
else
local t = TS:Create(display, TweenInfo.new(1), {CFrame = close.CFrame})
t:Play()
t.Completed:Wait(2)
print("CLOSED!")
isOpen = false
end
end)
Examples
BigHead Command
local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")
local TweenInfo = TweenInfo.new(
1.5,--[Time]
Enum.EasingStyle.Elastic,--[EasingStyle]
Enum.EasingDirection.InOut,--[EasingDirection]
0,--[repeats,when its 0, it'll repeat indefinitely]
true,--[reverse]
0 --[delay]
)
Players.PlayerAdded:Connect(function(Player)
Player.Chatted:Connect(function(Msg)
if Msg:lower() == "!bighead" then
local Tween = TweenService:Create(object.Character.Head,TweenInfo,{Size = Vector3.new(5,5,5)})
task.wait(1)
Tween:Play()
end
end)
end)
Combining `Touched` event
local TweenService = game:GetService("TweenService")
local Part = game.Workspace.Cube
local TweenInfo = TweenInfo.new(
1,--[Time]
Enum.EasingStyle.Quad,--[EasingStyle]
Enum.EasingDirection.InOut,--[EasingDirection]
1,--[repeats,when its 0, it'll repeat indefinitely]
false,--[reverse]
0 --[delay]
)
Part.Touched:Connect(function(obj)
if obj.Parent:FindFirstChild("Humanoid") then
local Tween = TweenService:Create(Part,TweenInfo,{Size = Vector3.new(15,50,15),Color = Color3.fromRGB(0, 0, 0)})
task.wait(1.1)
Tween:Play()
end
end)
CFrame - A Pushing Door
local TweenService = game:GetService("TweenService")
local Part = game.Workspace.Cube
local TweenInfo = TweenInfo.new(
0.2,--[Time]
Enum.EasingStyle.Quad,--[EasingStyle]
Enum.EasingDirection.InOut,--[EasingDirection]
0,--[repeats,when its 0, it'll repeat indefinitely]
false,--[reverse]
0 --[delay]
)
Part.Touched:Connect(function(obj)
if obj.Parent:FindFirstChild("Humanoid") then
local Tween = TweenService:Create(Part,TweenInfo,{CFrame = Part.CFrame * CFrame.Angles(math.rad(45),0,0)})
task.wait(1.1)
Tween:Play()
end
end)
Udim2
local TweenService = game:GetService("TweenService")
local POS = UDim2.new(0.5, 0,0.5, 0)
script.Parent.TextButton.MouseButton1Click:Connect(function()
script.Parent.Frame:TweenPosition(POS,Enum.EasingDirection.In,Enum.EasingStyle.Linear,0.5)
end)
Increasing WalkSpeed
local TweenService = game:GetService("TweenService")
local Part = game.Workspace.Cube
local TweenInfo = TweenInfo.new(
1.5--[Time]
)
Part.Touched:Connect(function(obj)
if obj.Parent:FindFirstChild("Humanoid") then
local Tween = TweenService:Create(obj.Parent.Humanoid,TweenInfo,{WalkSpeed = 150})
Tween:Play()
end
end)
Tweening Door
Debounces
Debounces
We’ll cover up 2 things within this topic:
1- Do we actually need them? And why?
2- How to use them.
What are Debounces?
Before we answer this question, I first would like you to take a glance on this code :
--Services
local players = game:GetService("Players")
--Functions
function PRINT_TESTING(CONTEXT)
print(CONTEXT)
end
function TUTORIAL_TESTING(Object)
--Defining Humanoid
local humanoid = Object.Parent:FindFirstChild("Humanoid")
--If there is a humanoid, then we can define the player
if humanoid then
--getting the player with the function GetPlayerFromCharacter - finding the Player whose character touched this brick
local player = players:GetPlayerFromCharacter(Object.Parent)
--if the player was found
if player then
--We're calling the PRINT function, and providing an argument [text] that will be printed
PRINT_TESTING(player.Name.." has touched the brick!")
end
end
end
script.Parent.Touched:Connect(TUTORIAL_TESTING)
Seems to be working fine, right?
True! However, if we press ‘Play’ and test it, we could see in the output:
Valkyrop has touched the brick!(x33)
Why has this event occurred 33 times?
You could notice that, this code will always work as long as the object that touched the brick, is a player. Since we’re not having any condition or delay that’d slow it, it’d keep printing even if we have touched the brick already!
Solution
Here, is when Debounces
are involved,
using them, will help us prevent/slow our event from occurring multiple times within a short time!
Debounces
are values
[could be a number, a string, a boolean] , the most common one to use is boolean. That can help us creating delays, and statements that could reduce/prevent our code from running multiple times within a short time!
So, now that we know debounces
are helpful /useful to prevent/reduce events /functions from occurring multiple times within a short time.
Lets apply them on our code!
First, create a variable [ you can call it whatever you want :)] , I’ll be using BooleanValue
in this code.
Place it on top , amid the Services and the Functions.
--Debounces
local Debounce = true
Now, the PRINT_TESTING function can stay as it is, we dont need to use our debounce there.
Now, inside the TUTORIAL_TESTING function, before we even define the humanoid, we’re going to make an If statement
that will allow us to run a code only if that condition/statement has happend/ is happening.
Therefore, in our case, we want to check if our Debounce
value is true, to compare stuff, we use ==
function TUTORIAL_TESTING(Object)
--Using our Debounce
if Debounce == true then
Now, we need to actually do something only if our debounce is true, so we could set it to false now [within the statement], and what’d happen is -the code after that, would run only once, because our condition is false yet.
function TUTORIAL_TESTING(Object)
--Using our Debounce
if Debounce == true then
Debounce = false
--Defining Humanoid
local humanoid = Object.Parent:FindFirstChild("Humanoid")
--If there is a humanoid, then we can define the player
if humanoid then
--getting the player with the function GetPlayerFromCharacter - finding the Player whose character touched this brick
local player = players:GetPlayerFromCharacter(Object.Parent)
--if the player was found
if player then
--We're calling the PRINT function, and providing an argument [text] that will be printed
PRINT_TESTING(player.Name.." has touched the brick!")
end
end
As we can tell, it still doesn’t do anything, right?
It’s because we didn’t add the actual delay and set our debounce back to true.
To do so, all we need to do is to add a task.wait()
when the if humanoid
statement ends
if humanoid then
--getting the player with the function GetPlayerFromCharacter - finding the Player whose character touched this brick
local player = players:GetPlayerFromCharacter(Object.Parent)
--if the player was found
if player then
--We're calling the PRINT function, and providing an argument [text] that will be printed
PRINT_TESTING(player.Name.." has touched the brick!")
end
end
--Creating a delay
task.wait(3) -- you could put inside, how many seconds you want the delay to be lasting for
And lastly, we want to make sure our Debounce is set up to true, so all we need to do is :
--Creating a delay
task.wait(3) -- you could put inside, how many seconds you want the delay to be lasting for
Debounce = true
Our final code :
--Services
local players = game:GetService("Players")
--Debounces
local Debounce = true
--Functions
function PRINT_TESTING(CONTEXT)
print(CONTEXT)
end
function TUTORIAL_TESTING(Object)
--Using our Debounce
if Debounce == true then
--Changing the value so that the code would run only once, until the next time[after the delay]
Debounce = false
--Defining Humanoid
local humanoid = Object.Parent:FindFirstChild("Humanoid")
--If there is a humanoid, then we can define the player
if humanoid then
--getting the player with the function GetPlayerFromCharacter - finding the Player whose character touched this brick
local player = players:GetPlayerFromCharacter(Object.Parent)
--if the player was found
if player then
--We're calling the PRINT function, and providing an argument [text] that will be printed
PRINT_TESTING(player.Name.." has touched the brick!")
end
end
--Creating a delay
task.wait(3) -- you could put inside, how many seconds you want the delay to be lasting for
Debounce = true
end
end
script.Parent.Touched:Connect(TUTORIAL_TESTING)
Mouse
**NOTE: Mouse
is deprecated. UserInputService
& ContextActionService
are better.
Hello fellow devs and builders, I decided to make a tutorial for beginners - on Mouse
.
Note
I know there’s a tutorial on it on the devhub, I decided to elaborate a bit and give various examples from my prespective view.
What is A Mouse
?
I believe it’s pretty obvious, Mouse
is our cursor, and with it, we can do many things that we want to happen after doing something with our cursor.
Some Events
Icon
Changes the cursor’s Icon, example:
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
Mouse.Button1Down:Connect(function()
Mouse.Icon = "rbxasset://SystemCursors/OpenHand"
end)
Button1Down
Fires when the left mouse is pressed, example:
--Client
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
Mouse.Button1Down:Connect(function()
print("Left Mouse has been pressed!")
end)
Button1Up
Fires when the left mouse is released. Example:
--Client
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
Mouse.Button1Up:Connect(function()
print("Left Mouse has been released!")
end)
Button2Down
Fires when the right mouse is pressed.Example:
--Client
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
Mouse.Button2Down:Connect(function()
print("Right Mouse has been pressed!!")
end)
Button2Up
Fires when the right mouse is released. Example:
--Client
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
Mouse.Button2Up:Connect(function()
print("Right Mouse has been released!!")
end)
Idle
Fires as long as there is no another Mouse
event occurring at the moment, if there is, it’ll fire slowly [heartbeats]. Example:
--Client
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
Mouse.Idle:Connect(function()
print("Idle!")
end)
Move
Fires when the cursor is moving. Example:
--Client
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
Mouse.Move:Connect(function()
print("Moved")
end)
WheelBackward
Fires when the wheel on your mouse moves backwards . Example:
--Client
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
Mouse.WheelBackward:Connect(function()
print("Moved backwards")
end)
WheelForward
Fires when the wheel on your mouse moves forwards. Example:
--Client
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
Mouse.WheelForward:Connect(function()
print("Moved forwards")
end)
Examples:
Change Colors on Touch
--Client
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
local Replicated = game:GetService("ReplicatedStorage")
local remote = Replicated:WaitForChild("Remote")
Mouse.Button1Down:Connect(function()
if Mouse.Target and Mouse.Target.Parent then
remote:FireServer(Mouse.Target)
end
end)
--Server
game.ReplicatedStorage.Remote.OnServerEvent:Connect(function(Player,MouseClick)
MouseClick.BrickColor = BrickColor.new("Really blue")
end)
TP Tool
--Client
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
local Replicated = game:GetService("ReplicatedStorage")
local remote = Replicated:WaitForChild("Remote")
Mouse.Button1Down:Connect(function()
if Mouse.Target and Mouse.Target.Parent then
remote:FireServer(Mouse.Hit)
end
end)
--Server
game.ReplicatedStorage.Remote.OnServerEvent:Connect(function(Player,MouseClick)
Player.Character:MoveTo(MouseClick.p)
end)
Get a Vector3
--Client
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
local Replicated = game:GetService("ReplicatedStorage")
local remote = Replicated:WaitForChild("Remote")
Mouse.Button1Down:Connect(function()
if Mouse.Target and Mouse.Target.Parent then
remote:FireServer(Mouse.Hit)
end
end)
--Server
game.ReplicatedStorage.Remote.OnServerEvent:Connect(function(Player,MouseClick)
print(MouseClick.p)
end)
Hope I could help , Don’t forget to practice,practice and practice.
Best of luck!