|
--By Robertoman. Not me.
Every script needs a function for it to carry out objectives in a certain instance. here are the functions available in Lua.
function
while true do
if
for
The next thing to know is that a function requires an end, if it doesn't end, it wont function. For instance:
function
end
OR
function
while true do
if
for
end
end
end
end
That is the first lessons and the most important ones will learn.
After you can make a function, and you can end it, you need to make a funtion MEAN something, carry out an objective, and give good output. You can make a new function and call it anything you want; such as.
function onTouched
That is a well used function, but a function has no meaning unless you tell the script what onTouched is; so at the end of the script you should type a connection of the function onTouched. If you wanted the connection to be when a brick is touched you would make it look like this:
script.DIRECTORY.Touched:connect(onTouched)
The place where DIRECTORY is put, you would add the direct line of paret/children in order to get to the brick that is touched. Most people will put a script like this inside of a brick, if they wanted that brick to do something. Then they would put:
script.Parent.Touched:connect(onTouched)
That will connect the brick that is the parent of the script. So any time something touched the brick(it doesn't have to be a person), the function will activate. To see what this looks like in full:
function onTouched(hit)
end
script.Parent.Touched:connect(onTouched)
The item called hit is just a variable that is designed to be known to the script to be the occurance of script.Parent.Touched. So in english words, when the item is touched, do this function.
Now that you have a workinf function, lets make it do something. Lets first make the block that is being touched change it's color to a new color. Roblox has set apart meanings of words. Roblox calls these items properties, when you want to edit a block, look at the properties of the block. Properties can be changed through directories. If we wanted to change the color of a brick, you will first need to know what the class name of the brick is, it is a Part. In a Part the color is known as "BrickColor". So as we go into the script to edit it, we would say:
function onTouched(hit)
script.Parent.BrickColor = BrickColor.new(23)
end
script.Parent.Touched:connect(onTouched)
A property of an item is changed by typing the = sign, to let the script know to change the property of the item befor it. So the property of the script's parent's brickcolor will be changed to something different. When you are changing the color of a brick you must use BrickColor.new to tell the script you want to make a new brick color. You will then put the parenthesis to tell the script to make the new color the following number. The number 23 is known by roblox as the color blue. So when this button is touched, the brick will change to blue.
But wait, anything can touch this brick and change it's color... I only want items that have a humanoid to change it's properties. So lets make a new part to add to the script so only items with humanoids can make the function work. I'm going to create a line that looks like this:
local humaniod = hit.Parent:findFirstChild("Humanoid")
... and place it in the function, not before it. That way, when the item is it, it will check for the humanoid each time. The word local means, create a new variable for me and call it the following. We created a variable called humanoid. Then the = sign again meaning make the previous part = the next part, made the humanoid look in the directory of hit... what is hit? Hit is the connection that we made a while back, remember? function onTouched(HIT). Now it connects and looks for the parent of the hit, the hit is the object that made contact with this brick. So this is normaly a person's leg, it loks for the leg's parent. The leg's parent is the person in whole, meaning there is a Humanoid, Left Leg, Right Leg, Left Arm, Right Arm, Torso, Head, and some scripts in that person. The Humanoid has properties of the person's health, maxhealth, and speed. We don't want to edit the Humanoid's properties, we just want to make sure it is there. Then the phrase findFirstChild() is something that will be required, because, what if the Humanoid isn't there? It will hit that part and freeze the script, because it can't connect with a Humanoid. Any time you say findFirstChild(), you are saying, find this exact name in it's children. Now, lets make an if function that will check to see if the Humanoid is there. :D
function onTouched(hit)
local humaniod = hit.Parent:findFirstChild("Humanoid")
if (humanoid ~= nil) then
WAIT, we just created a new function, we will need to end the if also. So...
function onTouched(hit)
local humaniod = hit.Parent:findFirstChild("Humanoid")
if (humanoid ~= nil) then
script.Parent.BrickColor = BrickColor.new(23)
end
end
script.Parent.Touched:connect(onTouched)
Now we are telling it to only change the color of the brick IF the humanoid was found in the object's parent that touched it. This is confusing no? Well the ~= sign means NOT EQUAL TO. The word nil means NOWHERE. So if the humanoid is not equal to nowhere, meaning two nots = a yes, that it is asking if the humanoid is there. The word then is used to tell the if function that if the humanoid was there then do the following. BUT, what if a humanoid wasn't there? Lets create a section under that, to tell the function to do something else if the humanoid wasn't found. So:
function onTouched(hit)
local humaniod = hit.Parent:findFirstChild("Humanoid")
if (humanoid ~= nil) then
script.Parent.BrickColor = BrickColor.new(23)
else return nil
end
end
script.Parent.Touched:connect(onTouched)
The else means, if it wasn't found, then do this. The return means to return that function, and the nil means to return to empty, as if it was never touched. Always be sure that when you do an else, that it is befor the end of the functino you want the else to operate on.
Wait a sec, now if someone touches it, and then another person touches it, it will do the function more than once, not only that, the same person can accidentaly touch it more than once and all he did was step on it once. To fix this lets make a variable called debounce, it can be any variable you want, but debounce makes sence. NOTE: when you create a debounce, be sure to add it above the function, otherwise, every time someone touches is the debounce will = whatever you tell it to be. So:
debounce = false
function onTouched(hit)
local humaniod = hit.Parent:findFirstChild("Humanoid")
if (humanoid ~= nil) then
script.Parent.BrickColor = BrickColor.new(23)
else return nil
end
end
script.Parent.Touched:connect(onTouched)
But now the debounce = something, it equals false because something taht is false can only be true of false, it is easy to understand. you can make it equal a number, but true and false is easier to keep track of. Now that we have a debounce, it doesn't automaticly fix everything, we have to tell the script what to do now with the debounce. So let's create another if function to make the script only work if the debounce IS EQUAL TO false, not IS NOT EQUAL TO. and where there is a function, there is an end. Be sure to add an else portion.
debounce = false
function onTouched(hit)
local humaniod = hit.Parent:findFirstChild("Humanoid")
if (humanoid ~= nil) then
if (debounce == false) then
debounce = true
script.Parent.BrickColor = BrickColor.new(23)
debounce = false
else return nil
end
else return nil
end
end
script.Parent.Touched:connect(onTouched)
Now! AHHH, it still isn't working is it? That is beacuse the script runs so fast that it is doing the whole thing over and over again. The easiest way to fix this is to create a wait() part; Lua knows that wait(), means to wait the amount given. So:
debounce = false
function onTouched(hit)
local humaniod = hit.Parent:findFirstChild("Humanoid")
if (humanoid ~= nil) then
if (debounce == false) then
debounce = true
script.Parent.BrickColor = BrickColor.new(23)
wait(3)
debounce = false
else return nil
end
else return nil
end
end
script.Parent.Touched:connect(onTouched)
It will now wait three second before it moves on to the next part of the script, which is making the debounce false again. That way, they can hit is multiple times, BUT when the debounce is found as true for 3 seconds, it just returns as nil.
Lets say we want the block to change to the color gray after a second of it being blue, then let's make it brown, then red, lastly make it blue again. So:
debounce = false
function onTouched(hit)
local humaniod = hit.Parent:findFirstChild("Humanoid")
if (humanoid ~= nil) then
if (debounce == false) then
debounce = true
script.Parent.BrickColor = BrickColor.new(23)
wait(1)
script.Parent.BrickColor = BrickColor.new(31)
wait(1)
script.Parent.BrickColor = BrickColor.new(25)
wait(1)
script.Parent.BrickColor = BrickColor.new(21)
wait(1)
script.Parent.BrickColor = BrickColor.new(23)
wait(3)
debounce = false
else return nil
end
else return nil
end
end
script.Parent.Touched:connect(onTouched)
Now it is a brick that changes many colors when it has been touched, but but now it takes 7 seconds to go through the whole process, so let's change the times around some to make the whole time = 3 seonds. :D
debounce = false
function onTouched(hit)
local humaniod = hit.Parent:findFirstChild("Humanoid")
if (humanoid ~= nil) then
if (debounce == false) then
debounce = true
script.Parent.BrickColor = BrickColor.new(23)
wait(.5)
script.Parent.BrickColor = BrickColor.new(31)
wait(.5)
script.Parent.BrickColor = BrickColor.new(25)
wait(.5)
script.Parent.BrickColor = BrickColor.new(21)
wait(.5)
script.Parent.BrickColor = BrickColor.new(23)
wait(1)
debounce = false
else return nil
end
else return nil
end
end
script.Parent.Touched:connect(onTouched)
And there you have a button that changes colors when touched.
Let's do something simple, like make the properties of the person that touches this item change. As we learned from the last lesson, we can just paste the already learned matterial here, saving us much typing. So:
debounce = false
function onTouched(hit)
local humaniod = hit.Parent:findFirstChild("Humanoid")
if (humanoid ~= nil) then
if (debounce == false) then
debounce = true
debounce = false
else return nil
end
else return nil
end
end
script.Parent.Touched:connect(onTouched)
Now, let's make it find the player's head, left arm, right arm, left leg, and right leg. This will aid us in changing that person's body properties later. So:
debounce = false
function onTouched(hit)
local humaniod = hit.Parent:findFirstChild("Humanoid")
if (humanoid ~= nil) then
if (debounce == false) then
debounce = true
local head = hit.Parent:findFirstChild("Head")
local la = hit.Parent:findFirstChild("Left Arm")
local ll = hit.Parent:findFirstChild("Left Leg")
local ra = hit.Parent:findFirstChild("Right Arm")
local rl = hit.Parent:findFirstChild("Right Leg")
debounce = false
else return nil
end
else return nil
end
end
script.Parent.Touched:connect(onTouched)
Now that we have found the items, let's make the person change to a half visible person :D
debounce = false
function onTouched(hit)
local humaniod = hit.Parent:findFirstChild("Humanoid")
if (humanoid ~= nil) then
if (debounce == false) then
debounce = true
local head = hit.Parent:findFirstChild("Head")
local la = hit.Parent:findFirstChild("Left Arm")
local ll = hit.Parent:findFirstChild("Left Leg")
local ra = hit.Parent:findFirstChild("Right Arm")
local rl = hit.Parent:findFirstChild("Right Leg")
head.Transparency = .5
la.Transparency = .5
ll.Transparency = .5
ra.Transparency = .5
rl.Transparency = .5
debounce = false
else return nil
end
else return nil
end
end
script.Parent.Touched:connect(onTouched)
Ok, this block will make anyone that touches it turn to a 50% visible rate. Let's make the block say this above it. When you see a person, you see their name above their head, correct? The I presume it is safe to say that if you create a brick called Head, and place it in a model with a Humanoid in it, the brick will have writing above it. So we will create a model, and place the Head and a Humanoid in the model. Then anything we name the model will show above the Head. :D So, would we put this above the script, or in it? Well just look at it this way, if we put anything in a function, it wont HAPPEN, unless the function is TRUE. Meaning that unless someone touched that brick, the actions in the function wont happen. So the answer is, put it above the block, that way it only happens once, and it will be there BEFORE anyone touched the brick.
local model = Instance.new("Model")
model.Parent = script.Parent.Parent
model.Name = "Transparency = 50%"
Remember that we want the model to be made OUTSIDE of the brick that this script is in, so make the model's parent this brick's parent. Also remember that this model's name is going to be what shows above the Head. A player is a model with a Head and a Humanoid in it, the Head isn't called the person's name, BUT the model is called their name.
local h = Instance.new("Humanoid")
h.Parent = model
Ok, we can make a new item and have it placed directly in the item we made previously, cool.
script.Parent.Parent = model
script.Parent.Name = "Head"
O.O we just made this script's parent, being the block, move to the model, then we called it Head.
debounce = false
function onTouched(hit)
local humaniod = hit.Parent:findFirstChild("Humanoid")
if (humanoid ~= nil) then
if (debounce == false) then
debounce = true
local head = hit.Parent:findFirstChild("Head")
local la = hit.Parent:findFirstChild("Left Arm")
local ll = hit.Parent:findFirstChild("Left Leg")
local ra = hit.Parent:findFirstChild("Right Arm")
local rl = hit.Parent:findFirstChild("Right Leg")
head.Transparency = .5
la.Transparency = .5
ll.Transparency = .5
ra.Transparency = .5
rl.Transparency = .5
debounce = false
else return nil
end
else return nil
end
end
script.Parent.Touched:connect(onTouched)
So far so good, let's see what this looks like so far:
local model = Instance.new("Model")
model.Parent = script.Parent.Parent
model.Name = "Transparency = 50%"
local h = Instance.new("Humanoid")
h.Parent = model
script.Parent.Parent = model
script.Parent.Name = "Head"
debounce = false
function onTouched(hit)
local humaniod = hit.Parent:findFirstChild("Humanoid")
if (humanoid ~= nil) then
if (debounce == false) then
debounce = true
local head = hit.Parent:findFirstChild("Head")
local la = hit.Parent:findFirstChild("Left Arm")
local ll = hit.Parent:findFirstChild("Left Leg")
local ra = hit.Parent:findFirstChild("Right Arm")
local rl = hit.Parent:findFirstChild("Right Leg")
head.Transparency = .5
la.Transparency = .5
ll.Transparency = .5
ra.Transparency = .5
rl.Transparency = .5
debounce = false
else return nil
end
else return nil
end
end
script.Parent.Touched:connect(onTouched)
Looks great, and all we did was coppied our last parts and made this out of it, how easy is that. Scripting is getting easier already. BUT WAIT, this brick is going to have a health bar above it, we don't want this brick to have a health bar, just the message, so let's make it's health go to 0.
local model = Instance.new("Model")
model.Parent = script.Parent.Parent
model.Name = "Transparency = 50%"
local h = Instance.new("Humanoid")
h.Parent = model
h.Health = 0
h.MaxHealth = 0
script.Parent.Parent = model
script.Parent.Name = "Head"
debounce = false
function onTouched(hit)
local humaniod = hit.Parent:findFirstChild("Humanoid")
if (humanoid ~= nil) then
if (debounce == false) then
debounce = true
local head = hit.Parent:findFirstChild("Head")
local la = hit.Parent:findFirstChild("Left Arm")
local ll = hit.Parent:findFirstChild("Left Leg")
local ra = hit.Parent:findFirstChild("Right Arm")
local rl = hit.Parent:findFirstChild("Right Leg")
head.Transparency = .5
la.Transparency = .5
ll.Transparency = .5
ra.Transparency = .5
rl.Transparency = .5
debounce = false
else return nil
end
else return nil
end
end
script.Parent.Touched:connect(onTouched)
Yes, be sure to make it's MaxHealth = 0 too or else it will have the bar, but the bar will be red instead of green. There you have it, this will do everything we wanted, so lets move on :D
Let's make something that nearly EVERY place needs... a leader board. A leaderboard is a display in the top right hand corner of the screen when you enter a place. I'm sure you have noticed that some places have gold, money, wood, level, XP, or some other type of off name at the top of it. Those being items you get in the map. A leaderboard is so easy to make, it is only a matter of knowing what to connect it's function to, and knowing how to create instances.
I will first start with naming it's function Entered :D Then connect it to when a player enters the game.
function Entered()
end
game.Players.ChildAdded:connect(Entered)
Wow, that is easy, now you know what to say when a new child has been added to anything... doesn't have to be a player :-P So now let's add the most important instance, the MAIN one, and let's call it leaderstats. Also, don't forget to call the connection we made something, remember that when a human hit the buttons, the connection was called "hit", let's call this connection newPlayer.
function Entered(newPlayer)
local LS = Instance.new("IntValue")
LS.Name = "leaderstats"
LS.Parent = newPlayer
end
game.Players.ChildAdded:connect(Entered)
Now you ask... where is newPlayer at? newPlayer is in the child that was added :D So now the location of leaderstats is: game.Workspace.Players.(newPlayer.Name).leaderstats. Don't forget that newPlayer.Name means the name of the newPlayer, which would be the name of the new child that was added. So, this function will run every time a new child is added to the game.Players directory. It just so happens that when a player enters a game, thier name is placed there, so this happens every time someone enters the game. Now that we have a leaderstats, let's create another part that we will call... Deaths, and deaths will go in the leaderstats, not the newPlayer.
function Entered(newPlayer)
local LS = Instance.new("IntValue")
LS.Name = "leaderstats"
LS.Parent = newPlayer
local deaths = Instance.new("IntValue")
deaths.Parent = LS
deaths.Name = "Deaths"
deaths.Value = 0
end
game.Players.ChildAdded:connect(Entered)
Why did I make the deaths.value = 0? Because, if I didn't give it a value, people would start with no number system. How can you calculate an amount of times died if you can't make deaths a number?
Well, we have a function for when someone enters, but I think it would be cool if it would announce the new person that came in. So let's add a message to the workspace when a newplayer enters.
function Entered(newPlayer)
local LS = Instance.new("IntValue")
LS.Name = "leaderstats"
LS.Parent = newPlayer
local deaths = Instance.new("IntValue")
deaths.Parent = LS
deaths.Name = "Deaths"
deaths.Value = 0
local message = Instance.new("Message")
message.Text = "~Welcome to my place ".. newPlayer.Name .."~"
message.Parent = game.Workspace
wait(6)
message:remove()
end
game.Players.ChildAdded:connect(Entered)
Yeah, this is cool, now when someone enters the place, they get an introductory message that everyone sees. Now that we are introducing every player... let's let everyone know when they leave. :D This will require a new function, but let's keep it in the same script. This function will be connected to ChildRemoved, rather than ChildAdded. So...
function Left(oldPlayer)
end
game.Players.ChildRemoved:connect(Left)
I think it is appropriate to call the leaving player an old player, lol. Now let's say bye bye to them when they are gone... :(
function Left(oldPlayer)
local message = Instance.new("Message")
message.Text = "Aww, ".. oldPlayer.Name .." has left :("
message.Parent = game.Workspace
wait(4)
message:remove()
end
game.Players.ChildRemoved:connect(Left)
There, now we have two sections to our leaderboard! Yeah, we rock :D Now there is one problem... We created a death leaderstat, but how is it going to calculate the stats? Yeah... more scripting -.- At least we are understanding it now. So how are we going to calculate the stat? There are a few ways, but I say that we create another function called Died, and see if we can make it add 1 to the deaths stat every time they die. We can track the player's humanoid so that when it is equal to 0, it will add 1 to the deaths stat! But let's make it find the deaths stat and then add 1 to it, we can create the connection afterwards.
function HumanoidDied(player)
local stats = player:findFirstChild("leaderstats")
if (stats ~= nil) then
local deaths = stats:findFirstChild("Deaths")
deaths.Value = deaths.Value + 1
end
end
There, now that it can find the player's stat called Deaths, and it adds 1 to it, let's make that connection. :D I think the connection should be added in the Entered function, so:
function Entered(newPlayer)
local LS = Instance.new("IntValue")
LS.Name = "leaderstats"
LS.Parent = newPlayer
local deaths = Instance.new("IntValue")
deaths.Parent = LS
deaths.Name = "Deaths"
deaths.Value = 0
local message = Instance.new("Message")
message.Text = "~Welcome to my place ".. newPlayer.Name .."~"
message.Parent = game.Workspace
wait(6)
message:remove()
local humanoid = newPlayer.Character.Humanoid
humanoid.Died:connect(function() HumanoidDied(humanoid, newPlayer) end )
end
game.Players.ChildAdded:connect(Entered)
Ok, we made a connection with a humanoid, AND the newPlayer, being player. So now we have to go BACK to the died function, and add this humanoid part to it's function. Just like when a new object is created and placed in another object, it is considered ChildAdded, so is the same as the humanoid's health = 0, it is called Died. So the above, connected to the newPlayer's humanoid dying, then it connects to another function called HumanoidDied, and gave it two variables, the humanoid, and the player. Lastly, we end the function's connection.
function HumanoidDied(humanoid, player)
local stats = player:findFirstChild("leaderstats")
if (stats ~= nil) then
local deaths = stats:findFirstChild("Deaths")
deaths.Value = deaths.Value + 1
end
end
And there we have it, a complete leaderboard, let's see it in full suit :D
function Entered(newPlayer)
local LS = Instance.new("IntValue")
LS.Name = "leaderstats"
LS.Parent = newPlayer
local deaths = Instance.new("IntValue")
deaths.Parent = LS
deaths.Name = "Deaths"
deaths.Value = 0
local message = Instance.new("Message")
message.Text = "~Welcome to my place ".. newPlayer.Name .."~"
message.Parent = game.Workspace
wait(6)
message:remove()
local humanoid = newPlayer.Character.Humanoid
humanoid.Died:connect(function() HumanoidDied(humanoid, newPlayer) end )
end
game.Players.ChildAdded:connect(Entered)
function HumanoidDied(humanoid, player)
local stats = player:findFirstChild("leaderstats")
if (stats ~= nil) then
local deaths = stats:findFirstChild("Deaths")
deaths.Value = deaths.Value + 1
end
end
function Left(oldPlayer)
local message = Instance.new("Message")
message.Text = "Aww, ".. oldPlayer.Name .." has left :("
message.Parent = game.Workspace
wait(4)
message:remove()
end
game.Players.ChildRemoved:connect(Left)
Looks great, I think we have learned a lot today, let's take a break... LOL
--Originally by Robertoman |