Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

I made a doorway unlocked with points but how do I make it take points and stay gone?

So I am working on a new game again, but this time I want to make the doorways to new areas actually take your points and stay gone (save so it does not take your points when ever you go through it)

However, I don't know scripting well enough to do that.What do I need to change? Here is my script...

function getPlayer(humanoid) 
	local players = game.Players:children() 
	for i = 1, #players do 
		if players[i].Character.Humanoid == humanoid then
			return players[i]
		end 
	end
end

local Door = script.Parent
function onTouched(hit)
	print("Door Hit")
	local human = hit.Parent:findFirstChild("Humanoid")
	if (human ~= nil ) then
		print("Human touched door")
		local player = getPlayer(human) 
		if (player == nil) then
			return
		end

		local stats = player:findFirstChild("leaderstats") 
		local sp = stats:findFirstChild("points") 
		if sp == nil then
			return false
		end

		if (sp.Value >= 250) then  
			print("Human passed test")
			Door.Transparency = 0
			Door.CanCollide = false
			wait(0.129)
			Door.CanCollide = true
			Door.Transparency = 0
		end
	end
end

connection = Door.Touched:connect(onTouched)

All help is apprectiated!

3 comments

0

i did

0

It didn't load correctly, so I edited it, btw you talk about saving the door setting but I dont see a DataStore in this code...?

0

i dont know how to make it save is the problem

2 answers

✓ Accepted answer

GENERAL PRACTICE

:children() is deprecated in favor of :GetChildren(), However, to get a table of players, it is better to use the :GetPlayers() function of the Players Service since if an object was added to the players service with the same name as a player, you may grab it by mistake.

Instead of using for i = 1, #table and the players[i], you can use for index, value in pairs(table) do instead as it is more condensed and efficient

":findFirstChild()" should be capitalized to :FindFirstChild()

Use :WaitForChild() to make sure that a part exists before using or changing it when you know it is supposed to be there.

You can use :GetPlayerFromCharacter() to get the player of a character model more directly within a touched event than iterating over a table.

To prevent spam of the door, use a debounce as a cooldown for the door to complete its changes.

ISSUES

You can place a function's connection in the same line as its definition. (You also wrote connect =, which is not required)

In order to save data, you must use a DataStore which will save values such as numbers and strings. Generally, we add a pcall to this to make sure that errors are circumvented and do not stop the rest of the script from running. DataStores are generally used to load data when a player joins the game, and then saves the data once they leave. As a result, if we change the data value we want to save on the server, when the player leaves, this change will stay in place. Below, the script will check that the bool is true, if it is false, then it will change the value to true and remove 250 points from the player, if it is true, then the value will remain the same and no points will be deducted.

REVISED SERVER SCRIPT

local DSS = game:GetService("DataStoreService")
local Storage = DSS:GetDataStore("Score")

local Door = script.Parent
local debounce = true

game:GetService("Players").PlayerAdded:Connect(function(player)
	local bool = Instance.new("BoolValue")
	bool.Name = "RemoveDoor1"
	bool.Value = false
	bool.Parent = player
	
	local success, result = pcall(function()
		Storage:GetAsync(player.UserId)
	end)
	
	if not success then
		warn(result)
	else
		local LoadValue = Storage:GetAsync(player.UserId)
		if LoadValue then
			bool.Value = LoadValue
			print(bool.Value)
		end
	end
end)

game:GetService("Players").PlayerRemoving:Connect(function(player)
	Storage:SetAsync(player.UserId, player:WaitForChild("RemoveDoor1").Value)
end)

Door.Touched:Connect(function(hit)
	if debounce == false then return end
	debounce = false
	print("Door Hit")
	local human = hit.Parent:FindFirstChild("Humanoid")
	if human ~= nil then
		print("Human touched door")
		local player = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
		if player ~= nil then
			local sp = player:WaitForChild("leaderstats"):WaitForChild("points")
			local check = player:WaitForChild("RemoveDoor1")
			if check.Value == false and sp.Value >= 250 then
				print("Human passed test")
				check.Value = true
				sp.Value = sp.Value - 250
				Door.CanCollide = false
				wait(0.129)
				Door.CanCollide = true
			elseif check.Value == true then
				print("Human already has access")
				Door.CanCollide = false
				wait(0.129)
				Door.CanCollide = true
			end
		end
	end
	debounce = true
end)

1 comment

0

this is so late but yeah it works! but there is problem it lets you walk through for free sometimes.

So you can use SaveAsync() and GetAsync() to save data. You can put the player's id as the key for the save, and then when retrieving it, put the same player's id. You can save whenever you want, how often you want. You could use a while loop, a changed event, a playerremoved event (although the server might shut down unexpectedly so playerremoved can be dangerous), etc. So you need to create a datastore, then you need to SetAsync to the player's userid and retrieve it when the player joins the game. Oh and I forgot to mention that you only want to do datastore in server scripts and module scripts required by server scripts. Saving data is what the server does, not the client, so remember to always use a server script for datastore.

Go here to read the article about Datastore: DataStoreService

Here is my example for datastore:

local DataStoreService = game:GetService("DataStoreService")
local PlayersService = game:GetService("Players")
local PointsDataStore = DataStoreService:GetDataStore("YourDataStoreNameHere")

PlayersService.PlayerAdded:Connect(OnPlayerAdded)
PlayersService.PlayerRemoving:Connect(UpdateDataStore(9032802984290482930))

function OnPlayerAdded(Player)
	local Cheeto = PointsDataStore:GetAsync(Player.UserId)
	local Cost = 9422564436436
	print(Cheeto)
	if Cheeto == Cost then
		--Do stuff
	end
end

function UpdateDataStore(Player, Value)
	PointsDataStore:SetAsync(Player.UserId, Value)
end

I hope this helps!

1 comment

0

ill try it

This discussion is preserved as it was. New answers, comments, and votes are closed.