How do i make a like/dislike buttons?


I am trying to make like and dislike buttons. i made this code but it is not yet working (also, i am rusty at scripting so please have patience)

in this second picture you can also see the layout of everything, I have a clickdetector with the above script in it, and numOfLikes inside the surface gui is what i am trying to make go up when clicked.

local CD = script.Parent --You don't need to add .ClickDetector to the end of it
local likes - script.Parent.Parent.SurfaceGui.numOfLikes --You also don't need to add .child to it

CD.MouseClick:Connect(function() --The code inside this block will run when someone clicks the button
	local NumberOfLikes = tonumber(likes.Text) --This converts the number of likes into a number so that you can do math on it
	local NewNumberOfLikes = NumberOfLikes + 1 --Adds a like
	likes.Text = NewNumberOfLikes -- Sets the new number
end)

Try this script. I haven’t tested it so hopefully I haven’t made any typos lol
If you want to add a string and a number to the text(for example “Likes: 4”), then you should add an Intvalue. Just tell me if you need help with that.

3 Likes

Wow, ty. So that works great but do you know how to cap it for one person, so everyone can only vote once?

For this you need to put a value on the player and when the player clicks the button loop through the player to see if the value is true or not if it is true then the player has already liked. If not then let the player like/dislike and set it to true. This may not work cause I literally just wrote this in 2 minutes

Just add the executor to an exclusion table and check if theyre inside of the table. if so then remove the link on re-execution. I will not provide code.

Dont need to loop through it. If they store the user as a value within a table then they can just do if not table.find(table, playerHere) then --code end. Looping though it is pointless. The snipet pretty much is the same as doing a true false check.

Both of their solutions should also work. I can still make a script for you if you want, however, I will probably use Mikeart’s solution because I am not super familiar with tables.

Though your idea could be better and more advanced, mine could still work. Just add a boolvalue to the player and find it and see if it is set to true or not.

Why use a boolean when you can save the extra work by inserting them into a table and finding the same person in the same table. You’re adding extra work for no reason. It doesn’t add any functionality apart for bloat the code.

To find the person I dont mean do a for i, v loop. You can save your own time by doing table.find(table, instance) and checking from that return.

I already said your idea can work and is probably better but did you know that my solution can be easier and simpler

Explain how come? To me it doesn’t seem it to be. It seems like it is just extra work for no reason.

  1. Learning tables can take time
  2. What do you mean by extra work when it is just adding values to a player and checking for them.

Tables are the easiest thing in coding imo. Roblox has given you functions to even handle data to and from a table too. I don’t see why someone could just do table.insert/table.find. There is documentation with code snippets and the outputs provided with those snippets too. Adding values to the player its self is just repetitive and a bad practice to store everything on the player instance and not a table which is meant for data storing.

A player instance shouldn’t be a place that you should store everything at. You can instead use a module script to store not only data but functions related to such.

There are so many tutorials, docs and videos to help you learn/understand how to/not to use things and how to interact with/the usage of things aswell.

I still feel like folders with variables in them may be easier for beginners because you can just do something like :WaitForChild(playername). Your solution is probably better overall though because you don’t have to worry about deleting variables when a player leaves the game. Also, module scripts do have a slight learning curve if you are just starting to learn luau.

Module may for some but not all so we shouldn’t rule those out completely as it is like saying everyone has a learning curve with modules. Plus it is more work when having to create more and more things for no reason apart to bloat scripts. Also I mean a table in general within the same script not a module script although you can use one if wanted.

1 Like

I guess that is true. I still feel like the variable method would be better in the short term for people who are too lazy to learn tables but I guess I am biased because my most recent game is basically built on variables.

I will agree with this one. Though my solution wouldn’t be as bad as it is, tables maybe better.

hey sorry for the late answer but i’ve been trying stuff and it has’nt been working, it would be amazing if you could write something up, and dont feel obligated.

Sure, I will probably do it tonight

Alright, here are the scripts

Before I actually paste the scripts on to here, I should mention that they suck and are very messy. The scripts are just good enough for my standards (which are low). Also, you can download a copy of the game here: devforum help game thing - Roblox

First of all, make sure that your model thing looks something like this
image
If you change any of the names, make sure to change the variables inside of the script

First, we are going to make the script that adds a new value when someone joins or leaves. I added a few comments on it that explain what everything does.

--Services
local Players = game:GetService("Players")
--Variables
local LikeFolder = script.Parent.HappyNub.PlayerLikes
local DislikeFolder = script.Parent.UpsetNub.PlayerDislikes

--This is the script that creates the new values when a player joins/leaves the game.

Players.PlayerAdded:Connect(function(plr) --Runs when the player joins the game
	local NewLikedValue = Instance.new("BoolValue", LikeFolder) --Adds a new value inside of LikedFolder
	
	NewLikedValue.Name = plr.Name.."LikedValue"
	--[[Renames the new variable to whatever the players name is plus LikedValue. For example, a player named
	ImSuperCool24 would have a value name called ImSuperCool24LikedValue]]--
	
	--This basically does the same thing as above except it makes a value for the disliked folder instead
	local NewDislikedValue = Instance.new("BoolValue", DislikeFolder)
	NewDislikedValue.Name = plr.Name.."DislikedValue"
end)

Players.PlayerRemoving:Connect(function(plr)--This runs when the player leaves. This will remove the player's value from the folders to "clean" it
	if LikeFolder:WaitForChild(plr.Name.."LikedValue", 2) then --Checks to see if the value exists
		LikeFolder:WaitForChild(plr.Name.."LikedValue"):Destroy() --If it does exist, it will delete it
	end
	
	if DislikeFolder:WaitForChild(plr.Name.."DislikedValue") then
		DislikeFolder:WaitForChild(plr.Name.."LikedValue"):Destroy()
	end
end)

Now that we have that out of the way, we can make our like and dislike click scripts. Looking at it now, I should have just made one large script but I don’t feel like going back to fix it.

--Services
local Players = game:GetService("Players")
--Variables
local LikeFolder = script.Parent.Parent.PlayerLikes
local DislikeFolder = script.Parent.Parent.Parent.UpsetNub.PlayerDislikes
local LikeText = script.Parent.Parent.SurfaceGui.TextLabel
local DislikeText = script.Parent.Parent.Parent.UpsetNub.SurfaceGui.TextLabel
local debounce = false



local function GetLikes()
	local AmountOfLikes = 0

	for i, value in pairs(LikeFolder:GetChildren()) do --Gets the children of the value folder and checks to see if the value is true.
		if value.Value == true then --If it is true, it will update the amount of likes it has by 1
			AmountOfLikes = AmountOfLikes + 1
		end
	end
	return AmountOfLikes --Tells the script how many likes there are. You can use a variable to get this.
end

local function GetDislikes() --Same thing as above except for dislikes
	local AmountOfDislikes = 0
	for i, value in pairs(DislikeFolder:GetChildren()) do
		if value.Value == true then
			AmountOfDislikes = AmountOfDislikes + 1
		end
	end
	return AmountOfDislikes
end




script.Parent.MouseClick:Connect(function(plr)
	if not debounce then
		debounce = true
		local LikedPlayerValue = LikeFolder:WaitForChild(plr.Name.."LikedValue", 3) --Gets the player's liked value
		local DislikedPlayerValue = DislikeFolder:WaitForChild(plr.Name.."DislikedValue", 3) --Gets the player's disliked value
		
		DislikedPlayerValue.Value = false
		LikedPlayerValue.Value = true
		local AmountofLikes = GetLikes() --Gets the amount of likes
		local AmountofDislikes = GetDislikes() --Gets the amount of dislikes

		LikeText.Text = "Likes: "..tostring(AmountofLikes) --Changes the like text
		DislikeText.Text = "Dislikes: "..tostring(AmountofDislikes) --Changes the dislike text
		
		debounce = false
	end
end)

Now, we basically do the same thing but for the dislike script. Like I said earlier, you could probably just combine this script and the last script in to one but both methods should work.

--Services
local Players = game:GetService("Players")
--Variables
local DislikeFolder = script.Parent.Parent.PlayerDislikes
local LikeFolder = script.Parent.Parent.Parent.HappyNub.PlayerLikes
local DislikeText = script.Parent.Parent.SurfaceGui.TextLabel
local LikeText = script.Parent.Parent.Parent.HappyNub.SurfaceGui.TextLabel
local debounce = false

local function GetLikes()
	local AmountOfLikes = 0
	
	for i, value in pairs(LikeFolder:GetChildren()) do --Gets the children of the value folder and checks to see if the value is true.
		if value.Value == true then --If it is true, it will update the amount of likes it has by 1
			AmountOfLikes = AmountOfLikes + 1
		end
	end
	return AmountOfLikes --Tells the script how many likes there are. You can use a variable to get this.
end

local function GetDislikes() --Same thing as above except for dislikes
	local AmountOfDislikes = 0
	for i, value in pairs(DislikeFolder:GetChildren()) do
		if value.Value == true then
			AmountOfDislikes = AmountOfDislikes + 1
		end
	end
	return AmountOfDislikes
end




script.Parent.MouseClick:Connect(function(plr)
	if not debounce then
		debounce = true
		local LikedPlayerValue = LikeFolder:WaitForChild(plr.Name.."LikedValue", 3) --Gets the player's liked value
		local DislikedPlayerValue = DislikeFolder:WaitForChild(plr.Name.."DislikedValue", 3) --Gets the player's disliked value

		DislikedPlayerValue.Value = true
		LikedPlayerValue.Value = false
		local AmountofLikes = GetLikes() --Gets the amount of likes
		local AmountofDislikes = GetDislikes() --Gets the amount of dislikes
		
		LikeText.Text = "Likes: "..tostring(AmountofLikes) --Changes the like text
		DislikeText.Text = "Dislikes: "..tostring(AmountofDislikes) --Changes the dislike text
		
		debounce = false
	end
end)

That is basically it. If you want to find out how many likes/dislikes it has in another script, you can copy and paste(or fire an event) the GetLikes and GetDislikes function. Just make sure that you update the variables.

If you have any questions, feel free to ask me. Like I said at the beginning, I made the game free to download. I am sorry for making you read those ugly and messy scripts lol.

yes, i took a screenshot of the image you posted and added it
image

2 Likes