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

Roblox Studio中DataStore保存非Leaderstat数据异常求助

问题描述

我正在制作一款点击器游戏,想用DataStore存储点击器的图片资源ID和点击收益值(点击按钮获得的数值)。但无论把数值改成多少,退出重进后数值都会变成2,而且控制台没打印"Assigning default value",说明不是用了默认值。我对DataStore不太懂,求帮忙!

原代码:

function PlayerAdded(player)
    
    local clickValue = Instance.new("IntValue")
    clickValue.Name = "clickValue"
    clickValue.Parent = player

    local clickerImage = Instance.new("StringValue")
    clickerImage.Name = "clickerImage"
    clickerImage.Value = "rbxassetid://284663799"
    clickerImage.Parent = player
    
    
    
    local success = nil
    local playerData = nil
    local attempt = 1
    repeat
        success, playerData = pcall(function()
            return dataStore:GetAsync(player.UserId)
        end)
        attempt +=1
        if not success then
            warn(playerData)
            task.wait(3)
        end
        
    until success or attempt == 5
    if success then
        print("Connected to database")
        if not playerData then
            print("Assigning default data")
            playerData ={
                ["clickWorth"] = 1,
                ["ImageTexture"] = "rbxassetid://284663799"
                    
            }
        end
        sessionData[player.UserId] = playerData
        
    else
        warn("Unable to get data for", player.UserId)
        player:Kick("Unable to load you data.Try again later")
    end
    clickValue.Value = sessionData[player.UserId].clickWorth
    clickerImage.Value = sessionData[player.UserId].ImageTexture

    clickValue.Changed:Connect(function()
        sessionData[player.UserId].clickWorth = clickValue.Value
        
    end)
    clickerImage.Changed:Connect(function()
        
        sessionData[player.UserId].ImageTexture = clickerImage.Value
    end)
        

    end



function PlayerLeaving(player)
    if sessionData[player.UserId] then
        local success = nil
        local errorMsg = nil
        local attempt = 1
        
        repeat
            success, errorMsg = pcall(function()
                local clickValue = player.clickValue
                local clickerImage = player.clickerImage
                clickValue.Value = sessionData[player.UserId].clickWorth
                
            dataStore:SetAsync(player.UserId, sessionData[player.UserId])
            end)
            attempt +=1
            if not success then
                warn(errorMsg)
                task.wait(3)
            end
        until success or attempt == 5
        if success then
            print("Data saved for", player.Name)
        else
            warn("Unable to save for", player.Name)
        end
    end
        
    end

注:大部分代码来自YouTube视频。


问题分析与修复

核心问题

  1. 旧错误数据残留:DataStore中已经存储了值为2的错误数据,每次加载时直接读取该值,不会触发默认值分支,所以看不到"Assigning default value"的打印。
  2. PlayerLeaving函数冗余操作:函数内的clickValue.Value = sessionData[player.UserId].clickWorth属于无效反向赋值,虽然不影响存储,但暴露了逻辑上的冗余,容易引发误解。

修复步骤

  1. 清除旧错误数据(测试用):在测试阶段,临时在PlayerAdded函数开头添加dataStore:RemoveAsync(player.UserId),清除已存储的错误数据,让游戏重新生成默认值(测试完成后务必删除该行)。
  2. 移除冗余代码:删除PlayerLeaving函数内的local clickValue = player.clickValue和clickValue.Value = sessionData[player.UserId].clickWorth两行,sessionData已通过Changed事件与客户端数值实时同步,无需反向赋值。
  3. 优化内存管理:在PlayerLeaving函数末尾添加sessionData[player.UserId] = nil,避免玩家离开后残留数据占用内存。

修复后完整代码

-- 需提前定义基础服务与变量
local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("ClickerGameData")
local sessionData = {}

function PlayerAdded(player)
    -- 测试用:清除旧数据,测试完成后删除
    -- dataStore:RemoveAsync(player.UserId)

    local clickValue = Instance.new("IntValue")
    clickValue.Name = "clickValue"
    clickValue.Parent = player

    local clickerImage = Instance.new("StringValue")
    clickerImage.Name = "clickerImage"
    clickerImage.Value = "rbxassetid://284663799"
    clickerImage.Parent = player

    local success = nil
    local playerData = nil
    local attempt = 1
    repeat
        success, playerData = pcall(function()
            return dataStore:GetAsync(player.UserId)
        end)
        attempt += 1
        if not success then
            warn(playerData)
            task.wait(3)
        end
    until success or attempt == 5

    if success then
        print("Connected to database")
        if not playerData then
            print("Assigning default data")
            playerData = {
                ["clickWorth"] = 1,
                ["ImageTexture"] = "rbxassetid://284663799"
            }
        end
        sessionData[player.UserId] = playerData
    else
        warn("Unable to get data for", player.UserId)
        player:Kick("Unable to load your data. Try again later")
    end

    clickValue.Value = sessionData[player.UserId].clickWorth
    clickerImage.Value = sessionData[player.UserId].ImageTexture

    clickValue.Changed:Connect(function(newValue)
        sessionData[player.UserId].clickWorth = newValue
    end)

    clickerImage.Changed:Connect(function(newValue)
        sessionData[player.UserId].ImageTexture = newValue
    end)
end

function PlayerLeaving(player)
    if sessionData[player.UserId] then
        local success = nil
        local errorMsg = nil
        local attempt = 1
        repeat
            success, errorMsg = pcall(function()
                dataStore:SetAsync(player.UserId, sessionData[player.UserId])
            end)
            attempt += 1
            if not success then
                warn(errorMsg)
                task.wait(3)
            end
        until success or attempt == 5

        if success then
            print("Data saved for", player.Name)
        else
            warn("Unable to save for", player.Name)
        end
        -- 清理会话数据,避免内存泄漏
        sessionData[player.UserId] = nil
    end
end

-- 绑定玩家事件
game.Players.PlayerAdded:Connect(PlayerAdded)
game.Players.PlayerRemoving:Connect(PlayerLeaving)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 10:23:14