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

Roblox食物脚本在Studio正常运行但游戏内失效的问题求助

Roblox食物值扣除脚本发布后失效问题排查与修复

问题描述

食物值扣除脚本在Roblox Studio中可正常每隔9秒扣除10点Food值,但发布到线上游戏后无法运行,控制台无报错。此前使用while true循环时触发script timeout: exhausted allowed execution time错误,改为while player.Character do后问题仍未解决。

代码问题分析

  • 全局变量userid导致数据存储错误:在PlayerAdded回调中赋值的userid是全局变量,多玩家场景下后续玩家ID会覆盖该变量,导致PlayerRemoving时保存错误的玩家数据。
  • 循环无法在玩家复活后重启:当前循环仅在玩家首次加入时执行一次,玩家死亡销毁Character后循环终止,复活后不会自动重启,导致后续不再扣除Food值。
  • 冗余的WaitForChild调用:每次循环都重复获取Humanoid,属于不必要的性能消耗,且极端场景下可能引发无意义等待。

修复后的代码

local Datastoreservice = game:GetService("DataStoreService")
local datastore = Datastoreservice:GetDataStore("food")
print("Coucou toi !")

game.Players.PlayerAdded:Connect(function(player)
    -- 创建玩家数值容器
    local Values = Instance.new("Folder")
    Values.Name = "Values"
    Values.Parent = player

    local food = Instance.new("NumberValue")
    food.Parent = Values
    food.Name = "Food"
    food.Value = 100

    -- 加载玩家数据
    local userId = player.UserId
    local success, errormessage = pcall(function()
        local data = datastore:GetAsync(userId)
        if data then
            food.Value = data
        end
    end)

    if not success then
        warn("加载玩家数据失败: " .. errormessage)
        food.Value = 100
    end

    -- 定义Character加载后的逻辑
    local function onCharacterAdded(character)
        -- 重置Food值
        food.Value = 100
        -- 获取Humanoid
        local hum = character:WaitForChild("Humanoid")
        -- 启动Food扣除循环
        task.spawn(function()
            while character.Parent do -- 检查Character是否仍在游戏中
                food.Value = math.clamp(food.Value - 10, 0, 100)
                -- 根据Food值调整生命值
                if food.Value == 0 then
                    hum.Health = math.max(hum.Health - 5, 0)
                else
                    hum.Health = math.min(hum.Health + 5, hum.MaxHealth)
                end
                task.wait(9)
            end
        end)
    end

    -- 绑定CharacterAdded事件,处理首次加载和复活场景
    player.CharacterAdded:Connect(onCharacterAdded)
    -- 如果玩家加入时已经有Character,立即执行一次
    if player.Character then
        onCharacterAdded(player.Character)
    end
end)

game.Players.PlayerRemoving:Connect(function(player)
    local foodValue = player:FindFirstChild("Values"):FindFirstChild("Food")?.Value
    if not foodValue then return end

    local userId = player.UserId
    local success, errormessage = pcall(function()
        datastore:SetAsync(userId, foodValue)
    end)

    if success then
        print("玩家数据已保存: " .. player.Name)
    else
        print("保存玩家数据失败: " .. player.Name)
        warn(errormessage)
    end
end)

关键修改说明

  • 使用局部变量存储玩家ID:在PlayerAdded和PlayerRemoving中直接使用player.UserId或局部变量,避免全局变量覆盖问题。
  • 循环逻辑封装到Character加载回调:每次玩家Character生成(首次加入/复活)时启动新循环,确保Food值持续扣除。
  • 用task.spawn启动循环:避免阻塞主线程,保证循环在独立线程中运行。
  • 优化循环终止条件:使用character.Parent判断Character是否存在,比player.Character更准确。
  • 完善生命值边界处理:用math.max和math.min确保生命值不会低于0或超过最大值。
  • 增加错误提示:便于排查数据加载/保存时的问题。

内容的提问来源于stack exchange,提问作者The0lexx

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 13:10:09