You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Roblox LuaU抢劫银行脚本现金增速异常问题求助

Roblox 抢劫银行脚本现金增速异常修复方案

问题症状

  • 设定cashPerSecond为每秒现金增量,但实际增速远超设定值
  • 每次抢劫启动时会额外多增加约1秒的现金额度
  • 修改为playersRobbing[player] += cashPerSecond + wait(1)后,出现异常小数金额且现金会超出maxCash上限

问题根源

  1. 多循环并行执行:当多个玩家几乎同时触发门的Touched事件时,会多次调用beginRobbery函数,导致多个加钱循环同时运行,现金被多次叠加
  2. 部件重复检测:Region3遍历玩家身体的多个部件(头、手、脚等),虽有去重逻辑,但原代码的玩家判断逻辑冗余,容易出现漏判或误判
  3. 无上限截断处理:加钱时未判断叠加后是否超过maxCash,导致现金溢出
  4. 错误的时间值累加:将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 13:24:56