Roblox LuaU抢劫银行脚本现金增速异常问题求助
Roblox 抢劫银行脚本现金增速异常修复方案
问题症状
- 设定
cashPerSecond为每秒现金增量,但实际增速远超设定值 - 每次抢劫启动时会额外多增加约1秒的现金额度
- 修改为
playersRobbing[player] += cashPerSecond + wait(1)后,出现异常小数金额且现金会超出maxCash上限
问题根源
- 多循环并行执行:当多个玩家几乎同时触发门的Touched事件时,会多次调用
beginRobbery函数,导致多个加钱循环同时运行,现金被多次叠加 - 部件重复检测:Region3遍历玩家身体的多个部件(头、手、脚等),虽有去重逻辑,但原代码的玩家判断逻辑冗余,容易出现漏判或误判
- 无上限截断处理:加钱时未判断叠加后是否超过
maxCash,导致现金溢出 - 错误的时间值累加:将
wait(1)的返回值(实际等待时长,非精确1秒)加到现金中,产生小数金额
修复后的完整代码
local maxCash = 3000 local cashPerSecond = 500 local timeToRob = 300 local robbing = false local cooldown = 30 local closed = false local defaultVaultPosition = script.Parent.VaultDoor.Position local playersRobbing = {} local alreadyRobbed = {} local guis = {} function endRobbery() closed = true robbing = false wait(1) script.Parent.Door.CanCollide = true script.Parent.VaultDoor.Position = defaultVaultPosition -- 清理所有抢劫GUI for _, gui in pairs(guis) do if gui:IsDescendantOf(game.Players) then gui:Destroy() end end guis = {} -- 将剩余抢劫玩家传送至失败点 for p, _ in pairs(playersRobbing) do if p.Character and p.Character:FindFirstChild("HumanoidRootPart") then p.Character.HumanoidRootPart.CFrame = script.Parent.FailedToRob.CFrame end end playersRobbing = {} alreadyRobbed = {} script.Alarm:Stop() wait(cooldown) closed = false script.Parent.Door.CanCollide = false end function beginRobbery() -- 确保同一时间只有一个抢劫循环运行 if robbing then return end robbing = true local vaultArea = script.Parent.VaultArea local region3 = Region3.new(vaultArea.Position - vaultArea.Size/2, vaultArea.Position + vaultArea.Size/2) region3 = region3:ExpandToGrid(4) -- 优化Region3精度 for i = 1, timeToRob do local startTick = tick() -- 获取区域内的所有玩家角色 local parts = workspace:FindPartsInRegion3(region3, script.Parent, math.huge) local playersInRegion = {} -- 去重:通过角色获取玩家,避免同一玩家多个部件被检测 for _, part in pairs(parts) do local player = game.Players:GetPlayerFromCharacter(part.Parent) if player and playersRobbing[player] and not alreadyRobbed[player] then playersInRegion[player] = true end end -- 为区域内的玩家加钱 for player, _ in pairs(playersInRegion) do if playersRobbing[player] < maxCash then -- 计算应加金额,确保不超过上限 local addAmount = math.min(cashPerSecond, maxCash - playersRobbing[player]) playersRobbing[player] += addAmount -- 初始化或更新GUI local playerGui = player.PlayerGui local robberyGui = playerGui:FindFirstChild("RobberyGui") if not robberyGui then robberyGui = script.RobberyGui:Clone() robberyGui.Parent = playerGui robberyGui.StatsHUD.CashBagHUD.Cash.Amount.Text = "$0" robberyGui.StatsHUD.CashBagHUD.Cash.Visible = true robberyGui.StatsHUD.CashBagHUD.CashIcon.Visible = true table.insert(guis, robberyGui) end robberyGui.StatsHUD.CashBagHUD.Cash.Amount.Text = "$" .. playersRobbing[player] end end -- 等待剩余时间,确保每轮循环精确间隔1秒 local elapsed = tick() - startTick if elapsed < 1 then wait(1 - elapsed) end end endRobbery() end local touchedCooldown = {} script.Parent.Door.Touched:Connect(function(hit) local player = game.Players:GetPlayerFromCharacter(hit.Parent) if not player then return end if not closed and not touchedCooldown[player] and not playersRobbing[player] and not alreadyRobbed[player] then touchedCooldown[player] = true playersRobbing[player] = 0 script.Alarm:Resume() -- 启动抢劫循环(仅第一次触发时启动) if not robbing then spawn(beginRobbery) end -- 冷却后移除标记 spawn(function() wait(2) touchedCooldown[player] = nil end) end end) -- 取钱触发逻辑 game.Workspace.Doors.DoubleKeyDoorCriminal.Trigger.Touched:Connect(function(hit) local player = game.Players:GetPlayerFromCharacter(hit.Parent) if not player then return end if not closed and not touchedCooldown[player] and playersRobbing[player] then -- 增加玩家现金 if player:FindFirstChild("leaderstats") and player.leaderstats:FindFirstChild("Cash") then player.leaderstats.Cash.Value += playersRobbing[player] end -- 移除抢劫状态 playersRobbing[player] = nil alreadyRobbed[player] = true -- 检查是否还有玩家在抢劫 local stillRobbing = next(playersRobbing) ~= nil if not stillRobbing then endRobbery() end end end) -- 打开金库门逻辑 script.Parent.OpenVault.Touched:Connect(function(hit) local player = game.Players:GetPlayerFromCharacter(hit.Parent) if not player then return end wait(3) local tweenService = game:GetService("TweenService") tweenService:Create(script.Parent.VaultDoor, TweenInfo.new(5), { Position = defaultVaultPosition + Vector3.new(0, script.Parent.Door.Size.Y, 0) }):Play() end)
关键修改说明
- 避免多循环并行:在
beginRobbery开头增加if robbing then return end判断,确保同一时间只有一个抢劫循环运行 - 优化玩家检测:通过角色去重,避免同一玩家多个身体部件被重复检测
- 现金上限控制:使用
math.min计算应加金额,确保现金不会超过maxCash - 精确时间控制:通过
tick()计算循环耗时,等待剩余时间保证每轮间隔精确1秒 - 移除错误逻辑:删除将
wait(1)返回值加到现金中的错误写法,避免小数金额 - 代码冗余清理:简化玩家获取逻辑,减少重复调用
game.Players:GetPlayerFromCharacter
内容的提问来源于stack exchange,提问作者Mistrix
相关产品推荐
相关产品推荐

