How do script [ Update Version]2022/2023

Introduction

Hey there! TodayI will be teaching you how to script from scratch - all the basics you need to know when coming to script on Roblox with a better and updated version!

[If you’re a beginner] After this tutorialyou should learn:

  • Understand the very basics of scripting on Roblox.

In this tutorialwe’ll be talking about:

  • VariablesDataTypes.
  • AttributesProperties.
  • Math library.
  • Conditions,FunctionsLoops.
  • ReturnRemotes.
  • Gamepasses,DevProducts.
  • Tools,PlayerCharacterAnimation.
  • TweenServiceCamera.
  • ClickDetectors & ProximityPrompts.
  • Mouse & UserInputService.

Anticipation and expectations

Looklike every other profession/hobbiesit doesnt take straight away to success in learning something new. It is a processit might be short or long waybut you can’t escape the process. The result doesn’t matter. What matters is the process done throughout the way. Because during thatyou’re learning how to be betterand how to struggle with multiple conditions.

Sowhat does scripting mean?

When you’re scripting/programmingyou’re actually manipulatingcustomizingand making cool stuff using an existing program/system. Meaningyou’re providing instructions to your computer - telling it what to doand how do you want to acheive your goal by doing what I mentioned above.

On Robloxyou could think of scripting as the Scenes in the back of each game on the platform. And every game you see on Robloxwas made by people who scripted and wrote codes to run these games properly and playable.

Let’s dive into the sea!

So now that we know what we are doing and what stands behind itwe should start learning how to implement and write our first codes which would eventually lead to a long process that at the endwe’ll be ready to make our own games.

Part 1

Variables

A variable is basically a name[ string ] that can hold / have any value.
Very impotant! There are few keys that you can not use as variablesand those are:


Defining a variable should look like this:

local myVar = 5
--OR
myVar = 5

The difference between the 2 ways is: first one is localwhereas the second one is global[ which is slower by the way]. You could see that difference in the following example:

--Local Variable
local myVar = 0
for k = 1,10 do
	local myVar = 0
	myVar += k
	print("myVar now equals to: "..k) -- 10
end
print("myVar now equals to: "..myVar) -- 0


--Global Variable
myVar = 0
for k = 1,10 do
	myVar += k
	print("myVar now equals to: "..k) -- 10
end
print("myVar now equals to: "..myVar) -- 55
DataTypes

A DataType in programming means classifying values and specifying their variables with value types. [For example : stringnumberbooleantablenil]. In addition to thatit also determines what type of mathematicalrelational or logical operations can be applied to itwhich would eventually lead us to different results depending on what we used.

Data Types On Roblox!

On Robloxwe have 6 types of Data Typeslet’s review them and see what they are and what they do.

1. Nil

On Robloxthe nil value means nothing/doesn’t exist. And what it does is remove the object/value from your game or and/or its reference. Moreeverluau [ Roblox language] has a garbage collector which basically removes any data/references which are not used/accessible by any script. Let’s see an example:

local part = Instance.new("Part")

--Properties
part.Name = "Test"
part.Color = Color3.fromRGB(85255255)
part.Size = Vector3.new(1,1,1)
part.Transparency = 0.5
part.Position = Vector3.new(0,5,0)

--Parenting it
part.Parent = workspace
print(part) -- Test

--Delay
task.wait(3)

--Re-parting it and removing itso you can't see it.
part.Parent = nil
print(part,part.Parent) -- Testnil

--Removing part reference
part = nil
print(part) -- Nil

As you can seethe code above creates a partchanges some of its propertiesparents it into workspaceand then to niland then setting the part itself to niland as you should’ve noticed :
Although we parented the part to nilwe still had its referencehence that’s why the second print returned us the partwhereas the last print returned nil because we removed the part’s reference.

2. Boolean

The boolean value can have 2 values - true or false. Notice that if you set the bool’s value to nilit would return you false. An example:

local value = Instance.new("BoolValue")

value.Name = "Boolean"
value.Value = nil
value.Parent = workspace

print(value,value.Value) -- Booleanfalse
3. Numbers

A number value represents any possible number. Including decimalszero and negatives. It is also important to know its limits:
Range: from : -1.7 × 10308 to 1.7 × 10308 (around 15 digits of precision)

An int value represents any possible integers. Including zero and negatives.
Trying to set an intvalue’s value to a decimal numberwould give you the following error:
Unable to cast string to int64.
It is also important to know its limits -
Range: from: -2 ^ 31 to 2^31 - 1.

Note:
When you’re trying to set an int/numbervalue’s value to nilit’d return 0. And when you’re trying to set an intValue’s value to a decimalit’d round that number to its closest int value. [ see example below].

The following example is simply creating an IntValue and a NumberValueand tries to set its values to different time of values.

------Creating an IntValue-------
local Int = Instance.new("IntValue")
Int.Name = "Int"
Int.Value = 10
Int.Parent = workspace

------Creating a NumberValue-------
local Num = Instance.new("NumberValue")
Num.Name = "Num"
Num.Value = 10
Num.Parent = workspace

------Setting their values to different values-------
Int.Value = nil
print(Int.Value) -- 0

Int.Value = 10.5
print(Int.Value) -- 11

Num.Value = nil
print(Num.Value) -- 0
4. Strings

A string value is simply a sequence full of characters [ lettersnumbers and symbols].

Declaring Strings On Roblox:
There are multiple ways to define/delcare a string on RobloxI will show 3 of them:
1.double quotes (")look at the example below to see.
2.single quotes (')look at the example below to see.
3.double brackets ([[)look at the example below to see.

The following example simply delcares multiple strings in all 3 ways mentioned above.

------------Defining Strings------------
local String1 = "Hey! This is a string!"
local String2 = '1+1 = 2! This is a string too!'

local String3 = [[
"Hello!"
'Hello!'
]]

------------Printing Strings------------
print(String1) -- Hey! This is a string!
print(String2) -- 1+1 = 2! This is a string too!
print(String3) -- "Hello!"
               -- 'Hello!'

Converting Strings → Numbers and vice versa.
There are multiple times when you would prob need to convert a string into a number [ or vice versa]a fresh example would be: Say you have a TextBox which lets you redeem players’ IDsand you want to use the input to do something. You notice that that number is passed as a string. Not as a number.
That’s where tonumber() and tostring() get involved.

tonumber()
This function would convert your string into a number [ if possible].

tostring()
This function would convert your value into a string [ if possible].

The following example would try to convert both a string → numberand number → string.

local Number = 1
local String1 = "Hello"
local String2 = "1"

print(Number + String2) -- 2! Since `String2` can be defined as a number althought its variable defined as a string.
print(Number + String1) -- Error! attempt to perform arithmetic (add) on number and string.

print(tonumber(String2)) -- 1
print(tonumber(String1)) -- nil

print(tostring(Number)) -- 1
print(tostring(String2)) -- 1

Combining Strings
To combine 2 [ or more] stringsyou’ll need to use this: .. . See example below:

local String1 = "Hello"
local String2 = "World"
local String3 = 5

print(String1.." "..String2) -- "Hello World"
print(String1..String2) -- "HelloWorld"
print(String1..String3) -- Hello5
5. Tables

Think of tables as big containers which contain multiple types of variables [ except for nil].
There are ‘2 types of tables’ that you’ll see:

Arrays

A list with an ordercontaining multiple types of values. An example:

local myArray = {"Hello",1,game.Workspace.MyPart,true)

As you can seemyArray contains 4 types of values: stringnumberobject and a boolean [ accordingly].

Notes:
To get a value/ read from an arraysimply put a [] and the index within. For example:

print(myArray[1]) -- would print "Hello"
print(myArray[6]) -- nildoesnt exist.

To replace an exisiting value within an arraywith something elseyou should call the index of the value you want to changeand put in within the [ ] when calling the arrayan example:

local myArray = {"Hello",1}
print(myArray[1]) -- "Hello"

myArray[1] = 2
print(myArray[1]) -- 2

Functions For Arrays:
There are multiple functions to work with when using arrayshere is the list of them:
-table.clone()
-table.find()
-table.getn()
-table.maxn()
-table.move()
-table.pack()
-table.sort()
-table.clear()
-table.concat()
-table.create()
-table.freeze()
-table.insert()
-table.remove()
-table.unpack()
-table.foreach()
-table.foreachi()
-table.isfrozen()

I will exaplain 4 of them:
1.table.getn(): returns the amount of items your array has. An example:

local mytab = {1,2,6}
print(table.getn(mytab)) -- 3

2.table.insert(): inserts the provided value into the provided table. An example:

local mytab = {1,2,6}
print(mytab[4])--nil
local newValue = table.insert(mytab,5)
print(mytab[4]) -- 5

3.table.concat(): returns all the values in your arrayseparated with the given symbol. An example:

local mytab = {1,2,6}
print(table.concat(mytab,"!")) -- 1!2!6!

4.table.clear(): clears all the values from the given table. Meaning it sets those values to nil. An example:

local mytab = {1,2,6,"hey"}
print(mytab[1],#mytab) -- 1,4
table.clear(mytab)
print(mytab[1],#mytab)-- nil,0

Iterating/Looping over arrays:
To loop over an arraysimply use the global ipairs() [or pairs()depending on your use] function in a for loop. You should also remember that arrays have numerical indiceswhich means - you can also use a numeric for loop from 1 to the length of the array (#array).
An example:

local tab = {4,3,2,1.2}

for index,value in pairs(tab) do
	print(index,value)
end

print("------------------------")

for index,value in ipairs(tab) do
	print(index,value)
end

The difference is that if there was a nil value within the tablepairs would continue countingbut without the nil index. Whereas ipairs would stop at one index before the nil valueand won’t continue.

Dictionaries

Extention of arrays.Unlike arraysdictionaries contain a set of key-value pairs. (where the keys can be any numberstringor object.) An example:

local dictionary = {
	Key1 = "Bell"-- Key,Value
	Key2 = "Steve"--Key,Value
	Key3 = 500 --Key,Value
}
print(dictionary)

To replace an exisiting value within a dictionarysimply specify the key of that value within a couple of []. An example:

local dictionary = {
	Key1 = "Bell",
	Key2 = "Steve",
	Key3 = 500
}
print(dictionary["Key1"]) -- Bell
dictionary["Key1"] = 5
print(dictionary["Key1"]) -- 5

To add new valuessimply specify a key within a [ ]. An example:

local dictionary = {
	Key1 = "Bell",
	Key2 = "Steve",
	Key3 = 500
}
print(dictionary["Key4"]) -- nil
dictionary["Key4"] = 5
print(dictionary["Key4"]) -- 5

Iterating/Looping over dictionaries:
Notice! ipairs only works with arraysso don’t try to use ipairs on dictionaries [unless you have made custom functions which would help you with that].

Notice! using pairs would NOT necessarily return you the items in a specified orderit’s random.
A solution could be as the following:

--Our dictionarycontaining multiple keys.
local dictionary = {
	Key1 = 5,
	Key2 = 25,
	Key3 = 500,
	Key4 = 210
}
--A table[to be an array] that will store our values from the dictionary
local values = {}

--A for loopto loop over our dictionary and then insert the values into our 'values' array
for key,value in pairs(dictionary) do
	table.insert(values,value)
end

--Using 'table.sort' to sort our values with an order. function(a,b) would determine what order we want to have
table.sort(values,function(a,b)
	return a<b
end)

--Printing our 'new sorted' dictionary
print(values)
6. Enums

Enums ( stands for enumeration ) are numbers which can take on specific sets of values. To access any type of enumyou should start with Enum.an example:

local Part = Instance.new("Part")

Part.Name = "Block"
Part.Color = Color3.fromRGB(2551700)
Part.Shape = Enum.PartType.Ball
Part.Name = "Ball"

Part.Parent = workspace

The above example creates a new partchanges few of its propertiesand then switch its shape into a Ball. Nowwe could alternatively change its shape like this:

Part.Shape = "Ball"

But this isn’t the best wayand might be a little problematic.
Nowif you’re curiousyou could go and put another . after the Balland you’ll see: NameValue and EnumType. And if you try to print thoseyou’d get:

print(Part.Shape.EnumType,Part.Shape.Name,Part.Shape.Value) -- PartTypeBall0

Each Enum has a Value [ a number]a Name[ string]and a EnumType [enum].
If you want to get the entire list of available enumsyou’ll need to go to the DeveloperHub.

Notes:
To get all items of an enumuse GetEnumItems(). An example:

local PartEnums = Enum.PartType:GetEnumItems()

for index,value in pairs(PartEnums) do
	print(value)
end

--[[
	Enum.PartType.Ball
	Enum.PartType.Block
	Enum.PartType.Cylinder
]]
Properties & Attributes

In this sectionwe’ll be learning about Properties and Attributes[ custom properties].

Sowhat are properties?

Properties allow you to adjust and change the look & behaviour of certain objectsyou can change some of them manually through VIEWPROPERTIES.In the following examplewe’re changing multiple properties of a Part :

------Inserting a Part------
local Part = Instance.new("Part")

------Editing some properties------
Part.Name = "Hey there" -- chaning its name
Part.Size = Vector3.new(5,5,5) -- changing its size
Part.BrickColor = BrickColor.random()  -- changing its BrickColor to a random one
Part.Anchored = true -- setting its anchored to trueso that it won't fall from air

------Parenting it to workspace------
Part.Parent = workspace

Attributes

Attributes are custom properties which allow you to customize and edit your own properties on objects.
Attributes can be used in these cases:

To manually create an attribute you should go to your object’s propertiesscroll down until you find Add Attributes button.

To create an attribute from a scriptwe will use the SetAttribute() methodand insidewe’ll provide 2 arguments : 1.Attribute Name2.Attribute Value.

local Part = script.Parent
Part:SetAttribute("NewProperty",50)

To get an exisiting/created attribute from your objectwe will use GetAttribute()and provite it 1 argument - the attribute’s name. [Noticeyou could also use GetAttributes() [don’t provide anything]it would return you a table of all your object attributes.

local Part = script.Parent

-----Setting the Attribute------
Part:SetAttribute("NewProperty",50)

-----Calling the Attribute------
print(Part:GetAttribute("NewProperty")) -- 50

To simply delete an attributeset its value to nil.

local Part = script.Parent

-----Setting the Attribute------
Part:SetAttribute("NewProperty",50)

-----Removing the Attribute------
Part:SetAttribute("NewProperty",nil)

To detect when an attribute has changedwe will use either GetAttributeChangedSignal(AttributeName:string) or AttributeChanged(). See the example below:

local Part = script.Parent

-----Setting the Attribute------
Part:SetAttribute("NewProperty",50)

-----Detecting Attribute Changes------
Part:GetAttributeChangedSignal("NewProperty"):Connect(function()
	print(Part:GetAttribute("NewProperty"))
end)
Math Functions

In this sectionwe’ll be learning some of the most useful functions there are in luau math library. Let’s begin! (If you’re interested in seeing all math functionsplease visit Math Library - Roblox DebHub.)

math.abs(x:number):

abs stands for absolute. Meaning it returns you the absolute value of the number.

print(math.abs(-5)) -- > 5

math.ceil(x:number):

ceil stands for ceiling. Meaning it rounds your number up to the closest integer.

print(math.ceil(5.21)) -- > 6

math.floor(x:number):

This function rounds your number down to the closest integer.

print(math.floor(5.21)) -- > 5

math.clamp(x:number,minimum:number,maxmium:number):

This function checks the first given numberand checks if it’s within the minimum & maximum range. There are 3 possible conditions:

A. That number is within the range. Result: we should get the exact same number.
B. That number is bigger than the maximum. Result: we should get the maximum number.
C. That number is smaller than the minimum. Result: we should get the minimum number.

print(math.clamp(1,0,10)) -- > 1
print(math.clamp(-1,0,10)) -- > 0
print(math.clamp(25,0,10)) -- > 10

math.min(x:number,…:number):

Simply returns the minimum[smallest] number among the passed numbers.

print(math.min(-5,25,-10,0,15,1)) -- -10

math.max(x:number,…:number):

Simply returns the maximum[biggest] number among the passed numbers.

print(math.max(-5,25,-10,0,15,1)) -- 25

math.random(x:number,y:number):

Simply returns a random number within the range of these 2 numbers.

print(math.random(1,100)) -- > 66

(If you’re interested to get decimals aswellyou might want to use the following:)

local random = Random.new()
print(random:NextNumber(1100)) -- 82.012

math.sqrt(x:number):

Simply returns the squre root ot the given number.

local number = 25
print(math.sqrt(number)) --- 5

Notice that when you’re trying to do: math.sqrt(-number) [number > 0]this would return you nan [ not a number].

math.pow(x:number,y:number):

Simply returns you x to the power of y.

local a = 2
local b = 5
print(math.pow(a,b)) -- 2 ^ 5 = 32

math.rad(angle:number):

Simply returns you the given angle[degrees] but in radians.

local AngleInDegrees = 90
print(math.rad(AngleInDegrees)) -- 1.5707

math.deg(angle:number):

Simply returns you the given angle[radians] but in degrees.

local AngleInDegrees = 90
local AngleInRadians = math.rad(AngleInDegrees)

print(math.deg(AngleInRadians)) -- 90

math.round(x:number):

Simply returns you the closest integer to that number.

local a = 25.666666666666666666666
local b = 25.111111111111111111111

print(math.round(a)) -- 26
print(math.round(b)) -- 25

math.log(x:number,y:base):

Simply returns you the logarithm of xwith the base of y.

local num = 8
local base = 2

print(math.log(num,base)) -- 3since 2^3 == 8

Numbers with math. :

math.pi: A number. Equals [ approximately] to 3.14159265359.
math.huge: A huge number. Would return you inf if you printed math.huge.

If Statements

If statements are conditional statements. Meaning - code inbetween the if statement would only run under specified condition.Let’s see some examples:

local myVar = false

if myVar == true then -- if our variable equals to truethen..[condition 1]
	print(true)
else -- if notmeaning it equals to false [because booleans have only true / false conditions]then..[condition 2]
	print(false)
end

As you can seewhen we run this codeit prints false. Simply because the first condition didn’t happen because it wasn’t true. But the ncame the second condition [ the else]. And checked if this
can happenand it did.

Nowhere are some tips/notes :
1.Instead of doing if myVal == trueyou could simply do if myVal
2.Do not get confused! = is used when we set change or define variables. Whereas == is used to compare between conditions.

The following example would check if the script.Parentwhich is a Part hereis transparent or notand act accordingly:

local Part = script.Parent

if Part.Transparency == 1 then
	print(Part.Name.. " is transparent!")
else
	print(Part.Name.." is visible!")
end
Loops

Before we get into what loops are. Let’s say we have a code that runs onceand we want to run it multiple times. How’d we do that? Obviouslythere are several ways to do thatbut we’ll focus on loops. Using a loop will help us run our code for more than once. And that’s what loops basically do - some loop through values / objects whereas others would just run the code multiple times.
Let’s review some of the loops we have on Roblox:

The for k = a,b,c loop.

for k = 0,10,1 do
	print(k)
end
--This would print all numbers from 0 to 10.

Nowyou might be wondering what are these 3 numberslet’s have a look here:
for k = a: Is the ‘control variable’in fact - that would be our variable and starting point.
b: Is the end value where that loop should stop at.
c: The increment value. By what numberdo we want to increase/decrease the count.

Let’s now see an example where we decrease the value.

--This would not runsince we can't really increase 10 by 1 to reach 0.
for k = 10,0,1 do
	print(k)
end

--This would count from 10 to 0-1 is the value we decrease the count by.
for k = 10,0,-1 do
	print(k)
end

The for index,value in pairs() / in ipairs() loops.

local tab = {1,2,3,4,nil,5,6}

for index,value in pairs(tab) do
	print(index,value)
end

--[[
	1 1
	2 2
	3 3
	4 4
	6 5
	7 6
]]

print("------------------------")

for index,value in ipairs(tab) do
	print(index,value)
end

--[[
	1 1
	2 2
	3 3
	4 4
]]

Let’s understand and review what’s going on here. So firstwe have a table - containing few number values and 1 nil value. Both loops would loop through the items[values] within the table and print their index + value. If sowhy do we get different results?
The answer is:
ipairs would stop once it finds a nil value within the table.
Whereaspairs would just ignore that nil value and continue to the end.

As we mentioned when we talked about tables. pairs is a loop that would run for both types of tableswhereas ipairs would only run for arrays.

The While Loop

while true do
	--Code here would run foreveras long as the condition is met
	--Notice that without putting a delaythis would crash your game!
	--That's whyyou should always have a task.wait()
	task.wait() -- you can choose any number you wantdepending on your needs.
end

Let’s analyze this code,
so we first have this line while true dowhich basically would run foreveras long as the condition is true/met.

You might be askingbut why do we need that task.wait()?
The answer is simple! If you tried to run a while loop without a delaythis would crash your studio/gameand that - we don’t want.

Breaking a While Loop

local Elapsed = 0
local Limit = 10

while true do
	print("Looping...")
	task.wait(1)
	Elapsed += 1

	if Elapsed == Limit then
		break
	end
end

print("Loop interupped/stopped.")

Let’s analyze the codeso we first have 2 variables at the top.
Elapsed is the initial value we’re counting on.
Limit is the maximum number we want the counting to go on.

Nextwe’re having a delay of 1 secondand then we’re adding +1 to our initial value.

if Elapsed == Limit then
    break
end

This if statement is checking if we’ve reached the maximum number we want to add to our countingand if it didwe break the loop. Which meansthe loop will stop.

Functions

In this sectionwe’ll be learning about all basic types of functions you’ll need to know when scripting on Roblox. You could view functions as alot of thingsone common way is as machines with defined tasks. And if we want to be a bit more accurate functions are values that take up memory receives thread control when called and can be anonymous. Where the goals are portabilitysimplicitysmall sizeand scripting.

Define A Function:

local function myFunction() -- myFunction is the name of the function.
	--Any code herewould run only when the function is called
end

Nowyou might be asking 2 things:
1.When I run this codeit doesnt do anythingwhy?
2.What if I wanted to put values in the ( )?

Parameters & Arguments

Let’s answer these questions and see how to implement it.
1.In order to make it actually do something/what the function is defined to doyou need to call the function. You can do this by declaring the function’s name.

local function myFunction() -- myFunction is the name of the function.
	print("This function is now running!")
end

myFunction() -- Calling the function to begin

2.If we wanted to provide values into our functionthat’s what parameters are for!
Parameters allow us to edit and modify objects/values within our functions. You now might be wondering - how do I set parameters and use them? Let’s take a look here:

local function myFunction(String1,String2) -- myFunction is the name of the function.
	print(String1..String2) -- Hello!World
end

myFunction("Hello!","World") -- Calling the function to begin

As we can seewe have 2 parameters in out function - String1 and String2.
And you might notice that when we’re calling the function,we provided 2 values,[ in this case2 string values] - those are called arguments. And it is important to match them accordingly. What I mean is:
Hello!String1
WorldString2.

Returning data

Let’s assume we have the following function:

local function SumNumbers(n1,n2)
	local sum = n1+n2
	print(sum)
end

SumNumbers(1,2) -- > 3
SumNumbers(2,5) -- > 7
SumNumbers(2,5-2) -- > 5
SumNumbers(2,3)-5 -- > error

We can conclude a few conclusions:
1.We can call the function multiple times with different arguments.
2.We can’t perform any arithmetic actions with the result of the function yet.

And nowa question is asrising - how can we get the result [ the sum in this case]and perform arithmetic actions on it? The answer is return! Returning any data we want from the functionwill help us use that data later onagain and again. Let’s return sum and see what happens:

local function SumNumbers(n1,n2)
	local sum = n1+n2
	return sum
end

local CallingFunction1 = SumNumbers(1,2) 
print(CallingFunction1) -- 3


local CallingFunction2 = SumNumbers(1,2) + 5 
print(CallingFunction2)  -- 8


local CallingFunction3 = CallingFunction1 + CallingFunction2
print(CallingFunction3) -- 11

You can notice that since we’re returning data and want to use itwe’re setting our function call as variables. This also allows us to easily do our stuff much faster. We could also do this if we wanted:

local function SumNumbers(n1,n2)
	local sum = n1+n2
	return sum
end

local CallingFunction1 = SumNumbers(2,3) 
print(CallingFunction1 / 25) -- 0.2since 5/25 is 1/5 which is 0.2

Anonymous Functions

So farwe’ve seen functions with names. But nowit’s time to learn a ‘new type’ of functions - the anonymous functions! They do not have namesand they’re usually connected to an event / callback. Let’s take a look:

local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(Player)
	print(Player.Name.." has arrived!")
end)

I am sure all of you have seen this event and used alot of it. What it does is basically calls an event [PlayerAdded] which is an event for the Players service and connects it to a function. Within that functionwe can provide a parameterwhich refers to the player who joined in the game. This is useful in so many cases.

Variadic Functions

Variadic Functions are functions that can accept an unlimited amount of arguments.[take for example the print() function:

print("Hello there John! did you know that :",1,"+",1,"=",2)
print(string.format("This %s is a %s!""post""tutorial")) -- This post is a tutorial!

Calling a Variadic Function with Arrays

Let’s assume we had the following array local array = {2,4,8,10,12}
We could do the following:

local array = {2,4,6,8,10,12}
print( "The first 5 even numbers are:"unpack(array))

Which basically ‘gets out’ all the items from the array and arrange them in the string.

Part2

In the comment belowsince we have a 50k characters limit.

Wait! So how do I make a game?

That’s a good question! Here are some tipsthat some of them are given from some successul developers on Roblox:

1.Don’t give up! Keep going!
2.Try learn from free modelssee the logic behind it!

Resources to learn from

HereI am giving you some very helpful resources which would help you understand scripting better and how to move onstep by step.

Roblox ‘DevHub’ [now named Docs]:
This is probably one of the bestif not the best resource you can learn scripting from.

Feedback

It took me about 2-3 days to make this post [ organize and work as hard as possible to make it the best I could do].
And I would be very delighted to hear from all of youis there anything I forgot/was wrong about?
if soit’d be wonderful if you sent me a dm here on Robloxand tell me what should be improved!

  • It’s flawless ! I found this helpful!
  • Although I am not a beginnerI like it!
  • It’s very good! Feels like could’ve been a bit betterbut good job.
  • Overallit’s pretty nice for beginners!

0 voters

Your feedbacks will help me improve myself for the next tutorial!

Thank you! And best of luck!

159 Likes

Part 2

Remote Events & Functions

In this sectionwe’ll be talking about Remote Events & Remote Functions + how to secure them as much as possible.

Introduction:

So firstwhat are they and why do we need them?
To those of you who didn’t knowback then - before Roblox changed and updated their filterenabled system & securityexploiters could basically do any type of exploit they wanted - it was a disastertons of exploits that ruined some good & popular games. And that’s when Roblox have decied to add remote event and functions. This wouldn’t completely stop exploiters thobut it SIGNIFICANTALLY changed and fixed tons of issuesincluding patching alot of exploits that no longer work.

Idea:

As mentioned abovethe idea of using RemoteEvents and RemoteFunctions is to help us handle our game as correctly as possibleand to protect our game from being completely ruined. From the moment they were addedwe now can use them to prevent exploiters from doing some crazy and weird exploits. Le’ts begin!

Remote Events

A remote event allows us to : one-way communicate across the client-server boundary. You can use it to send requests across the boundary without yielding for a response.[ Meaning: You could use these to handle things on the server / client when needed.

When can I use remote events ?
Remote events are good to use in these cases:

Client --> Server

Using this to fire an event from a certain client[player] to the serverso that everyone could see those changes. Let’s have an example:

--Local ScriptStarterGui
local Replicated = game:GetService("ReplicatedStorage")
local UserInput = game:GetService("UserInputService")

local Remote = Replicated:WaitForChild("ClientServer")


UserInput.InputBegan:Connect(function(Key,IsTyping)
	if IsTyping then return end -- if he's typing in chat/anything like that.
	if Key.KeyCode == Enum.KeyCode.K then
		Remote:FireServer("string1",Color3.fromHSV(0.0560.5019611),25)
	end
end)


--Server Script
local Replicated = game:GetService("ReplicatedStorage")
local Remote = Replicated.ClientServer

Remote.OnServerEvent:Connect(function(Player,arg1,arg2,arg3) -- Player is the player who fired the remote.
	--Let's check their typesto see that an exploiter didn't provide a not matching type
	--If the types are not matchingwe end the function.
	if typeof(arg1) ~= "string" and typeof(arg2) ~= "Color3" and typeof(arg3) ~= "number" then return end
	print(Player.Name.." has fired a remote!")
end)
Server --> Client
--Server Script
local Replicated = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local Remote = Replicated.ServerClient

Players.PlayerAdded:Connect(function(Player)
	Remote:FireClient(Player,Player.Name)
end)

--Local ScriptStarterPlayerScripts
local Replicated = game:GetService("ReplicatedStorage")
local Remote = Replicated:WaitForChild("ServerClient")


Remote.OnClientEvent:Connect(function(Player)
	game:GetService("StarterGui"):SetCore("ChatMakeSystemMessage",{
		Text = string.format("Hey %s welcome to the game!",Player);
		Color = Color3.fromRGB(85255127)
	})
end)
Server --> All Clients
--Server Script
local Replicated = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local Remote = Replicated.ServerClients

Players.PlayerAdded:Connect(function(Player)
	Remote:FireAllClients(Player.Name)
end)

--Local ScriptStarterPlayerScripts
local Replicated = game:GetService("ReplicatedStorage")
local Remote = Replicated:WaitForChild("ServerClients")


Remote.OnClientEvent:Connect(function(Player)
	game:GetService("StarterGui"):SetCore("ChatMakeSystemMessage",{
		Text = string.format("%s  has joined the game!",Player);
		Color = Color3.fromRGB(255170127)
	})
end)

As you can see hereon the server sidewe’re using FireAllClients() functionwhich would fire/ notify every client[player] in the gameabout the given event/message provided / made on the client. Note: the message could’ve been made on the server and sent as the second argument within the FireAllClients().
On the client sidewe use game:GetService("StarterGui"):SetCore() to create a message on chatso that everyone in-game can see that.

Client --> Other Client

This can’t be directly doneso it has to be through the server. Here is how:
You can use FireServer() to share the server with the changesthen on the serveruse FireClient() or FireAllClients() to fire the client[s] ,and then use OnClientEvent() on the client to do the stuff.

Remote Functions

A remote function unlike remote eventsallow us to two-way communicate across the client-server boundary. You can use it to send requests across the boundary and yield for a response. Here it what it means:

Player1: Invokes the server [ using InvokeServer()]thenon the server ,he returns something [ most commonly is booleans]and then - on the clienthe can use that result after he assigned the InvokeServer() call as a variablelike this -local call = remote:InvokeServer(). (This is very useful when we want to make a code redeeming systemfor exampleor even a trade system).

When can I use remote functions?
Remote functions are good to use in these cases:

Client -- > Server
--LocalScriptunder a `ScreenGui`.
local Replicated = game:GetService("ReplicatedStorage")
local Remote = Replicated:WaitForChild("ClientServer")

local Button = script.Parent.Release
local Input = script.Parent.Input
local ResultText = script.Parent.Result

Button.MouseButton1Click:Connect(function()
	local Result = Remote:InvokeServer(Input.Text)
	if Result then -- if the code was valid
		ResultText.Text = "SUCCESS" 
	else -- if the code wasnt valid
		ResultText.Text = "FALED"
	end
	task.wait(3)
	ResultText.Text = "" -- 'making the text invisible - no text'
end)

--Server Script
local Replicated = game:GetService("ReplicatedStorage")
local Remote = Replicated:WaitForChild("ClientServer")
local Codes = {
	["Test1"] = 250,
	["FREE"] = 50
}

Remote.OnServerInvoke = function(Player,Code)
	if typeof(Code) ~= "string" then return end
	print(string.format("%s has redeemed the input: %s",Player.Name,Code))
	if not Codes[Code] then return false else return true end
end
Server --> Client

Not recommendeddo not try it unless you’ve a strong sanity checks that would prevent exploiters from ruining and messing up with it. These are the risks you could have with it:

1.If the client throws an errorthe server throws the error too.
2.If the client disconnects while it’s being invokedthen RemoteFunction:InvokeClient() throws an error.
3.If the client doesn’t return a valuethe server yields forever.

Player & Character

In this sectionwe’ll be talking about the Player and its ‘visual’ appearance - the Character.
We’ll talk about how they’re differentand what each has and offersthat the second - does not.

Player

The Player is an object/instancewhere you can view most of the main things/properties your player/other players have in-game[ and some can actually give info from out of the game]. To be a bit more accurateevery Player object represents the Client when they’re connected to the game.

Properties

Like every other objectthe Player object has properties aswelllet’s review some of them:

Character

This property is an ObjectValueand it should represent the actual model of the player - the character [ which we can visually see in-games].

DisplayName

Obviouslythis property is a Stringand it should represent the DisplayName of the player.

AccountAge [Read Only]

This property is a Number and it automatically updates the Age [in days] of the player.
NOTICE: this property is read onlymeaning - you can’t modify or change that property.

Team

This property belongs to the Team classand this allows us to know/edit and change the player’s team.The Team value itselfis an ObjectValue. And it’s supposed to represent the player’s team or nil [if the team doesnt exist/destroyed].

Events

In herewe’ll be talking about some cool and useful events the Player object has.

CharacterAdded(Character)

This event should fire every time the player’s character spawns or respawns.

local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(Player)
	print(Player.Name.."- Player Instance")
	Player.CharacterAdded:Connect(function(Character)
		print(Character.Name.."- Model Instance")
	end)
end)

Chatted(Message)

This event would fire each time the player is chatting through Roblox built-in chat.

local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(Player)
	Player.Chatted:Connect(function(Message)
		print(string.format("%s has said the word: %s",Player.Name,Message))
	end)
end)
Methods

In herewe’ll be talking about some useful methods you might need to know and use.

ClearCharacterAppearance()

This method would remove all accessories and objects from the player’s character.[if they are decalsaccessories and clothes].

local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(Player)
	print(Player.Name.."- Player Instance")
	Player.CharacterAppearanceLoaded:Connect(function(Character)
		Player:ClearCharacterAppearance()
	end)
end)

Kick(Message)

This method would kick the player from your game and show him the given message [if given]if not,t then the default Roblox message.

local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(Player)
	Player:Kick("Test")
end)

Character

The Character is a Model objectwhich should represent the player’s character [ or any player’s character]and can also be used for making NPC’s. Every character essentially contains:
Humanoid ,HumanoidRootPart and a Head part. About other limbs - depending on what rig you’re using [R6 or R15].The character is the entity of yourself and other players in games which allows you to do actions [ runwalk,sitjump ,dance] and more things that can be viewed from the character prespective.

Properties

Like every other object/instancethe Character object has properties aswelllet’s review some of them.

Archivable

This property [ boolean ] would determine if the object is included in the game and can be seen when published and it also impacts to clone objects. If set to falsethe object won’t be cloned. If set to truethe object will be cloned when using the Clone() method.

local newObject = Instance.new("Part")
print(newObject:Clone())  --> Partbecause `Archivable` is automatically set here to true

newObject.Archivable = false

print(newObject:Clone())  --> nil

PrimaryPart

This is an ObjectValuewhich refers to the PrimaryPart of your model. You should know that -
The primary part acts like the physical reference for the pivot of the modelwhich basically means -
The pivot will move in sync with the primary part. If the primary part is not setthe pivot will stay at the same position in world space even if parts within the model are no longer there.
It is also important to mention that when setting a primary partthat primary part has to be a descendant of that modelor else - setting that primary part will change it to nil automatically.

Events

In herewe’ll be talking about some useful events to use on our character.

AncestryChanged()

This event would run when the parent or any of its ancestors is changed. It includes 2 parameters: child and parent. Where:

child is the object whose parent was changed.
parent is the new parent of that child[object].

local Baseplate = game.Workspace.Baseplate

Baseplate.AncestryChanged:Connect(function(Child,Parent)
	print(Child.Name .. " is now a child of " .. Parent.Name)
end)
Baseplate.Parent = workspace.isModel
Methods

In this sectionwe’ll be learning about some cool and useful methods to use on our character.

BreakJoints()

This method will break any connection between parts in your character. Using this on your characterwill kill you [ by killing your humanoid].

local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Char)
		task.wait(1)
		Char:BreakJoints()
	end)
end)

MoveTo()

This method will move the character/any model’s primary part to the provided position.Make sure your model always has a PrimaryPart. Because if your model doesnt have onethis would select the root part of that model as the primary part. Andsince the root part is not deterministicit is recommended to always set a primary part.

ToolsBackpack & StarterGear

In this sectionwe’ll be talking about toolsbackpack ,startergearand how to use and how they work.

Tools

By definitiontools on Roblox are objects which the Character[ if he has a humanoid within]can equip unequip and activate it. Notice this pattern:
Tool is in BackpackPlayer Equips it – > Tools is now in his Character.
When you place tools in StarterPackthis would put all the given tools under the player’s Backpack folder. [From where he can equip his tools].

You notice that when you dieyou lose your tools. How can you prevent this?
Simply make sure the tools are also in StarterGearthis would give you those items each time you die/reset.

On desktops,pressing a number key (123…) will equip the tool whose index is at that number key.
[Meaningpressing 1 should give you the first tooletc.]
Let’s review a quick example:

local tool = script.Parent

local function explode(point)
	local e = Instance.new("Explosion")
	e.DestroyJointRadiusPercent = 0 
	e.Position = point
	e.Parent = workspace
end

local function Activated()
	--Getting the humanoid of the tool's owner
	local human = tool.Parent.Humanoid
	--Calling the explode function
	explode(human.TargetPoint)
end

--Connecting the Activated event to the Activated function
tool.Activated:Connect(Activated)

The tool in the above example will create an explosion at the position of the tool owner.
Let’s now move onto PropertiesEvents and Methods.

Properties

In herewe’ll be talking about some useful properties you might need when working with tools.

CanBeDropped [ boolean ]

This property will determine if you can drop your tool [by pressing Backspace] or not.

Enabled [ boolean ]

This property will determine if you can actually use the tool or not.[ Say you wanted to remain that tool in the player’s backpackbut only preventing him from using it].
When set to truethe player can use the tool. When set to falsethe tool is disabled and the player cannot use it. This would also prevent any Activation / Deactivation events from happeningsince you aren’t able to use the tool if set to false.

RequiresHandle [ boolean ]

This property determines if your tool can work without the need of a handle.
[Meaning that if your tool doesnt have a handleand that property is set to falsethen you could still activate your tool and do stuff].

Events

In herewe’ll be talking about some useful events on tools.

Activated

This event runs whenever the player clicks while equipping a tool.
[Do not get confused with the method Activate().]

local Tool = script.Parent

Tool.Activated:Connect(function()
	print(string.format("%s was activated!",Tool.Name))
end)

Equipped

This event runs whenever the player equips a tool.

local Tool = script.Parent

Tool.Equipped:Connect(function()
	print(string.format("%s was equipped!",Tool.Name))
end)
Methods

In this sectionwe’ll be learning about some useful methods to do with tools.

ClearAllChildren()

This method simply clears every child / descendant of the given object.
Notice that if you’re wishing to not clear completely all childrenyou could use a for loop + an if statement to check the class of the children etc.

Gamepasses & DevProducts

In this categorywe’ll be trying to understand the ideas behind gamepasses and devproductsand what they do.Before we dive into thatlet’s first explain what service they stand behind.
As you might knoweach service in Roblox Studio has different types of tasks to do/get.
And obviouslynot all services are shown in the Explorer.

In this partwe’ll be using the Marketplace Service.
MarketplaceService allows us to configure and work with in-game transactionsuse its methods to fetch information about developer products and gamepassesand more assets.

It has many many eventsas well as methods. We’ll be talking about some prominent ones.

Events

Here,we’ll be talking about some very useful events to work with MarketplaceService.

PromptGamePassPurchaseFinished

This event would run whenever the purchase dialog of a game pass is closed.Meaning whenever the player presses either ‘OK’ or ‘Cancel’.

It contains 3 parameters:

player[instance]: the player object whom got the prompt.
gamePassId[number]: the id of our gamepass.
wasPurchased[boolean]: checks if it was purchased or not.

--Defining Services
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")

--Making a Function
local function gamepassPurchaseFinished(player,id,purchased)
	print(player,id,purchased)
	print("PromptGamePassPurchaseFinished"player,id,purchased)
end

MarketplaceService.PromptGamePassPurchaseFinished:Connect(gamepassPurchaseFinished)

task.wait(5)
--Prompting a Gamepass Purchase for the testing
MarketplaceService:PromptGamePassPurchase(Players.LocalPlayer,87186006)

--In this casewe got:
--[[
 	PromptGamePassPurchaseFinished Valkyrop 87186006 false
]]

Notice that we got false herebecause I already own this gamepass.

PromptPremiumPurchaseFinished

Fires whenever the premium purchase modal closes[ meaning ‘Cancel’ or ‘OK’ buttons].

--Defining Services
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")

MarketplaceService.PromptPremiumPurchaseFinished:Connect(function()
	print("Player either closed or purchased premium!")
end)

task.wait(5)
--Prompting a Gamepass Purchase for the testing
MarketplaceService:PromptPremiumPurchase(Players.LocalPlayer)
Methods

In this sectionwe’ll be learning about some useful methods.

PromptGamePassPurchase()

This method prompts the given playerthe given gamePassID.

--Defining Services
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local GamepassID = 000000000 -- change it to your gamepass ID

--Prompting a Gamepass Purchase for the testing
MarketplaceService:PromptGamePassPurchase(Players.LocalPlayer,GamepassID)

PromptPremiumPurchase()

This method simply prompts the player to buy/get premium from the game.[Only parameter is the player whom this will be shown to].

GetDeveloperProductsAsync()

This method returns pages/lists of all current DevProducts the game has.

local MarketplaceService = game:GetService("MarketplaceService")
local developerProducts = MarketplaceService:GetDeveloperProductsAsync():GetCurrentPage()


for _devProduct in pairs(developerProducts) do
	for indexvalue in pairs(devProduct) do
		print(index .. ": " .. value)
	end
	print(" ")
end

--Result:
--[[
 DeveloperProductId: 16344291
 displayName: Developer Product 1 
 Name: Developer Product 1
 ProductId: 1316305655
 PriceInRobux: 25
]]

GetProductInfo()

This method returns information about an asset,dev product or even a gamepass.
You should provide the assetID + assetTypemeaning:

local success,result = pcall(function()
    return MarketService:GetProductInfo(87186006,Enum.InfoType.GamePass)
end)
ClickDetectors & ProximityPrompts

In this sectionwe’ll be learning about ClickDetectors and ProximityPrompts.

Introduction:

Sobefore we dive into it. Let’s first understand what they are and what they do.

ClickDetectors:allow us receive pointer input on 3D objects through their MouseClick eventmeaning - lets us click on objects with our cursorand do lots of stuff. They only work if they’re parented to:
BasePartModel or Folder's. Here is a very simple example:

--Assuming you have this script under a clickdetector which is under a part.
script.Parent.MouseClick:Connect(function()
	print("Someone has clicked on me!")
end)

ProximityPrompts: unlike ClickDetectorsProximityPrompts are visualized gui that appears each time the player approaches to objectswithin a certain range of a distance.
Here is a simple example:

--Assuming you have this script under a ProximityPrompt which is under a Part
script.Parent.Triggered:Connect(function()
	print("Someone has pressed this Prompt!")
end)
ClickDetectors

So after that introductionlet’s begin by learning some of its properties and events.

Properties

CursorIcon[Content]

This property allows you to change the icon of your cursor.

MaxActivationDistance[number]

This property tells you from what distance you’re able to click and activate that clickdetector.

Events

MouseClick

This event fires everytime a player presses and releases the left mouse button while the cursor is hovering over a model or any basepart with a clickdetector.Alsoit’s important for the player’s character to be within the MaxActivationDistancein order to activate it.

local clickDetector = script.Parent:FindFirstChild("ClickDetector")

clickDetector.MouseClick:Connect(function(Player) -- Player is a parameter for the player who clicked on it
	print(string.format("%s has pressed on me!",Player.Name))
end)

MouseHoverEnter

This event runs whenever the player begins to hover his cursor over the ClickDetector's parent.[Can be used in both Script and LocalScript].

local clickDetector = script.Parent:FindFirstChild("ClickDetector")

clickDetector.MouseHoverEnter:Connect(function(Player) -- Player is a parameter for the player who clicked on it
	print(string.format("%s has hovered his cursor!",Player.Name))
end)
ProximityPrompts

So after that introductionlet’s begin by learning some of its properties and events.

Properties

ActionText[string]

This property is where the text you’ll see on your promptlike this:
image

HoldDuration[float]

This would determine how long the player would have to hold the prompt.

MaxActivationDistance[float]

This would help you determine from what distance the player can activate the prompt.

Events

Triggered

This event runs whenever the player has done clicking/holding the prompt [and finished it].

script.Parent.Triggered:Connect(function()
	print("Prompt has been triggered!")
	game.Workspace.Baseplate.Size = Vector3.new(4,4,4)
end)

PromptButtonHoldBegan

This event runs whenever the prompt is being held by the player[make sure HoldDuration is > 0].

script.Parent.PromptButtonHoldBegan:Connect(function()
	print("Prompt triggering has begun")
end)

TweenService

In this sectionwe’ll be learning about TweenServicewhat it does and how to use it.

Introduction:

Tweens are used to interpolate the properties of instances. Meaningto edit,modify and change them in /animation.Notice! Only the following types can be used in TweenService:
image.

To start using this server and its featuresyou should use the main function : TweenService:Create()which takes information about the object and acts accordingly when playing the tween.

NOTES:
1.You can tween multiple properties at the same time.
2.If you’re trying to tween the same properties at the same timeonly the last one of those properties would tween.

Examples

1.Tweening part size
local tweenService = game:GetService("TweenService")
local Part= script.Parent
local tweenInfo = TweenInfo.new(
	2-- Time
	Enum.EasingStyle.Linear--Style
	Enum.EasingDirection.Out-- Direction
	-1--RepeatCount.[if it's <0 this would loop forever]
	true-- Reverse
	0 -- daly
)
local Goal = { -- properties to change
	Size = Vector3.new(10,10,10)
}
local PartTween = tweenService:Create(Part,tweenInfo,Goal) -- preparing the animation
PartTween:Play() -- playing the tween

task.wait(7) -- delay
PartTween:Cancel() -- this will stop the tweening
2. Tweening part size and Color
local tweenService = game:GetService("TweenService")
local Part= script.Parent
local tweenInfo = TweenInfo.new(
	2-- Time
	Enum.EasingStyle.Linear--Style
	Enum.EasingDirection.Out-- Direction
	-1--RepeatCount.[if it's <0 this would loop forever]
	true-- Reverse
	0 -- daly
)
local Goal = {
	Size = Vector3.new(10,10,10),
	Color = Color3.fromRGB(085255)
}
local PartTween = tweenService:Create(Part,tweenInfo,Goal)
PartTween:Play()

task.wait(7)
PartTween:Cancel()
--Change the part color to 'Really Red' to see the efffect.
Tweening a Door Spin
local tweenService = game:GetService("TweenService")
local Door= script.Parent
local tweenInfo = TweenInfo.new(
	2-- Time
	Enum.EasingStyle.Linear--Style
	Enum.EasingDirection.Out-- Direction
	-1--RepeatCount.[if it's <0 this would loop forever]
	false-- Reverse
	0 -- daly
)
local Goal = {
	CFrame = Door.CFrame * CFrame.Angles(0,math.rad(180),0),
}

local Tween = tweenService:Create(Door,tweenInfo,Goal)

Tween:Play()
Camera

In this sectionwe’ll be learning about Camera ; what it is and what it does.

Introduction:

Camera on Roblox is a special object which lets us define and view the world from a 3D prespective.
Every time a client[player] joins the gamehe has his own camera object.
We can’t access others camera through the server,only on the clientand access ours only. To access/find the camera objectwe use Workspace.CurrentCamera.

The Camera object has many important proprtieshowever - only 5 of them are more important than othersand these are:

[Camera.CFrame]: Simply represents the position and rotation of the camera.
[Camera.Focus](CFrame): Simply sets the focus of the camera to the given CFrameit is the point where the camera is looking.
[Camera.CameraType]: Determines how will the camera update every frame.
[Camera.CameraSubject]: Determines what object should the camera follow.
[Camera.FieldOfView]: Determines the observable world through the camera field of view.
The bigger the numberthe further the field of view is.

Examples:

Switching Camera Objects
--Variables
local camera = workspace.CurrentCamera
local players = game:GetService("Players")

local player = players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()

--Making the camera scriptableso we could apply our changes
camera.CameraType = Enum.CameraType.Scriptable


--Variables
local bb = script.Parent.BlueBrick
local door = script.Parent.Door
local you = script.Parent.You

bb.MouseButton1Click:Connect(function()
	camera.CameraSubject = game.Workspace.BlueBrick
end)

you.MouseButton1Click:Connect(function()
	camera.CameraSubject = char.Humanoid or char:WaitForChild("char")
end)

door.MouseButton1Click:Connect(function()
	camera.CameraSubject = game.Workspace.Door
end)
Spectate Players Button
--Variables
local camera = workspace.CurrentCamera
local playersSerivce = game:GetService("Players")

local player = playersSerivce.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()

local toggle = script.Parent.Spectate
local frame = script.Parent.ViewingPlayers
local previous = frame.Previous
local next = frame.Next

--This would help us counting [down/up] when we press previous/nextand get the players.
local countingPlayers = 1 

toggle.MouseButton1Click:Connect(function()
	frame.Visible = not frame.Visible
	frame.PlayerName.Text = player.Name
	camera.CameraSubject = char
end)

previous.MouseButton1Click:Connect(function()
	local players = #playersSerivce:GetPlayers()
	countingPlayers -= 1
	if countingPlayers < 1 then
		countingPlayers = players
	end
	local realPlayer = playersSerivce:GetPlayers()[countingPlayers]
	camera.CameraSubject = realPlayer.Character.Humanoid
	frame.PlayerName.Text = realPlayer.Name
end)

next.MouseButton1Click:Connect(function()
	local players = #playersSerivce:GetPlayers()
	countingPlayers += 1
	if countingPlayers > players then
		countingPlayers = 1
	end
	local realPlayer = playersSerivce:GetPlayers()[countingPlayers]
	camera.CameraSubject = realPlayer.Character.Humanoid
	frame.PlayerName.Text = realPlayer.Name
end)
Humanoid/Tools Animation

In this sectionwe’ll be learning how to apply animations onto tools/player’s character.
When we talk about Animation herewe talk about loading custom/built in movements/actions for our tools/humanoid actions.When you’re testing in studioyou can view under your humanoidthere is an object named Animator. The Animator is the main object that is responsible for the animations you have in your game. There are 2 ways to create this object:
1.Humanoid:LoadAnimation().
2.AnimationController:LoadAnimation().

Important notes:

For animation replication to function it is important for the Animator to be first created on the server.

The Animator object must be initially created on the server and replicated to others for animation replication in order to be shown to all. If the Animator is created locallythen any animation loaded through this animatorwon’t replicate to server.

Loading Animation:

You’ll need to use the LoadAnimation() method ,and provide an Animation object [NOT its animationID]. An example:

local UIS = game:GetService('UserInputService')
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local Anim = Instance.new('Animation')
Anim.AnimationId = 'rbxassetid://10910827063'

--Start Running Animation
UIS.InputBegan:connect(function(input,processed)
	if processed then return end
	if input.KeyCode == Enum.KeyCode.LeftShift then
		Humanoid.WalkSpeed = 24
		PlayAnim = Humanoid:LoadAnimation(Anim)
		PlayAnim:Play()
 	end
end)

--Stop Running Animation
UIS.InputEnded:connect(function(input)
 	if input.KeyCode == Enum.KeyCode.LeftShift then
		Humanoid.WalkSpeed = 16
		if PlayAnim then
			PlayAnim:Stop()
			PlayAnim:Destroy()
		end
 	end
end)
Mouse & UserInputService

In this sectionwe’ll be learning about Mouse and UserInputService ; what they are and what they do.

Introduction:

Mouse:
Simply our cursor. We can get the Mouse in this way:

--Local script
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()

Notice:

Although Mouse is deprecated [UserInputService and ContextActionService are its replacement],
it is still supported and can be used.

Properties

Hit(CFrame)

This property returns the mouse’s position in the 3D space which we work with in studio.

Target(BasePart)

This property returns the 3D object which the mouse is pointing to.
Notice: if you set Mouse.TargetFilterthen all the provided objects within the filter would be ignored.

Events

Move

This event fires whenever the mouse is moved.[Only when the mouse’s position is updated/changed].

local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()

Mouse.Move:Connect(function()
	local Target = Mouse.Target
	print(Target) -- would print nil if pointed to sky
end)

UserInputService:
Simply a service used to detect and capture the different types of input available on a user’s device.[ConsoleMobilePCetc].
Basicallythe main purpose of this service is to provide the best experience possible to all possible devices.

Notice:

This service is client-sided only. Meaningit can only be used on the client. Which obviously means - you can only use it in LocalScript's or in ModuleScript's required by localscripts.

Properties

MouseEnabled[boolean]

This property checks if the player’s device has a mouse.[ and returns true if found]if not found - it returns false.

TouchEnabled[boolean]

Simply checks if the player’s device has any available touch screen.
If there is a touch screen foundyou could use UserInputService - TouchEnded/TouchStarted events to operate accordingly and detect their behavior on their device.

VREnabled[boolean]

Simply checks if the player is using a VR device. If a VR device was foundyou could use some events such as UserInputService:GetUserCFrame() to do some cool stuff with it.

Events

InputBegan

This event would run whenever a player begins interacting with one of the following devices [ pc,mobile,console,vr,etc].

local UserInputService = game:GetService("UserInputService")

UserInputService.InputBegan:Connect(function(Key,Processed)
	if Processed then return end -- if I am during chattingthen end the function.
	print(Key.KeyCode.Name) -- would print the name of the pressed key.
end)

InputChanged

This would fire everytime the player is changing their interaction type [ for example: Mouse button down].

local UserInputService = game:GetService("UserInputService")

UserInputService.InputChanged:Connect(function(Key,Processed)
	if Processed then return end -- if I am during chattingthen end the function.
	if Key.UserInputType == Enum.UserInputType.MouseMovement then
		print("The Mouse has been moved!")
	end
end)

Here is Part2since I couldnt fit it in the original post because of a limit.

95 Likes

Thank you! I was having a bit of trouble learning UserInputService

12 Likes

HelloI just read your tutorial and it’s 65% better than all the tutorials I’ve seen.

You provided an explanation on what each thing does and put it in very specific wordsalthough my brain is really bad at understanding just looking at wordsbut definitely very useful!

23 Likes

Do you give out paid tutorials?

6 Likes

can you add an option to the poll saying its the worst reading experience i ever had in my life

15 Likes

Nosorry
I don’t have time for it

but I hope this somehow helped you :wink:
best of luck!

9 Likes

Thank you so much for writing this. I have used other programming languages and I’m working to get into Lua. Knowing how things are formatted with Lua has helped me a lot!

7 Likes

Ok this helped a ton! I knew other languages like python but wanted to learn about Roblox luau and about remote events etc. This helped a lot thanks for taking your time for making this tutorial for us!

3 Likes