How to create a basic scanner system

hello there!
I’m RandomizedHistory (random for short), an upcoming and aspiring developer. This tutorial goes in-depth on how to make a basic scanner where, when a card is inserted into the correct part, a math.random() function is called in which, if the number called is greater than another value, the player is “accepted”. Let’s get started!

PART 1; Preparation
What you will need to create this system:
(note: It’s recommended you put the components inside a model for better organization.)

  • Part named scanPart (insert two sounds named Accepted & Denied into the part, along with a script. Sounds are optional.)
  • Part named textPart (inside, insert a surface gui and a text label inside the surface gui.)
  • Part named lightPart (feel free to modify this part however you want to.)
  • Three tools named (card_1, card_2, & card_3)
    (note: Feel free to name the components whatever you desire, it does not matter.)

PART 2; Coding
After you have gotten all of the necessary components (make sure the model is anchored) it is time to start coding! If you have not already, create/open the script inside the scanPart and let’s begin!

We first want to create some variables, we will need to reference the sounds, Text Label, scanPart, lightPart & a debounce boolean.

Code:

local acceptedSound = script.Parent:WaitForChild("Accepted")
local deniedSound = script.Parent:WaitForChild("Denied")
local scanPart = script.Parent
local lightPart = script.Parent.Parent:WaitForChild("lightPart")
local label = script.Parent.Parent.textPart.SurfaceGui:WaitForChild("TextLabel")
local debounce = false

Now that we have finished creating our variables and referencing our components, we will move onto the primary functions, for this portion of the code, the aforementioned tools will each have a different chance of being accepted in the system, to topple that obstacle, we’re going to use the math.random() function. For the sake of the tutorial, for the math.random function, we’re going to use the standard range of 1-10.

Code:

scanPart.Touched:Connect(function(touch)
	if touch.Name == "Handle" and touch.Parent.Name == "card_1" and debounce == false then
		debounce = true
		local num = math.random(10)
		if num > 1 then
			print("Player Accepted!")
		elseif num <= 1 then
			print("Player Denied!")
		end
		wait(.5)
		debounce = false
	end
end)

Going a little more in-depth in this portion, you can see the function is called when the player’s card touches the scanPart, after that, an if statement is called to ensure that the object inserted into the scan part was a card and to also ensure that the debounce boolean is false. After that, we set the debounce to true and we’re using the aforementioned math.random function to call a random number from 1-10. Then, we create another if statement checking if the number called is greater the number we want, in this case that number is one. If true, the server prints “Player Accepted!” and if not, the server prints “Player Denied!”. Then we use a wait() function and the debounce will once again be set to false.

Now it’s time to replace the print functions with actual code, let’s get to it!

Code:

scanPart.Touched:Connect(function(touch)
	if touch.Name == "Handle" and touch.Parent.Name == "card_1" and debounce == false then
		debounce = true
		local num = math.random(10)
		if num > 1 then
			label.Text = "scanning..please wait"
			wait(1)
			label.Text = "Player Accepted!"
			acceptedSound:Play()
			lightPart.BrickColor = BrickColor.Green()
			wait(1.5)
			lightPart.BrickColor = BrickColor.new("Medium stone grey")
			label.Text = "> awaiting input.."
		elseif num <= 1 then
			label.Text = "scanning..please wait"
			wait(1)
			label.Text = "Player Denied!"
			deniedSound:Play()
			lightPart.BrickColor = BrickColor.Red()
			wait(1.5)
			lightPart.BrickColor = BrickColor.new("Medium stone grey")
			label.Text = "> awaiting input.."
		end
		wait(.5)
		debounce = false
	end
end)

Right, little bit more code than last time, let’s look into it. So, in the first line of code after the if statement checking the number called, it says "label.Text = “scanning…please wait”. Essentially, to make the system more “realistic” and not so instantaneous, I added that line of code just to make it feel a bit more “slower” and again, realistic. In this portion of the code,

label.Text = “Player Accepted!”
acceptedSound:Play()
lightPart.BrickColor = BrickColor.Green()
wait(1.5)
lightPart.BrickColor = BrickColor.new(“Medium stone grey”)
label.Text = “> awaiting input…”

You can see how if accepted, the color of the light part changes to green, the accepted sound is played, and the text of the label now says “Player Accepted!”. Then after 1.5 seconds, the lightPart returns to its normal color and the label’s text is returned to it’s previous message. This portion of code is nearly identical to what happens when the player’s card is denied, however instead, the color of the lightPart is changed to Red and the text says “Player Denied!”

Now, you may be asking "Hey, random! What about those other two tools/cards, what is there use? Worry not, those cards are used to have different acceptance rates. I.e. card_2 may have a 60% chance to be accepted whereas card_3 may only have a 10% chance. To see that in display, check this portion of code:

Code:

	if touch.Name == "Handle" and touch.Parent.Name == "card_2" and debounce == false then
		debounce = true
		local num = math.random(10)
		if num > 4 then
			label.Text = "scanning..please wait"
			wait(1)
			label.Text = "Player Accepted!"
			acceptedSound:Play()
			lightPart.BrickColor = BrickColor.Green()
			wait(1.5)
			lightPart.BrickColor = BrickColor.new("Medium stone grey")
			label.Text = "> awaiting input.."
		elseif num <= 4 then
			label.Text = "scanning..please wait"
			wait(1)
			label.Text = "Player Denied!"
			deniedSound:Play()
			lightPart.BrickColor = BrickColor.Red()
			wait(1.5)
			lightPart.BrickColor = BrickColor.new("Medium stone grey")
			label.Text = "> awaiting input.."
		end
		wait(.5)
		debounce = false
	end

As you can see, nothing much is changed. The only components changed is in the main if statement, now the scanPart is checking for a different card and the number required to be accepted was also changed, in this case it was changed to four.

PART 3; Conclusion
If you have made all the way to this point and created a successful system, congratulations! You’ve gotten one step forward in learning to code in Roblox Lua. This is my first time writing a post, so excuse me for some of the vocabulary I used. Any and all feedback is appreciated, link that will direct you to a test game is located below, thanks for reading :wink:.

Link(s):

10 Likes

Great tutorial!
The only problem is that there is some redundant code. for example:

could be transformed into:

label.Text = "scanning..please wait"

wait(1)

    if num > 1 then
	    label.Text = "Player accepted!"
	    lightPart.BrickColor = BrickColor.Green()
    else
	    label.Text = "Player Denied!"
	    lightPart.BrickColor = BrickColor.Red()
    end

wait(1.5)

lightPart.BrickColor = BrickColor.new("Medium stone grey")
label.Text = "> awaiting input.."

By this way the code gets shorter, easier to read and to understand and more efficient!

Agreed, thanks for the feedback! I will say, I’d consider my programming skills intermediate and seeing how you shortened the code so much, definitely a more efficient approach! :smile: :+1:

1 Like

I’ve removed the tag from your title–that’s what the “optional tags” section is for. :slight_smile:

1 Like

Couldn’t say I saw a need to drop a space tab then another space at the end but some spaces in the actual code would have been nice for reading sake.

2 Likes