[URGENT]: How to make a "Vote To Skip" Button For My Story Game

Hey, Sun here. My game comes out in five days, 2022-08-27T18:00:00Z and I wanted to implement a feature seen in some story games … VOTE TO SKIP!

The Lobby, where you start the story game includes gates. Stepping into the game starts a 30 second countdown … For people that want to skip it (as 30 seconds can be a bit lengthy and sometimes makes players want to leave), I thought it would be cool to add a button that allows you to skip it via votes.

How It Would Work

  • Button will appear when entering the gate
  • Clicking the button will add a vote
  • The maximum votes is the current list count in the gate
  • If the vote reaches the list count, the timer stops, the bus leaves, and teleports the players.
  • The button resets after each teleport.

HERE IS MY CURRENT TOUCHGATESCRIPT CODE: (SERVER SCRIPT)

local TS = game:GetService("TeleportService")
local TweenService = game:GetService("TweenService")
local placeId = 10128543519
local leaveGuiEvent = game.ReplicatedStorage.LeaveGuiEvent
local TeleportEvent = game.ReplicatedStorage.TeleportEvent
local ServerStorage = game:GetService("ServerStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local BindableEvents = ReplicatedStorage.Functions_And_Events.BindableEvents
local list = {}
local gui = script.Parent.GuiPart.SurfaceGui
local timer
local teleporting = false
local spawnTeleport = script.Parent.spawn

local Car = workspace.LobbyElements.Gates_Busses.Bus.BusOne

local function updateGui()
	gui.Frame.players.Text = #list
	game.ReplicatedStorage.Remotes.PlayerTag.Value = #list
end

local function removeFromList(character)
	for i=1,#list do
		if list[i] == character.Name then
			table.remove(list,i)
			updateGui()
		end
	end
end

local function teleportPlayers()
	if #list > 0 then
		script.Parent.GuiPart.SurfaceGui.Frame.Status.Text = "TELEPORTING"
		local playersToTeleport = {}
		local teleportTime = 0
		for i=1,#list do
			if game.Players:findFirstChild(list[i]) then
				table.insert(playersToTeleport,game.Players:findFirstChild(list[i]))
				
				for i = 1,100 do
					Car:TranslateBy(Vector3.new(-0.5,0,0))
					wait() -- Do not change this line
				end
				
				TeleportEvent:FireClient(game.Players:findFirstChild(list[i]))
			else
				table.remove(list,i)	
			end
		end 
		local code = TS:ReserveServer(placeId)
		teleporting = true
		TS:TeleportToPrivateServer(placeId,code,playersToTeleport)
		repeat wait() until #list <= 0
		script.Parent.GuiPart.SurfaceGui.Frame.Status.Text = "READY"
		
		for i = 1,100 do -- Moves Car Reverse
			Car:TranslateBy(Vector3.new(0.1,0,0)) -- You might have to move the 1 in the position of a 0
			wait() -- Do not change this line
		end
		
		teleporting = false
		
		for i = 1,-100 do -- Moves Car Reverse
			Car:TranslateBy(Vector3.new(0.1,0,0)) -- You might have to move the 1 in the position of a 0
			wait() -- Do not change this line
		end
	end
end

script.Parent.Gate.Touched:Connect(function(hit)
	if hit.Parent:findFirstChild("Humanoid") then
		if teleporting == false then
			local char = hit.Parent
			local player = game.Players:FindFirstChild(char.Name)
			local alreadyExists = false
			
			for i=1,#list do
				if list[i] == char.Name then
					alreadyExists = true
				end
			end
			
			if alreadyExists == false then
				if #list < 16 then
					table.insert(list,char.Name)
					char.PrimaryPart.CFrame = spawnTeleport.CFrame
					char.Humanoid.JumpPower = 0
					char.Humanoid.WalkSpeed = 0
					
					for i,limb in pairs(player.Character:GetDescendants()) do
						if limb:IsA("MeshPart") then
							limb.Transparency = 1							
						end
					end
					
					updateGui()
					leaveGuiEvent:FireClient(player)
				end
				
				player.CharacterRemoving:connect(function(character)
					removeFromList(character)
				end)
			end
			
		end
	end
end)

leaveGuiEvent.OnServerEvent:Connect(function(player)
	if player.Character then
		player.Character.HumanoidRootPart.Anchored = false
		wait()
		player.Character.Humanoid.Jump = true
		
		for i,limb in pairs(player.Character:GetDescendants()) do
			if limb:IsA("MeshPart") then
				limb.Transparency = 0							
			end
		end
		
		player.Character.Humanoid.JumpPower = 50
		player.Character.Humanoid.WalkSpeed = 16
		
		wait()
		player.Character:MoveTo(game.Workspace.LobbyElements.LeavePart.Position)
		removeFromList(player.Character)
	end
end)

while wait() do
	timer = 30
	for i=1,timer do
		timer = timer - 1
		gui.Frame.time.Text = timer
		game.ReplicatedStorage.Remotes.TimerTag.Value = timer
		
		if timer == 10 then
			local notification = {
				Title = "BUS #1",
				Text = "IS LEAVING IN 10 SECONDS",
				Icon_url = nil,
				Duration = 2,
				BindableFunction_after_pressing = nil,
				button1name = nil,
				button2name = nil,
			}
			
			for i,player in pairs(game.Players:GetPlayers()) do
				BindableEvents.BindableNotification:Fire(notification, player)
			end
		end
		
		--[[if #list == #game.Players:GetPlayers() or 16 or 14 then
			break
		end]]--
		
		wait(1)
	end
	
	teleportPlayers()
end

HERE IS MY LOCAL SCRIPT CODE, WHICH CONTAINS THE PLAYER TAGS AND TIMER TAGS:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Remotes_Folder = ReplicatedStorage:WaitForChild("Remotes")

local TimerTag = Remotes_Folder:WaitForChild("TimerTag")
local PlayerTag = Remotes_Folder:WaitForChild("PlayerTag")

local Main_Frame = script.Parent.Main
local Exit_Button = Main_Frame:WaitForChild("Exit")
local Main_Text = Main_Frame:WaitForChild("MainText")

local player = game.Players.LocalPlayer

ReplicatedStorage.LeaveGuiEvent.OnClientEvent:Connect(function()
	
	player.CameraMaxZoomDistance = 50
	player.CameraMinZoomDistance = 10
	
	Main_Frame.Visible = true
	while wait(1) do
		if TimerTag.Value == 0 then
			Main_Text.Text = "PLAYERS: "..PlayerTag.Value..", TIME: 0"
			Main_Frame.Visible = false
		else
			Main_Text.Text = "PLAYERS: "..PlayerTag.Value..", TIME: "..TimerTag.Value
		end
	end
end)

player.PlayerGui.ExitButton.Main.Exit.MouseButton1Down:connect(function()
	ReplicatedStorage.LeaveGuiEvent:FireServer()
	player.PlayerGui.ExitButton.Main.Visible = false
end)

Note that I have not added any gui nor code for the vote to skip button. Any help is appreciated!

2 Likes

You can prob make it so that there is a local Voted = 0 and it adds +1 if there is a person that voted.

Heres what i would do for a vote script:
Make a gui with a vote skip button that fires a remote

Make a script that detects when a player fires the remote, and if that player has not already fired the remote then add them into a table and check if the size of that table (#table) is equal to the number of players currently in the game (#game.Players:GetPlayers()). If it is then that means that the vote has been skipped and you can teleport the players.

To check if somebody has already fired the remote just add them into a table the first time they fire it and then use table.find(plr) to check if it’s their first time pressing it.

After the teleport call just call table.clear(table) on the table of people who have already voted.

Hope this helps!