Howdy DevForum members! I need some help with this currency giver. I want it so that when a player walks onto the part they have to stay on it for 10 seconds in order to receive 5 coins. This is what I have currently.
local db = false
script.Parent.Touched:Connect(function(hit)
if not db then
db = true
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player then
wait(10)
player.leaderstats.Coins.Value += 5
end
wait(1)
db = false
end
end)
Roblox’s tutorial taught me how to do this, so I might as well put it all out there.
local db = false
local count = 0
script.Parent.Touched:Connect(function(hit)
if not db then
count += 1
local myCount = count
db = true
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player then
wait(10)
if count == myCount then
player.leaderstats.Coins.Value += 5
end
end
wait(1)
db = false
end
end)
Do you want them to stay on the part the ENTIRE TIME? If you want that, then you’ll want a script that checks if a player is in a Region3 for 10 seconds, and if the player isn’t, breaks the loop.
Something similar to this:
local RunService = game:GetService("RunService");
local maxParts = 1000;
local function walkedOff(flag)
flag = false;
end
script.Parent.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
local player = game.Players:GetPlayerFromCharacter(hit.Parent.Name);
loop(player);
end
end)
function loop(player)
local flag = true;
local flag2 = true;
local StartTime = RunService.Stepped:Wait();
while (flag) do
local partsInRegion = workspace:FindPartsInRegion3(Region, script.Parent, maxParts);
flag2 = false;
for i, part in pairs(partsInRegion) do
if (part.Parent:FindFirstChild("Humanoid") and part.Parent.Name == player.Name) then
flag2 = true;
end
end
if (not flag2) then
walkedOff(flag);
end
local CurrentTime = RunService.Stepped:Wait();
if (CurrentTime - StartTime >= 10) then
player.leaderstats.Coins.Value += 5;
break;
end
end
end
Yes, I do want to stay inside the part the whole time but if they step off they dont get the coins. Would that script go into a regular script inside of the part?
Yes, that’s what the script would do. It would be inside of a script in a part (you’d have to make the Region3 (“Region”) you want the player to be standing in). Edited the script a little as well. What the script does is that it starts a loop when the part is touched which should check if the player is there. If it does not find the player there (e.g. flag2 ~= true), it breaks the loop (triggers walkedOff()). If the time successfully reaches 10 without the loop breaking, it gives the player five coins and breaks the loop.
I tried the script, and it did not work. I edited a few times and I got errors. On line 23, Region won’t work, but I put Region 3 and received no more error from that. But it does not give the player the currency. On line 35 the player is underlined in orange.
Yes, you’d need to make a Region3 with the variable name “Region” (presumably above the part you want the player to be standing on) for that script to work, as I said in the other post. If you don’t know how to create a Region3, the API reference is here: Region3.
Apologies for the variable “player” being underlined in orange, I didn’t see where you defined it and assumed it was defined in another part of the script. I have updated the script in the original post to have the “player” variable.
While simpler to use, GetPartsInPart requires a part to exist (as a hitbox), while a Region3 doesn’t. GetPartBoundsInRadius acts as a sphere (GetPartBoundsInRadius returns an array of parts whose bounding boxes overlap a sphere). I suppose you could use GetPartBoundsInBox, but it is standard practice to use Region3 (and in general, it is a lot simpler) to figure out where a character is.
Sorry, but I am not quiet sure how to do that, I am not too advanced into scripting. And don’t understand and never used Regoin3. I have read through Region3 multiple times, but do not understand it.
The constructor: Region3.new (Vector3 min, Vector3 max).
In simpler terms: When creating a Region3, you want to put two arguments inside of the parentheses: Vector3 (one corner of the area where you want the player to be standing), and another Vector3 (the opposite corner).
When you create a Vector3, all you need to do is place three numbers inside of the parentheses as arguments in the constructor (x, y, and z).
If you have an issue with my use of Region3, I believe you are perfectly capable of editing my code to use another method instead. Region3 works just fine for this purpose.
I’m not saying you can’t use it, I’m just saying that there are newer methods that tend to work better. I also think that Region3 is more complicated, when GetPartBoundsInBox takes a position and size. But in the end, Region3 isn’t depreciated, and therefore perfectly valid. I just wanted to suggest using the newer methods rather than the older. Anyway, I’ll end this part of the discussion here.
You’d place it somewhere near the start of the code, if you’re using that code. Although, since you’re struggling with Region3, I find it more practical for you to use @MightyDantheman’s idea and simply have a part as a hitbox instead:
Simply replace “Part” with the location of the part you want the player to be standing in (canCollide off, anchored, optionally invisible).
local RunService = game:GetService("RunService");
local Part = workspace.Part;
local debounce = false;
local function walkedOff(flag)
flag = false;
end
script.Parent.Touched:Connect(function(hit)
if hit.Name == "HumanoidRootPart" then
if hit.Parent:FindFirstChild("Humanoid") then
if (debounce == false) then
debounce = true;
local player = game.Players:GetPlayerFromCharacter(hit.Parent);
loop(player);
end
end
end
end)
function loop(player)
local flag = true;
local flag2 = true;
local StartTime = RunService.Stepped:Wait();
while (flag) do
local partsInRegion = workspace:GetPartsInPart(Part);
flag2 = false;
for i, part in pairs(partsInRegion) do
if (part.Parent:FindFirstChild("Humanoid") and part.Parent.Name == player.Name) then
flag2 = true;
end
end
if (not flag2) then
debounce = false;
walkedOff(flag);
end
local CurrentTime = RunService.Stepped:Wait();
if (CurrentTime - StartTime >= 10) then
player.leaderstats.Coins.Value += 5;
flag = false;
debounce = false;
break;
end
end
end
I just tested this code in studio, and it should work perfectly for your application (although, due to the way the debounce works, it should only give one player coins at a time. If you want to have multiple players standing in the same hitbox and also collecting coins, you need to create a debounce value in the player / character and use that instead).
I have a quick question. I am having a problem, because I need players to jump and stuff. And I made the part cancollide off and transparency = 1. But it no longer gives coins. I’m trying to make it so if you stay on this thing for long enough, you get coins.